add node cost and add lt comparator, adjust a_star and helpers to use node.cost,
This commit is contained in:
parent
f225f42ba9
commit
4fae45b696
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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):
|
||||
|
Loading…
Reference in New Issue
Block a user