Changed seen_explored list to PriorityQueue
This commit is contained in:
42
astar.py
42
astar.py
@@ -2,7 +2,8 @@ from collections import namedtuple
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from math import floor
|
from math import floor
|
||||||
from random import choice
|
from random import shuffle
|
||||||
|
from queue import PriorityQueue
|
||||||
import pygame
|
import pygame
|
||||||
|
|
||||||
XYPair = namedtuple("XYPair", "x y")
|
XYPair = namedtuple("XYPair", "x y")
|
||||||
@@ -28,7 +29,7 @@ class NodeStates(Enum):
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Render_Info:
|
class Render_Info:
|
||||||
screen_dimensions: XYPair = XYPair(1000,1000)
|
screen_dimensions: XYPair = XYPair(1000,800)
|
||||||
padding: XYPair = XYPair(1, 1)
|
padding: XYPair = XYPair(1, 1)
|
||||||
background_color = Colors.BLACK.value
|
background_color = Colors.BLACK.value
|
||||||
|
|
||||||
@@ -118,8 +119,7 @@ class Node:
|
|||||||
if self.tcost != other.tcost:
|
if self.tcost != other.tcost:
|
||||||
return self.tcost < other.tcost
|
return self.tcost < other.tcost
|
||||||
return self.gcost < other.gcost
|
return self.gcost < other.gcost
|
||||||
|
|
||||||
|
|
||||||
def draw(self, screen) -> bool:
|
def draw(self, screen) -> bool:
|
||||||
screen.blit(self.image, self.rect)
|
screen.blit(self.image, self.rect)
|
||||||
|
|
||||||
@@ -144,18 +144,15 @@ class Board:
|
|||||||
self.start_node.set_state(NodeStates.START)
|
self.start_node.set_state(NodeStates.START)
|
||||||
self.goal_node.set_state(NodeStates.GOAL)
|
self.goal_node.set_state(NodeStates.GOAL)
|
||||||
self.start_node.scost = 0
|
self.start_node.scost = 0
|
||||||
self.seen_unexplored = [self.start_node]
|
self.seen_unexplored = PriorityQueue()
|
||||||
|
self.seen_unexplored.put(self.start_node)
|
||||||
for point in special_points:
|
for point in special_points:
|
||||||
self.matrix[point.y][point.x].set_state(NodeStates.WALL)
|
self.matrix[point.y][point.x].set_state(NodeStates.WALL)
|
||||||
|
|
||||||
def _pick_n_points(self, n: int):
|
def _pick_n_points(self, n: int):
|
||||||
points = []
|
set_of_points = [XYPair(x, y) for x in range(self.dimensions.x) for y in range(self.dimensions.y)]
|
||||||
set_of_points = set(XYPair(x, y) for x in range(self.dimensions.x) for y in range(self.dimensions.y))
|
shuffle(set_of_points)
|
||||||
for _ in range(n):
|
return set_of_points[:n]
|
||||||
last_point = choice(tuple(set_of_points))
|
|
||||||
points.append(last_point)
|
|
||||||
set_of_points = set_of_points - {last_point}
|
|
||||||
return points
|
|
||||||
|
|
||||||
def _normalize_point(self, point: XYPair):
|
def _normalize_point(self, point: XYPair):
|
||||||
|
|
||||||
@@ -180,17 +177,17 @@ class Board:
|
|||||||
|
|
||||||
def explore(self):
|
def explore(self):
|
||||||
|
|
||||||
if not self.seen_unexplored:
|
if self.seen_unexplored is None or self.seen_unexplored.empty():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
target = min(self.seen_unexplored)
|
target = self.seen_unexplored.get()
|
||||||
self.seen_unexplored.remove(target)
|
|
||||||
if target.state == NodeStates.GOAL:
|
if target.state == NodeStates.GOAL:
|
||||||
target.solve()
|
target.solve()
|
||||||
self.seen_unexplored = []
|
self.seen_unexplored = None
|
||||||
return True
|
return True
|
||||||
|
|
||||||
options = self._get_surrounding(target.position)
|
options = self._get_surrounding(target.position)
|
||||||
|
|
||||||
for option in options:
|
for option in options:
|
||||||
option.calculate_gcost(self.goal_node.position)
|
option.calculate_gcost(self.goal_node.position)
|
||||||
option.calculate_scost(target)
|
option.calculate_scost(target)
|
||||||
@@ -198,7 +195,7 @@ class Board:
|
|||||||
if option.state != NodeStates.SEEN: #prevents double appends
|
if option.state != NodeStates.SEEN: #prevents double appends
|
||||||
if option.state != NodeStates.GOAL:
|
if option.state != NodeStates.GOAL:
|
||||||
option.set_state(NodeStates.SEEN)
|
option.set_state(NodeStates.SEEN)
|
||||||
self.seen_unexplored.append(option)
|
self.seen_unexplored.put(option)
|
||||||
|
|
||||||
if target.state != NodeStates.START:
|
if target.state != NodeStates.START:
|
||||||
target.set_state(NodeStates.EXPLORED)
|
target.set_state(NodeStates.EXPLORED)
|
||||||
@@ -212,7 +209,7 @@ class Board:
|
|||||||
|
|
||||||
def main():
|
def main():
|
||||||
render_info = Render_Info()
|
render_info = Render_Info()
|
||||||
board = Board(XYPair(50, 50), 0.45, render_info)
|
board = Board(XYPair(100, 80), 0.45, render_info)
|
||||||
screen = pygame.display.set_mode(render_info.screen_dimensions)
|
screen = pygame.display.set_mode(render_info.screen_dimensions)
|
||||||
running = True
|
running = True
|
||||||
evolving = False
|
evolving = False
|
||||||
@@ -221,15 +218,13 @@ def main():
|
|||||||
|
|
||||||
while running:
|
while running:
|
||||||
|
|
||||||
clock.tick(10)
|
|
||||||
|
|
||||||
board.draw(screen)
|
board.draw(screen)
|
||||||
pygame.display.flip()
|
pygame.display.flip()
|
||||||
|
|
||||||
if evolving:
|
if evolving:
|
||||||
if not board.explore():
|
if not board.explore():
|
||||||
pygame.time.wait(5000)
|
pygame.time.wait(5000)
|
||||||
board = Board(XYPair(50, 50), 0.45, render_info)
|
board = Board(XYPair(100, 80), 0.45, render_info)
|
||||||
|
|
||||||
for event in pygame.event.get():
|
for event in pygame.event.get():
|
||||||
if event.type == pygame.QUIT:
|
if event.type == pygame.QUIT:
|
||||||
@@ -240,10 +235,7 @@ def main():
|
|||||||
evolving = not evolving
|
evolving = not evolving
|
||||||
|
|
||||||
if event.key == pygame.K_ESCAPE:
|
if event.key == pygame.K_ESCAPE:
|
||||||
board = Board(XYPair(50, 50), 0.45, render_info)
|
board = Board(XYPair(100, 80), 0.45, render_info)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
Reference in New Issue
Block a user