diff --git a/src/node.py b/src/node.py index 621a9f7..f73c903 100644 --- a/src/node.py +++ b/src/node.py @@ -4,14 +4,18 @@ from pygame import event class Node: - def __init__(self, x: int, y: int, direction: int, parent: Node = None, action: event = None): + def __init__(self, x: int, y: int, direction: int, parent: Node = None, action: event = None, cost=0): self.x = x self.y = y self.direction = direction self.parent = parent self.action = action + self.cost = cost def __eq__(self, other): if isinstance(other, Node): return self.x == other.x and self.y == other.y and self.direction == other.direction return False + + def __lt__(self, other): + return self.cost < other.cost diff --git a/src/search_algoritms/a_star.py b/src/search_algoritms/a_star.py index 6d776d6..9a12b9e 100644 --- a/src/search_algoritms/a_star.py +++ b/src/search_algoritms/a_star.py @@ -1,21 +1,19 @@ -from typing import List, Tuple from operator import itemgetter +from typing import List, Tuple -from src.node import Node -from src.tile import Tile 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 def a_star(field: List[List[Tile]], start_x: int, start_y: int, start_direction: int, goal: Tuple[int, int]): - print(goal) explored = [] - 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) + node_queue: List[Node] = [Node(start_x, start_y, start_direction)] while node_queue: - priority, node = node_queue.pop(0) + node = node_queue.pop(0) # przy get wyciąga element z najniższą wartością priorytetu if (node.x, node.y) == goal: @@ -24,22 +22,23 @@ 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(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)) + neighbour_node.cost = calculate_priority(field, neighbour_node, goal) + if neighbour_node not in explored and neighbour_node not in node_queue: + node_queue.append(neighbour_node) + node_queue.sort() elif (index := [ - index for index, queue_tuple in enumerate(node_queue) if neighbour_priority > queue_tuple[0] and neighbour_node == queue_tuple[1] + index for index, node_in_queue in enumerate(node_queue) if + neighbour_node == node_in_queue and neighbour_node.cost < node_in_queue.cost ]): - node_queue[index[0]] = (neighbour_priority, neighbour_node) + node_queue[index[0]] = neighbour_node node_queue = sorted(node_queue, key=itemgetter(0)) return False, False def heuristic(a: Tuple[int, int], b: Tuple[int, int]): - (x1,y1) = a - (x2,y2) = b + (x1, y1) = a + (x2, y2) = b return abs(x1 - x2) + abs(y1 - y2) @@ -55,4 +54,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) \ No newline at end of file + return (min_x, min_y) diff --git a/src/search_algoritms/helpers.py b/src/search_algoritms/helpers.py index f4a701f..783cfe7 100644 --- a/src/search_algoritms/helpers.py +++ b/src/search_algoritms/helpers.py @@ -6,28 +6,6 @@ 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): """ kody klawiszy: @@ -60,34 +38,12 @@ def get_path_actions(node: Node): 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 + return field[node.y][node.x].weight -def calculate_priority(field: List[List[Tile]], node, goaltest: Tuple[int, int]): - return cost(field, node) + heuristic(node, goaltest) +def calculate_priority(field: List[List[Tile]], node, goal_test: Tuple[int, int]): + return node.parent.cost + cost(field, node) + heuristic(node, goal_test) def heuristic(a, b):