def shortest_path(self, environment, start, end): queue = Queue([start]) visited_nodes = set([start]) shortest_path = [] while queue.queue: current_node = queue.dequeue() if current_node == end: shortest_path = self._recreate_path_for_node(current_node) break for action in environment.possible_actions_for_current_action( current_node.action): child_node_point = Point(current_node.point.x + action[0], current_node.point.y + action[1]) neighbor = environment.tiles[child_node_point.y][ child_node_point.x] if neighbor == Tile.empty or neighbor == Tile.fruit: child_node = Node(child_node_point) child_node.action = action child_node.previous_node = current_node if child_node not in visited_nodes and child_node not in queue.queue: visited_nodes.add(current_node) queue.enqueue(child_node) if shortest_path: return shortest_path else: return []
def move(self, environment): BaseGameModel.move(self, environment) shortest_path_move_from_transposition_table = self._path_move_from_transposition_table( self.starting_node, self.fruit_node) if shortest_path_move_from_transposition_table: return shortest_path_move_from_transposition_table stack = Stack([self.starting_node]) visited_nodes = set([self.starting_node]) shortest_path = [] while stack.stack: current_node = stack.pop() if current_node == self.fruit_node: shortest_path = self._recreate_path_for_node(current_node) for move in environment.possible_actions_for_current_action( current_node.action): child_node_point = Point(current_node.point.x + move[0], current_node.point.y + move[1]) neighbor = environment.tiles[child_node_point.y][ child_node_point.x] if neighbor == Tile.empty or neighbor == Tile.fruit: child_node = Node(child_node_point) child_node.action = move child_node.previous_node = current_node if child_node not in visited_nodes and child_node not in stack.stack: visited_nodes.add(current_node) stack.push(child_node) if shortest_path: self.transposition_table[self.fruit_node] = shortest_path first_point = shortest_path[-2] return first_point.action return environment.snake_action
def _neighbor(self, node, action, environment): neighbor_point = Point(node.point.x + action[0], node.point.y + action[1]) neighbor_tile = environment.tiles[neighbor_point.y][neighbor_point.x] if neighbor_tile == Tile.empty or neighbor_tile == Tile.fruit: neighbor_node = Node(neighbor_point) neighbor_node.previous_node = node neighbor_node.action = action return neighbor_node return None
def _hamilton_path(self, environment): head = self.starting_node inverse_snake_action = (environment.snake_action[0] * -1, environment.snake_action[1] * -1) tail = environment.snake[-1] tail_point = Point(tail.x + inverse_snake_action[0], tail.y + inverse_snake_action[1]) tail = Node(tail_point) if self.hamilton_path: return self.hamilton_path longest_path_solver = LongestPathSolver() self.hamilton_path = longest_path_solver.longest_path( head, tail, environment) return self.hamilton_path
def move(self, environment): self.starting_node = Node(environment.snake[0]) self.starting_node.action = environment.snake_action self.fruit_node = Node(environment.fruit[0])