diff --git a/src/const.py b/src/const.py index c42dc7e..badcb57 100644 --- a/src/const.py +++ b/src/const.py @@ -1,8 +1,9 @@ import os import pygame as pg +from ap_mine import APMine from image import Image - +from tile import Tile main_path = os.path.dirname(os.getcwd()) @@ -53,14 +54,14 @@ for name in [ DEBUG_FIELD = [ - [1, 11, 1, 1, 1, 1, 1, 1, 1, 1], - [1, 1, 1, 1, 4, 1, 1, 1, 1, 1], - [11, 1, 1, 1, 11, 4, 1, 1, 1, 1], - [4, 1, 1, 1, 11, 1, 1, 4, 1, 1], - [1, 1, 1, 1, 1, 1, 1, 11, 1, 1], - [1, 1, 1, 1, 1, 1, 1, 11, 4, 1], - [1, 1, 1, 1, 1, 1, 1, 11, 1, 1], - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], - [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + [Tile(1, 1), Tile(11, 20), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1)], + [Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(4, 1, APMine()), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1)], + [Tile(11, 20), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(11, 20), Tile(4, 0, APMine()), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1)], + [Tile(4, 0, APMine()), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(11, 20), Tile(1, 1),Tile(1, 1), Tile(4, 0, APMine()), Tile(1, 1),Tile(1, 1)], + [Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(11, 20), Tile(1, 1), Tile(1, 1)], + [Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(11, 20), Tile(4, 0, APMine()), Tile(1, 1)], + [Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(1, 1), Tile(11, 20), Tile(1, 1), Tile(1, 1)], + [Tile(1, 1) for _ in range(10)], + [Tile(1, 1) for _ in range(10)], + [Tile(1, 1) for _ in range(10)], ] diff --git a/src/environment.py b/src/environment.py index df881f4..041334e 100644 --- a/src/environment.py +++ b/src/environment.py @@ -8,10 +8,10 @@ from tilesFactory import TilesFactory def generate_field() -> List[List[Tile]]: tiles_factory = TilesFactory() tiles_list = tiles_factory.get_tiles_list() - return [choices(tiles_list, weights=[10, 10, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2], k=10) for _ in range(10)] + return [choices(tiles_list, weights=[10, 10, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4], k=10) for _ in range(10)] class Environment: def __init__(self, field: List[List[Tile]] = None): - self.field = field if field else generate_field() + self.field = generate_field() self.mine_count = sum(sum(1 for tile in row if tile.mine) for row in self.field) diff --git a/src/main.py b/src/main.py index 28d4a23..17c7f39 100644 --- a/src/main.py +++ b/src/main.py @@ -1,13 +1,11 @@ -from typing import Tuple - import pygame as pg from agent import Agent from game_ui import GameUi from const import ICON, IMAGES from environment import Environment -from search_algoritms.BFS import breadth_first_search -from src.search_algoritms.a_star import a_star, nearest_bomb +from search_algoritms.BFS import breadth_first_search, breadth_first_search_for_a_star +from src.search_algoritms.a_star import a_star from tilesFactory import TilesFactory @@ -64,21 +62,21 @@ def main(): elif event.type == pg.KEYDOWN: if event.key == pg.K_t: print('Starting to clear the sector') - #while env.mine_count: - print('-'*20) - #path, actions = breadth_first_search(env.field, agent.x, agent.y, agent.direction) - #xd: Tuple[int,int] = Tuple[agent.x, agent.y] - path, actions = a_star(env.field, agent.x, agent.y, agent.direction, nearest_bomb((agent.x, agent.y), env.field)) - if not path and not env.field[agent.y][agent.x].mine: - print('Unable to find path, rocks are in the way') - break - print(f'Path{path}') - print(f'Actions:{actions}') - for action in actions: - pg.fastevent.post(pg.event.Event(pg.KEYDOWN, {'key': action})) - - pg.fastevent.post(pg.event.Event(pg.KEYDOWN, {'key': pg.K_SPACE})) - handle_keys(env, agent, game_ui, factory) + while env.mine_count: + print('-'*20) + #path, actions = breadth_first_search(env.field, agent.x, agent.y, agent.direction) + path, actions = a_star (env.field, agent.x, agent.y, agent.direction, + breadth_first_search_for_a_star (env.field, agent.x, agent.y, + agent.direction)) + if not path and not env.field[agent.y][agent.x].mine: + print('Unable to find path, rocks are in the way') + break + print(f'Path{path}') + print(f'Actions:{actions}') + for action in actions: + pg.fastevent.post(pg.event.Event(pg.KEYDOWN, {'key': action})) + pg.fastevent.post(pg.event.Event(pg.KEYDOWN, {'key': pg.K_SPACE})) + handle_keys(env, agent, game_ui, factory) print('Sector clear') else: pg.fastevent.post(event) diff --git a/src/search_algoritms/BFS.py b/src/search_algoritms/BFS.py index f3e6b94..902c1aa 100644 --- a/src/search_algoritms/BFS.py +++ b/src/search_algoritms/BFS.py @@ -26,3 +26,25 @@ def breadth_first_search(field: List[List[Tile]], start_x: int, start_y: int, st node_queue.put(neighbour_node) return False, False + + +def breadth_first_search_for_a_star(field: List[List[Tile]], start_x: int, start_y: int, start_direction: int): + explored = [] + node_queue = queue.Queue() + node_queue.put(Node(start_x, start_y, start_direction)) + + while not node_queue.empty(): + node = node_queue.get() + + if field[node.y][node.x].mine: + return node.x, node.y + + explored.append(node) + for x, y, direction, action in successor(field, node.x, node.y, node.direction): + neighbour_node = Node(x, y, direction, node, action) + node_queue_list = node_queue.queue + if neighbour_node in explored or neighbour_node in node_queue_list: + continue + node_queue.put(neighbour_node) + + return False, False \ No newline at end of file diff --git a/src/search_algoritms/a_star.py b/src/search_algoritms/a_star.py index 78e80b3..f71201b 100644 --- a/src/search_algoritms/a_star.py +++ b/src/search_algoritms/a_star.py @@ -1,11 +1,10 @@ -from operator import itemgetter from typing import List, Tuple from ap_mine import APMine from at_mine import ATMine from src.node import Node from src.tile import Tile -from .helpers import successor, get_path_actions, calculate_priority +from .helpers import successor, get_path_actions_a_star, calculate_priority def a_star(field: List[List[Tile]], start_x: int, start_y: int, start_direction: int, goal: Tuple[int, int]): @@ -17,8 +16,8 @@ def a_star(field: List[List[Tile]], start_x: int, start_y: int, start_direction: # przy get wyciąga element z najniższą wartością priorytetu if (node.x, node.y) == goal: - return get_path_actions(node) - + return get_path_actions_a_star(node, field) + explored.append(node) for x, y, direction, action in successor(field, node.x, node.y, node.direction): neighbour_node = Node(x, y, direction, node, action) @@ -48,4 +47,4 @@ def nearest_bomb(a: Tuple[int, int], field: List[List[Tile]]): min = distance min_x = x min_y = y - return (min_x, min_y) + return min_x, min_y diff --git a/src/search_algoritms/helpers.py b/src/search_algoritms/helpers.py index d65ac59..bf8390d 100644 --- a/src/search_algoritms/helpers.py +++ b/src/search_algoritms/helpers.py @@ -28,7 +28,7 @@ def successor(field: List[List[Tile]], x: int, y: int, direction: int): return neighbours -def get_path_actions(node: Node): +def get_path_actions(node: Node, field: List[List[Tile]]): path = [] actions = [] while node.parent: @@ -37,6 +37,18 @@ def get_path_actions(node: Node): node = node.parent return path[::-1], actions[::-1] +def get_path_actions_a_star(node: Node, field: List[List[Tile]]): + path = [] + actions = [] + while node.parent: + path.append((node.x, node.y)) + print(field[node.y][node.x], field[node.y][node.x].weight, node.x, node.y, field[node.y][node.x].mine) + if field[node.y][node.x].mine: + actions.append(32) + actions.append(node.action) + node = node.parent + return path[::-1], actions[::-1] + def cost(field: List[List[Tile]], node): return 1 if (node.parent.x, node.parent.y) == (node.x, node.y) else field[node.y][node.x].weight diff --git a/src/tilesFactory.py b/src/tilesFactory.py index af6ee57..0638d83 100644 --- a/src/tilesFactory.py +++ b/src/tilesFactory.py @@ -10,9 +10,9 @@ class TilesFactory: img = IMAGES[number] if img.mine_type: module = import_module(f'{img.mine_type.lower()}_mine') - return Tile(number, 1, getattr(module, f'{img.mine_type}Mine')()) + return Tile(number, 0, getattr(module, f'{img.mine_type}Mine')()) else: - return Tile(number, 1) if 'grass' in img.name else Tile(number, 20) + return Tile(number, 5) if 'grass' in img.name else Tile(number, 30) def get_tiles_list(self) -> List[Tile]: return [self.create_tile(i) for i in range(13)]