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 _random_available_position(self): tile = None while tile is None or tile is not Tile.empty: random_x = random.randint(0, self.height - 1) random_y = random.randint(0, self.width - 1) tile = self.tiles[random_x][random_y] return Point(random_x, random_y)
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 _points_of(self, environment_object): points = [] for y in range(0, self.height): for x in range(0, self.width): tile = self.tiles[y][x] if tile == environment_object: points.append(Point(x, y)) return points
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 print_path(self, path): environment_string = "" for y in range(0, self.height): environment_string += "\n" for x in range(0, self.width): tile = self.tiles[y][x] for p in path: if tile == Tile.empty and p.point == Point(x, y): tile = Action.description(p.action) environment_string += " " + tile + " " print environment_string
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