import pygame import json import project_constants as consts import tile as tl import mine as mn 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 class Minefield: def __init__(self, json_path): # open JSON with minefield info with open(json_path) as json_data: data = json.load(json_data) # 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) ] # iterate through tiles, set their colors and add mines for x in range(consts.V_GRID_HOR_TILES): for y in range(consts.V_GRID_VER_TILES): # 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)) def draw(self, window): # iterate through tiles for column in self.matrix: for tile in column: # calculate tile position on the screen tile_screen_coords = calculate_screen_position(tile.position[0], tile.position[1]) # draw a tile window.blit(tile_asset_options.get(tile.color), tile_screen_coords) # 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) # draw the sapper sapper_screen_coords = calculate_screen_position(self.sapper_position[0], self.sapper_position[1]) window.blit(consts.ASSET_SAPPER, sapper_screen_coords) # 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 # Here are defined functions that move our agent. They are being called in main when certain key is pressed def go_right(self): 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))