add node cost and add lt comparator, adjust a_star and helpers to use node.cost,

This commit is contained in:
matixezor 2021-04-26 13:52:32 +02:00
parent f225f42ba9
commit 4fae45b696
3 changed files with 23 additions and 64 deletions

View File

@ -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

View File

@ -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)
return (min_x, min_y)

View File

@ -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):