Projekt_Sztuczna_Inteligencja/minefield.py

96 lines
3.4 KiB
Python

import agent as ag
import project_constants as const
import tile as tl
from mine_models.time_mine import TimeMine
import json_generator as jg
import pygame
import time
from display_assets import blit_graphics
from project_constants import HIGHLIGHT, INPUT_ROW, INPUT_COLUMN, RANDOM_BUTTON, OK_BUTTON
from ui.ui_components_list import UiComponentsList
class Minefield:
def __init__(self, json_path):
self.turn = 0
self.agent = ag.Agent(const.MAP_RANDOM_10x10)
# open JSON with minefield info
json_gen = jg.JsonGenerator()
json_gen.load_from_a_file(json_path)
# create matrix of a desired size, fill it with default tile objects
self.matrix = [
[
tl.Tile(
(row, column),
terrain_type=json_gen.get_tile((row, column))["terrain"],
mine=jg.create_a_mine(json_gen.get_mine((row, column)), (row, column))
) for column in range(const.V_GRID_HOR_TILES)
] for row in range(const.V_GRID_VER_TILES)
]
# iterate through chained mines, set mine predecessors
for pair in jg.get_chained_mine_and_its_predecessor_pairs(json_gen.get_grid()):
successor_position, predecessor_position = pair
successor_row, successor_column = successor_position
predecessor_row, predecessor_column = predecessor_position
predecessor = self.matrix[predecessor_row][predecessor_column]
self.matrix[successor_row][successor_column].mine.predecessor = predecessor
def next_turn(self):
self.turn += 1
for row in range(const.V_GRID_VER_TILES):
for column in range(const.V_GRID_VER_TILES):
mine = self.matrix[row][column].mine
if mine is not None and isinstance(mine, TimeMine):
mine.timer = max(0, mine.starting_time - int(self.turn / 4))
# ================ #
# === MOVEMENT === #
# ================ #
# check if sapper's destination is accessible
# If Agent comes upon a tile with a mine his starting position shall be reestablished
@staticmethod
def is_valid_move(target_row: int, target_column: int):
if 0 <= target_row < const.V_GRID_VER_TILES \
and 0 <= target_column < const.V_GRID_HOR_TILES:
return True
return False
def disarm_mine(self, x, y):
tile = self.matrix[x][y]
mine = tile.mine
mine.disarm()
# This for loop is temporary solution for graphics to refresh. It works weird but it will be changed eventually.
for i in range(3):
time.sleep(1)
self.next_turn()
# FPS control
pygame.time.Clock().tick(const.V_FPS)
delta_time = pygame.time.Clock().get_time() / 1000
action_delta_time = delta_time / const.ACTION_INTERVAL
# graphics (from display_assets)
blit_graphics(self)
const.SCREEN.blit(HIGHLIGHT, const.get_tile_coordinates((x, y)))
self.agent.update_and_draw(const.SCREEN, 0, self)
# drawing ui components so they don't "disappear"
UiComponentsList([INPUT_ROW, INPUT_COLUMN, RANDOM_BUTTON, OK_BUTTON]).draw_all(const.SCREEN,
pygame.mouse.get_pos())
# updating graphics
pygame.display.flip()