Merge branch 'autonomic_stroll'
This commit is contained in:
commit
439e27625c
17
game.py
17
game.py
@ -1,4 +1,4 @@
|
|||||||
from random import randint
|
from random import choice, randint
|
||||||
|
|
||||||
import project_constants as const
|
import project_constants as const
|
||||||
|
|
||||||
@ -112,8 +112,20 @@ class Game:
|
|||||||
def get_turn_number(self):
|
def get_turn_number(self):
|
||||||
return self.turn
|
return self.turn
|
||||||
|
|
||||||
|
# draws a random mine to disarm (in auto mode)
|
||||||
|
def set_random_mine_as_target(self):
|
||||||
|
self.goal = choice(self.minefield.get_active_mines()).position
|
||||||
|
|
||||||
|
# display new destination
|
||||||
|
self.input_box_row.set_texts(user_input=str(self.goal[0]))
|
||||||
|
self.input_box_column.set_texts(user_input=str(self.goal[1]))
|
||||||
|
|
||||||
|
# prevents highlighting input_box_row,
|
||||||
|
# couldn't find any better solution w/o major Game class changes
|
||||||
|
self.input_box_row.set_is_selected(False)
|
||||||
|
|
||||||
# gets action sequence for agent
|
# gets action sequence for agent
|
||||||
def get_action_sequence(self):
|
def get_action_sequence(self, target_type: str = "tile"):
|
||||||
return a_star.graphsearch(
|
return a_star.graphsearch(
|
||||||
initial_state=a_star.State(
|
initial_state=a_star.State(
|
||||||
row=self.agent.row,
|
row=self.agent.row,
|
||||||
@ -121,6 +133,7 @@ class Game:
|
|||||||
direction=self.agent.direction
|
direction=self.agent.direction
|
||||||
),
|
),
|
||||||
minefield=self.minefield,
|
minefield=self.minefield,
|
||||||
|
target_type=target_type,
|
||||||
tox=self.goal[0],
|
tox=self.goal[0],
|
||||||
toy=self.goal[1]
|
toy=self.goal[1]
|
||||||
)
|
)
|
||||||
|
22
main.py
22
main.py
@ -1,7 +1,8 @@
|
|||||||
# libraries
|
# libraries
|
||||||
|
import time
|
||||||
import pygame
|
import pygame
|
||||||
from pyglet.gl import * # for blocky textures
|
from pyglet.gl import * # for blocky textures
|
||||||
|
import random
|
||||||
# other files of this project
|
# other files of this project
|
||||||
from game import Game
|
from game import Game
|
||||||
import project_constants as const
|
import project_constants as const
|
||||||
@ -25,6 +26,7 @@ def main():
|
|||||||
# setting flags for program
|
# setting flags for program
|
||||||
running = True
|
running = True
|
||||||
in_menu = True
|
in_menu = True
|
||||||
|
auto = False
|
||||||
is_game_over = False
|
is_game_over = False
|
||||||
|
|
||||||
# create and initialize_gui_components game instance
|
# create and initialize_gui_components game instance
|
||||||
@ -37,7 +39,7 @@ def main():
|
|||||||
# ==== MENU ==== #
|
# ==== MENU ==== #
|
||||||
# ============== #
|
# ============== #
|
||||||
|
|
||||||
while running and in_menu:
|
while running and in_menu and not auto:
|
||||||
events = pygame.event.get()
|
events = pygame.event.get()
|
||||||
|
|
||||||
# checking if game should stop running
|
# checking if game should stop running
|
||||||
@ -58,12 +60,21 @@ def main():
|
|||||||
# if ok button is clicked then leave menu section
|
# if ok button is clicked then leave menu section
|
||||||
in_menu = not game.button_ok.is_clicked(pygame.mouse.get_pos(), events)
|
in_menu = not game.button_ok.is_clicked(pygame.mouse.get_pos(), events)
|
||||||
|
|
||||||
|
# if auto button is clicked then leave menu and start auto-mode
|
||||||
|
auto = game.button_auto.is_clicked(pygame.mouse.get_pos(), events)
|
||||||
|
|
||||||
# ========================== #
|
# ========================== #
|
||||||
# ==== BEFORE GAME LOOP ==== #
|
# ==== BEFORE GAME LOOP ==== #
|
||||||
# ========================== #
|
# ========================== #
|
||||||
|
|
||||||
# getting action sequence for agent
|
# getting action sequence for agent
|
||||||
action_sequence = game.get_action_sequence()
|
if auto:
|
||||||
|
in_menu = False
|
||||||
|
game.set_random_mine_as_target()
|
||||||
|
action_sequence = game.get_action_sequence("mine")
|
||||||
|
|
||||||
|
else:
|
||||||
|
action_sequence = game.get_action_sequence("tile")
|
||||||
|
|
||||||
# initializing game attributes before the game loop
|
# initializing game attributes before the game loop
|
||||||
game.initialize_before_game_loop()
|
game.initialize_before_game_loop()
|
||||||
@ -87,6 +98,11 @@ def main():
|
|||||||
# drawing minefield and agent instances
|
# drawing minefield and agent instances
|
||||||
game.draw_minefield()
|
game.draw_minefield()
|
||||||
|
|
||||||
|
# handling auto button (clicking quits auto-mode)
|
||||||
|
if auto:
|
||||||
|
game.button_auto.set_flags(is_active=True)
|
||||||
|
auto = not game.button_auto.is_clicked(pygame.mouse.get_pos(), events)
|
||||||
|
|
||||||
# drawing inactive gui components so they don't "disappear"
|
# drawing inactive gui components so they don't "disappear"
|
||||||
game.run_in_game_menu_overlay(pygame.mouse.get_pos(), events)
|
game.run_in_game_menu_overlay(pygame.mouse.get_pos(), events)
|
||||||
game.set_is_active_flag_for_all_in_game_gui_components(False)
|
game.set_is_active_flag_for_all_in_game_gui_components(False)
|
||||||
|
17
minefield.py
17
minefield.py
@ -45,6 +45,22 @@ class Minefield:
|
|||||||
if mine is not None and isinstance(mine, TimeMine):
|
if mine is not None and isinstance(mine, TimeMine):
|
||||||
mine.timer = max(0, mine.starting_time - int(self.turn / 4))
|
mine.timer = max(0, mine.starting_time - int(self.turn / 4))
|
||||||
|
|
||||||
|
def get_active_mines(self):
|
||||||
|
mines = list()
|
||||||
|
|
||||||
|
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 mine.active:
|
||||||
|
# do not add mines with predecessors
|
||||||
|
if mine.type == 'chained' and mine.predecessor is not None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
mines.append(mine)
|
||||||
|
|
||||||
|
return mines
|
||||||
|
|
||||||
def disarm_mine(self, x, y):
|
def disarm_mine(self, x, y):
|
||||||
tile = self.matrix[x][y]
|
tile = self.matrix[x][y]
|
||||||
mine = tile.mine
|
mine = tile.mine
|
||||||
@ -55,7 +71,6 @@ class Minefield:
|
|||||||
# ================ #
|
# ================ #
|
||||||
|
|
||||||
# check if sapper's destination is accessible
|
# check if sapper's destination is accessible
|
||||||
# If Agent comes upon a tile with a mine his starting position shall be reestablished
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def is_valid_move(target_row: int, target_column: int):
|
def is_valid_move(target_row: int, target_column: int):
|
||||||
if 0 <= target_row < const.V_GRID_VER_TILES \
|
if 0 <= target_row < const.V_GRID_VER_TILES \
|
||||||
|
@ -3,7 +3,7 @@ from .mine import Mine
|
|||||||
|
|
||||||
class StandardMine(Mine):
|
class StandardMine(Mine):
|
||||||
def __init__(self, position, active=True):
|
def __init__(self, position, active=True):
|
||||||
self.mine_type = "standard"
|
self.type = "standard"
|
||||||
super().__init__(position, active)
|
super().__init__(position, active)
|
||||||
|
|
||||||
def disarm(self):
|
def disarm(self):
|
||||||
|
@ -45,12 +45,32 @@ def get_estimated_cost(node: Node):
|
|||||||
return abs(node.state.row - GOAL[0]) + abs(node.state.column - GOAL[1])
|
return abs(node.state.row - GOAL[0]) + abs(node.state.column - GOAL[1])
|
||||||
|
|
||||||
|
|
||||||
def goal_test(state: State):
|
def tile_goal_test(state: State):
|
||||||
if (state.row, state.column) == GOAL:
|
if (state.row, state.column) == GOAL:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def mine_goal_test(state: State):
|
||||||
|
if state.row == GOAL[0] and state.column == GOAL[1] - 1:
|
||||||
|
if state.direction == Direction.RIGHT:
|
||||||
|
return True
|
||||||
|
|
||||||
|
elif state.row == GOAL[0] and state.column == GOAL[1] + 1:
|
||||||
|
if state.direction == Direction.LEFT:
|
||||||
|
return True
|
||||||
|
|
||||||
|
elif state.row == GOAL[0] - 1 and state.column == GOAL[1]:
|
||||||
|
if state.direction == Direction.DOWN:
|
||||||
|
return True
|
||||||
|
|
||||||
|
elif state.row == GOAL[0] + 1 and state.column == GOAL[1]:
|
||||||
|
if state.direction == Direction.UP:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def get_successors(state: State, minefield: Minefield):
|
def get_successors(state: State, minefield: Minefield):
|
||||||
successors = list()
|
successors = list()
|
||||||
|
|
||||||
@ -73,6 +93,7 @@ def graphsearch(initial_state: State,
|
|||||||
minefield: Minefield,
|
minefield: Minefield,
|
||||||
fringe: List[Node] = None,
|
fringe: List[Node] = None,
|
||||||
explored: List[Node] = None,
|
explored: List[Node] = None,
|
||||||
|
target_type: str = "tile",
|
||||||
tox: int = None,
|
tox: int = None,
|
||||||
toy: int = None):
|
toy: int = None):
|
||||||
|
|
||||||
@ -86,6 +107,15 @@ def graphsearch(initial_state: State,
|
|||||||
if tox is not None and toy is not None:
|
if tox is not None and toy is not None:
|
||||||
GOAL = (tox, toy)
|
GOAL = (tox, toy)
|
||||||
|
|
||||||
|
if target_type == "mine":
|
||||||
|
goal_test = mine_goal_test
|
||||||
|
else:
|
||||||
|
goal_test = tile_goal_test
|
||||||
|
if minefield.matrix[GOAL[0]][GOAL[1]].mine is not None and minefield.matrix[GOAL[0]][GOAL[1]].mine.active:
|
||||||
|
# TODO: cross-platform popup, move to separate function
|
||||||
|
ctypes.windll.user32.MessageBoxW(0, "Brak rozwiązania", "GAME OVER", 1)
|
||||||
|
return []
|
||||||
|
|
||||||
# fringe and explored initialization
|
# fringe and explored initialization
|
||||||
if fringe is None:
|
if fringe is None:
|
||||||
fringe = list()
|
fringe = list()
|
||||||
|
Loading…
Reference in New Issue
Block a user