diff --git a/astar.py b/astar.py index bfd3d14..27c6bd6 100644 --- a/astar.py +++ b/astar.py @@ -2,7 +2,8 @@ from collections import namedtuple from dataclasses import dataclass from enum import Enum from math import floor -from random import choice +from random import shuffle +from queue import PriorityQueue import pygame XYPair = namedtuple("XYPair", "x y") @@ -28,7 +29,7 @@ class NodeStates(Enum): @dataclass class Render_Info: - screen_dimensions: XYPair = XYPair(1000,1000) + screen_dimensions: XYPair = XYPair(1000,800) padding: XYPair = XYPair(1, 1) background_color = Colors.BLACK.value @@ -118,8 +119,7 @@ class Node: if self.tcost != other.tcost: return self.tcost < other.tcost return self.gcost < other.gcost - - + def draw(self, screen) -> bool: screen.blit(self.image, self.rect) @@ -144,18 +144,15 @@ class Board: self.start_node.set_state(NodeStates.START) self.goal_node.set_state(NodeStates.GOAL) 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: self.matrix[point.y][point.x].set_state(NodeStates.WALL) def _pick_n_points(self, n: int): - points = [] - set_of_points = set(XYPair(x, y) for x in range(self.dimensions.x) for y in range(self.dimensions.y)) - for _ in range(n): - last_point = choice(tuple(set_of_points)) - points.append(last_point) - set_of_points = set_of_points - {last_point} - return points + set_of_points = [XYPair(x, y) for x in range(self.dimensions.x) for y in range(self.dimensions.y)] + shuffle(set_of_points) + return set_of_points[:n] def _normalize_point(self, point: XYPair): @@ -180,17 +177,17 @@ class Board: def explore(self): - if not self.seen_unexplored: + if self.seen_unexplored is None or self.seen_unexplored.empty(): return False - target = min(self.seen_unexplored) - self.seen_unexplored.remove(target) + target = self.seen_unexplored.get() if target.state == NodeStates.GOAL: target.solve() - self.seen_unexplored = [] + self.seen_unexplored = None return True options = self._get_surrounding(target.position) + for option in options: option.calculate_gcost(self.goal_node.position) option.calculate_scost(target) @@ -198,7 +195,7 @@ class Board: if option.state != NodeStates.SEEN: #prevents double appends if option.state != NodeStates.GOAL: option.set_state(NodeStates.SEEN) - self.seen_unexplored.append(option) + self.seen_unexplored.put(option) if target.state != NodeStates.START: target.set_state(NodeStates.EXPLORED) @@ -212,7 +209,7 @@ class Board: def main(): 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) running = True evolving = False @@ -221,15 +218,13 @@ def main(): while running: - clock.tick(10) - board.draw(screen) pygame.display.flip() if evolving: if not board.explore(): 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(): if event.type == pygame.QUIT: @@ -240,10 +235,7 @@ def main(): evolving = not evolving 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__": main() \ No newline at end of file