diff --git a/images/Tiles/mud_01.png b/images/Tiles/mud_01.png index dab0866..3405aad 100644 Binary files a/images/Tiles/mud_01.png and b/images/Tiles/mud_01.png differ diff --git a/images/Tiles/mud_02.png b/images/Tiles/mud_02.png index c2d6ba6..a31d75d 100644 Binary files a/images/Tiles/mud_02.png and b/images/Tiles/mud_02.png differ diff --git a/src/const.py b/src/const.py index 12af6fa..2d30b91 100644 --- a/src/const.py +++ b/src/const.py @@ -22,10 +22,13 @@ for name, val in { 'grass_02_mineAT_01': 1, 'grass_02_mineAP_02': 1, 'grass_02_mineAP_03': 1, + 'mud_01':0, + 'mud_02':1 }.items(): IMAGES.append( Image( val, + name, pg.image.load( main_path + '/images/Tiles/' + name + ".png" ), diff --git a/src/environment.py b/src/environment.py index e8765e4..1e2db69 100644 --- a/src/environment.py +++ b/src/environment.py @@ -8,7 +8,7 @@ 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], k=10) for _ in range(10)] + return [choices(tiles_list, weights=[10, 10, 4, 4, 4, 4, 4, 4, 4, 4, 4,2,2], k=12) for _ in range(12)] class Environment: diff --git a/src/image.py b/src/image.py index 3ff81a7..7e8eaff 100644 --- a/src/image.py +++ b/src/image.py @@ -1,10 +1,12 @@ +import string from typing import Union from pygame import image class Image: - def __init__(self, parent: int, img: image, mine_type: Union[str, None]): + def __init__(self, parent: int, name: string, img: image, mine_type: Union[str, None]): self.parent = parent self.img = img self.mine_type = mine_type + self.name = name diff --git a/src/main.py b/src/main.py index c909d9f..f555f21 100644 --- a/src/main.py +++ b/src/main.py @@ -1,3 +1,5 @@ +from typing import Tuple + import pygame as pg from agent import Agent @@ -5,6 +7,7 @@ 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 tilesFactory import TilesFactory @@ -64,6 +67,8 @@ def main(): 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 diff --git a/src/search_algoritms/BFS.py b/src/search_algoritms/BFS.py index e899e09..f3e6b94 100644 --- a/src/search_algoritms/BFS.py +++ b/src/search_algoritms/BFS.py @@ -1,8 +1,8 @@ import queue from typing import List -from node import Node -from tile import Tile +from src.node import Node +from src.tile import Tile from .helpers import successor, get_path_actions diff --git a/src/search_algoritms/a_star.py b/src/search_algoritms/a_star.py index b972fc4..59b231f 100644 --- a/src/search_algoritms/a_star.py +++ b/src/search_algoritms/a_star.py @@ -1,14 +1,15 @@ from typing import List, Tuple from operator import itemgetter -from node import Node -from tile import Tile -from .helpers import successor, get_path_actions +from src.node import Node +from src.tile import Tile +from .helpers import successor, get_path_actions, calculate_priority +from ..mine import Mine def a_star(field: List[List[Tile]], start_x: int, start_y: int, start_direction: int, goal: Tuple[int, int]): explored = [] - node_queue: List[Tuple[int, Node]] = [(1, Node(start_x, start_y, start_direction))] + node_queue: List[Tuple[int, Node]] = [(field[start_x][start_y].weight, Node(start_x, start_y, start_direction))] # do kolejki dodawać krotke (priorytet, obiekt) while node_queue: @@ -21,14 +22,36 @@ def a_star(field: List[List[Tile]], start_x: int, start_y: int, start_direction: 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) - neighbour_priority = calculate_priority(node, goal) + neighbour_priority = calculate_priority(field, node, goal) if neighbour_node not in explored and all(neighbour_node not in queue_tuple for queue_tuple in node_queue): node_queue.append((neighbour_priority, neighbour_node)) node_queue = sorted(node_queue, key=itemgetter(0)) elif (index := [ - index for index, queue_tuple in enumerate(node_queue) if neighbour_priority > queue_tuple[0] - ][0]): - node_queue[index] = (neighbour_priority, neighbour_node) + index for index, queue_tuple in enumerate(node_queue) if neighbour_priority > queue_tuple[0] and neighbour_node == queue_tuple[1] + ]): + print(index) + node_queue[index[0]] = (neighbour_priority, neighbour_node) node_queue = sorted(node_queue, key=itemgetter(0)) - return False, False \ No newline at end of file + return False, False + + +def heuristic(a: Tuple[int, int], b: Tuple[int, int]): + (x1,y1) = a + (x2,y2) = b + return abs(x1 - x2) + abs(y1 - y2) + + +def nearest_bomb(a: Tuple[int, int],field: List[List[Tile]]): + min = 20 + min_x = 0 + min_y = 0 + for x in range(10): + for y in range(10): + if issubclass(Mine,field[x][y].mine.__class__): + distance = abs(a[0] - x) + abs(a[1] - y) + if distance < min: + min = distance + min_x = x + min_y = y + return (min_x, min_y) \ No newline at end of file diff --git a/src/search_algoritms/helpers.py b/src/search_algoritms/helpers.py index 1229b33..f4a701f 100644 --- a/src/search_algoritms/helpers.py +++ b/src/search_algoritms/helpers.py @@ -1,9 +1,31 @@ -from typing import List +from typing import List, Tuple import pygame as pg -from tile import Tile -from node import Node +from src.node import Node +from src.tile import Tile + + +def successor(field: List[List[Tile]], x: int, y: int, direction: int): + """ + kody klawiszy: + :a -> 97 + :d -> 100 + :w -> 119 + """ + neighbours = [] + coord = 'x' if direction in (1, 3) else 'y' + shift = -1 if direction in (0, 3) else 1 + + neighbours.append((x, y, (direction - 1) % 4, pg.K_a)) + neighbours.append((x, y, (direction + 1) % 4, pg.K_d)) + + if coord == 'x' and 0 <= x + shift <= 9 and field[y][x + shift].number not in (2, 3): + neighbours.append((x + shift, y, direction, pg.K_w)) + elif coord == 'y' and 0 <= y + shift <= 9 and field[y + shift][x].number not in (2, 3): + neighbours.append((x, y + shift, direction, pg.K_w)) + + return neighbours def successor(field: List[List[Tile]], x: int, y: int, direction: int): @@ -36,3 +58,37 @@ def get_path_actions(node: Node): actions.append(node.action) node = node.parent return path[::-1], actions[::-1] + + +def successor_priority(field: List[List[Tile]], x: int, y: int, direction: int): + """ + kody klawiszy: + :a -> 97 + :d -> 100 + :w -> 119 + """ + neighbours = [] + coord = 'x' if direction in (1, 3) else 'y' + shift = -1 if direction in (0, 3) else 1 + + neighbours.append((x, y, (direction - 1) % 4, pg.K_a)) + neighbours.append((x, y, (direction + 1) % 4, pg.K_d)) + + if coord == 'x' and 0 <= x + shift <= 9 and field[y][x + shift].number not in (2, 3): + neighbours.append((x + shift, y, direction, pg.K_w)) + elif coord == 'y' and 0 <= y + shift <= 9 and field[y + shift][x].number not in (2, 3): + neighbours.append((x, y + shift, direction, pg.K_w)) + + return neighbours + + +def cost(field: List[List[Tile]], node): + return field[node.x][node.y].weight + + +def calculate_priority(field: List[List[Tile]], node, goaltest: Tuple[int, int]): + return cost(field, node) + heuristic(node, goaltest) + + +def heuristic(a, b): + return abs(a.x - b[0]) + abs(a.y - b[1]) diff --git a/src/tile.py b/src/tile.py index 075a468..e2205ef 100644 --- a/src/tile.py +++ b/src/tile.py @@ -5,6 +5,7 @@ from at_mine import ATMine class Tile: - def __init__(self, number: int, mine: Union[None, APMine, ATMine] = None): + def __init__(self, number: int,weight: int, mine: Union[None, APMine, ATMine] = None): self.number = number self.mine = mine + self.weight = weight diff --git a/src/tilesFactory.py b/src/tilesFactory.py index d995653..b7b6eb0 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, getattr(module, f'{img.mine_type}Mine')) + return Tile(number, 1, getattr(module, f'{img.mine_type}Mine')) else: - return Tile(number, None) + return Tile(number, 1, None) if img.name.find('grass') else Tile(number,3, None) def get_tiles_list(self) -> List[Tile]: - return [self.create_tile(i) for i in range(11)] + return [self.create_tile(i) for i in range(13)]