2021-03-12 11:49:19 +01:00
|
|
|
import pygame
|
2021-03-12 21:25:33 +01:00
|
|
|
import json
|
2021-03-12 11:49:19 +01:00
|
|
|
import project_constants as consts
|
|
|
|
import tile as tl
|
|
|
|
import mine as mn
|
|
|
|
|
2021-03-12 21:25:33 +01:00
|
|
|
tile_asset_options = {
|
|
|
|
"BLUE": consts.ASSET_TILE_BLUE,
|
|
|
|
"GREEN": consts.ASSET_TILE_GREEN,
|
|
|
|
"ORANGE": consts.ASSET_TILE_ORANGE,
|
|
|
|
"PURPLE": consts.ASSET_TILE_PURPLE,
|
|
|
|
"RED": consts.ASSET_TILE_RED,
|
|
|
|
"WHITE": consts.ASSET_TILE_WHITE,
|
|
|
|
"YELLOW": consts.ASSET_TILE_YELLOW
|
|
|
|
}
|
|
|
|
|
|
|
|
mine_asset_options = {
|
|
|
|
'A': consts.ASSET_MINE_A,
|
|
|
|
'B': consts.ASSET_MINE_B,
|
|
|
|
'F': consts.ASSET_MINE_F,
|
|
|
|
'K': consts.ASSET_MINE_K
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
def calculate_screen_position(x, y):
|
|
|
|
coords = (
|
|
|
|
consts.V_SCREEN_PADDING + consts.V_TILE_SIZE * x,
|
|
|
|
consts.V_SCREEN_PADDING + consts.V_TILE_SIZE * y,
|
|
|
|
)
|
|
|
|
|
|
|
|
return coords
|
|
|
|
|
2021-03-12 11:49:19 +01:00
|
|
|
|
|
|
|
class Minefield:
|
2021-03-12 21:25:33 +01:00
|
|
|
def __init__(self, json_path):
|
2021-03-12 11:49:19 +01:00
|
|
|
|
2021-03-12 21:25:33 +01:00
|
|
|
# open JSON with minefield info
|
|
|
|
with open(json_path) as json_data:
|
|
|
|
data = json.load(json_data)
|
2021-03-12 11:49:19 +01:00
|
|
|
|
2021-03-12 21:25:33 +01:00
|
|
|
# create matrix of a desired size, fill it with default tile objects
|
|
|
|
self.matrix = [
|
|
|
|
[
|
|
|
|
tl.Tile((i, j)) for i in range(consts.V_GRID_VER_TILES)
|
|
|
|
] for j in range(consts.V_GRID_HOR_TILES)
|
|
|
|
]
|
2021-03-12 11:49:19 +01:00
|
|
|
|
2021-03-12 21:25:33 +01:00
|
|
|
# iterate through tiles, set their colors and add mines
|
2021-03-12 11:49:19 +01:00
|
|
|
for x in range(consts.V_GRID_HOR_TILES):
|
|
|
|
for y in range(consts.V_GRID_VER_TILES):
|
|
|
|
|
2021-03-12 21:25:33 +01:00
|
|
|
# load tile's data from json
|
|
|
|
tile_data = data[f"{x},{y}"]
|
|
|
|
|
|
|
|
# create and add mine if there is one
|
|
|
|
if tile_data["mine"] is not None:
|
|
|
|
mine_type = tile_data["mine"]["mine_type"].upper()
|
|
|
|
mine = mn.Mine((x, y), mine_type)
|
|
|
|
self.matrix[x][y].mine = mine
|
|
|
|
|
|
|
|
self.matrix[x][y].color = tile_data["color"].upper()
|
|
|
|
|
|
|
|
# probably a temporary solution
|
|
|
|
# (depends on sapper's movement implementation)
|
|
|
|
sapper_x, sapper_y = data['agent_starting_position'].split(",")
|
|
|
|
self.sapper_position = (int(sapper_x), int(sapper_y))
|
2021-03-12 11:49:19 +01:00
|
|
|
|
|
|
|
def draw(self, window):
|
|
|
|
# iterate through tiles
|
|
|
|
for column in self.matrix:
|
|
|
|
for tile in column:
|
|
|
|
|
2021-03-12 21:25:33 +01:00
|
|
|
# calculate tile position on the screen
|
|
|
|
tile_screen_coords = calculate_screen_position(tile.position[0], tile.position[1])
|
2021-03-12 11:49:19 +01:00
|
|
|
|
2021-03-12 21:25:33 +01:00
|
|
|
# draw a tile
|
|
|
|
window.blit(tile_asset_options.get(tile.color), tile_screen_coords)
|
2021-03-12 11:49:19 +01:00
|
|
|
|
2021-03-12 21:25:33 +01:00
|
|
|
# draw a mine on top if there is one
|
|
|
|
if tile.mine is not None:
|
|
|
|
window.blit(mine_asset_options.get(tile.mine.mine_type), tile_screen_coords)
|
2021-03-12 11:49:19 +01:00
|
|
|
|
2021-03-12 21:25:33 +01:00
|
|
|
# draw the sapper
|
|
|
|
sapper_screen_coords = calculate_screen_position(self.sapper_position[0], self.sapper_position[1])
|
2021-03-14 11:32:44 +01:00
|
|
|
window.blit(consts.ASSET_SAPPER, sapper_screen_coords)
|
2021-03-14 18:25:12 +01:00
|
|
|
|
|
|
|
# Make sure that sapper won't step on the mine.
|
|
|
|
def check_legal_move(self, target):
|
|
|
|
if self.matrix[target[1]][target[0]].mine is None:
|
|
|
|
return target
|
|
|
|
else:
|
|
|
|
return self.sapper_position
|
|
|
|
|
2021-03-14 11:32:44 +01:00
|
|
|
# Here are defined functions that move our agent. They are being called in main when certain key is pressed
|
|
|
|
def go_right(self):
|
2021-03-14 18:25:12 +01:00
|
|
|
if self.sapper_position[0] < consts.V_GRID_HOR_TILES - 1:
|
|
|
|
self.sapper_position = self.check_legal_move(
|
|
|
|
(int(self.sapper_position[0]) + 1, int(self.sapper_position[1])))
|
|
|
|
|
|
|
|
def go_left(self):
|
|
|
|
if self.sapper_position[0] > 0:
|
|
|
|
self.sapper_position = self.check_legal_move(
|
|
|
|
(int(self.sapper_position[0]) - 1, int(self.sapper_position[1])))
|
|
|
|
|
|
|
|
def go_up(self):
|
|
|
|
if self.sapper_position[1] > 0:
|
|
|
|
self.sapper_position = self.check_legal_move(
|
|
|
|
(int(self.sapper_position[0]), int(self.sapper_position[1]) - 1))
|
|
|
|
|
|
|
|
def go_down(self):
|
|
|
|
if self.sapper_position[1] < consts.V_GRID_VER_TILES - 1:
|
|
|
|
self.sapper_position = self.check_legal_move(
|
|
|
|
(int(self.sapper_position[0]), int(self.sapper_position[1]) + 1))
|