Projekt_Sztuczna_Inteligencja/minefield.py

114 lines
3.9 KiB
Python
Raw Normal View History

import json
2021-03-26 16:36:21 +01:00
import ctypes #
import agent as ag
2021-03-14 19:18:23 +01:00
import project_constants as const
2021-03-12 11:49:19 +01:00
import tile as tl
from mines_models import standard_mine as sm
2021-03-12 11:49:19 +01:00
2021-03-26 16:36:21 +01:00
tile_asset_options = {
2021-03-14 19:18:23 +01:00
"BLUE": const.ASSET_TILE_BLUE,
"GREEN": const.ASSET_TILE_GREEN,
"ORANGE": const.ASSET_TILE_ORANGE,
"PURPLE": const.ASSET_TILE_PURPLE,
"RED": const.ASSET_TILE_RED,
"WHITE": const.ASSET_TILE_WHITE,
"YELLOW": const.ASSET_TILE_YELLOW
}
mine_asset_options = {
2021-03-14 19:18:23 +01:00
'A': const.ASSET_MINE_A,
'B': const.ASSET_MINE_B,
'F': const.ASSET_MINE_F,
'K': const.ASSET_MINE_K
}
def calculate_screen_position(x, y):
coords = (
2021-03-14 19:18:23 +01:00
const.V_SCREEN_PADDING + const.V_TILE_SIZE * x,
const.V_SCREEN_PADDING + const.V_TILE_SIZE * y,
)
return coords
2021-03-12 11:49:19 +01:00
class Minefield:
def __init__(self, json_path):
self.turn = 0
2021-03-26 16:36:21 +01:00
self.agent = ag.Agent(const.MAP_RANDOM_10x10)
2021-03-12 11:49:19 +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
# create matrix of a desired size, fill it with default tile objects
self.matrix = [
[
tl.Tile((x, y)) for y in range(const.V_GRID_VER_TILES)
] for x in range(const.V_GRID_HOR_TILES)
]
2021-03-12 11:49:19 +01:00
# iterate through tiles, set their colors and add mines
2021-03-14 19:18:23 +01:00
for x in range(const.V_GRID_HOR_TILES):
for y in range(const.V_GRID_VER_TILES):
2021-03-12 11:49:19 +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:
# TODO: check mine type and create suitable one
# JSON file doesn't represent new mine types yet, so every mine is a standard one at the moment
mine = sm.StandardMine((x, y))
self.matrix[x][y].mine = mine
self.matrix[x][y].color = tile_data["color"].upper()
2021-03-26 16:36:21 +01:00
2021-03-12 11:49:19 +01:00
def draw(self, window):
# iterate through tiles
for raw in self.matrix:
for tile in raw:
2021-03-12 11:49:19 +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
# draw a tile
window.blit(tile_asset_options.get(tile.color), tile_screen_coords)
2021-03-12 11:49:19 +01:00
# draw a mine on top if there is one
if tile.mine is not None:
# TODO: blit appropriate mine type
# current icons don't represent actual types, thus every mine has the same icon (temporary solution)
window.blit(mine_asset_options['A'], tile_screen_coords)
2021-03-12 11:49:19 +01:00
2021-03-26 16:36:21 +01:00
# draw the sapper
2021-03-26 16:36:21 +01:00
sapper_screen_coords = calculate_screen_position(self.agent.position[0], self.agent.position[1])
2021-03-14 19:18:23 +01:00
window.blit(const.ASSET_SAPPER, sapper_screen_coords)
# ================ #
# === MOVEMENT === #
# ================ #
2021-03-26 16:36:21 +01:00
# check if sapper's destination is accessible if so then change position of the Agent
# If Agent comes upon a tile with a mine his starting position shall be reestablished
def is_valid_move(self, target_x: int, target_y: int):
if 0 <= target_x < const.V_GRID_HOR_TILES and \
2021-03-26 16:36:21 +01:00
0 <= target_y < const.V_GRID_VER_TILES:
if self.matrix[target_x][target_y].mine is None:
self.agent.position[0] = target_x
self.agent.position[1] = target_y
else:
self.agent.position[0] = int(self.agent.x)
self.agent.position[1] = int(self.agent.y)
ctypes.windll.user32.MessageBoxW(0, "Znowu się nie udało", "GAME OVER", 1)
# This part of the pop up message is just a temporary solution
# Here are defined functions that move our agent. They are being called in main when certain key is pressed
2021-03-14 19:18:23 +01:00
2021-03-26 16:36:21 +01:00