from typing import List from core.mushroom import Mushroom from core.node import Node from core.tree import Tree def a_star(board, fringe, explored, istate, successor, get_cost, goaltest): agent_x = istate[0] agent_y = istate[1] agent_angle = istate[2] fringe: List[Node] = [Node(agent_x, agent_y, agent_angle)] while fringe: if not fringe: return False, False node = min(fringe, key=lambda x: x.cost) fringe.remove(node) if (node.x, node.y) == goaltest: actions = [] while node.parent is not None: actions.append(node.action) node = node.parent actions.reverse() return actions explored.append(node) for action, x, y, angle in successor(board, node.x, node.y, node.angle): next_node = Node(x, y, angle) next_node.parent = node next_node.action = action next_node.cost = get_cost(next_node, goaltest, board) + heuristic_function(next_node, goaltest, board) if next_node not in fringe and next_node not in explored: fringe.append(next_node) else: for checked_node in fringe: if checked_node == next_node and next_node.cost < checked_node.cost: fringe[fringe.index(checked_node)] = next_node def successor(board, x, y, angle): result = [] result.append(("rotate_left", x, y, (angle + 1) % 4)) result.append(("rotate_right", x, y, (angle - 1) % 4)) if angle == 1: if x > 0: result.append(("move", x - 1, y, angle)) elif angle == 0: if y > 0: result.append(("move", x, y - 1, angle)) elif angle == 3: if x < board.col - 1: result.append(("move", x + 1, y, angle)) elif angle == 2: if y < board.row - 1: result.append(("move", x, y + 1, angle)) return result def get_cost(node, goal: Mushroom, board): if (node.parent.x, node.parent.y) == (node.x, node.y): weight = 1 elif isinstance((board.board[node.x][node.y]), Tree): weight = 1000 elif isinstance((board.board[node.x][node.y]), Mushroom) and board.dt.predict(board.board[node.x][node.y]): weight = 1000 else: weight = 2 return weight + node.parent.cost def heuristic_function(node, goal, board): try: return abs(node.x - goal[0]) + abs(node.y - goal[1]) except: print("No more edible mushrooms on the board. Score: " + str(board.agent.points)) exit(0) def bfs(istate, successor, board): fringe = [] explored = [] fringe_states = set() explored_states = set() agent_x = istate[0] agent_y = istate[1] agent_angle = istate[2] fringe.append(Node(agent_x, agent_y, agent_angle)) fringe_states.add((agent_x, agent_y, agent_angle)) while fringe: if not fringe: return False, False node = fringe.pop(0) fringe_states.remove((node.x, node.y, node.angle)) if isinstance((board.board[node.x][node.y]), Mushroom): if not board.dt.predict(board.board[node.x][node.y]): return node.x, node.y explored.append(node) explored_states.add((node.x, node.y, node.angle)) for action, x, y, angle in successor(board, node.x, node.y, node.angle): if ((x, y, angle) not in explored_states and (x, y, angle) not in fringe_states): next_node = Node(x, y, angle) next_node.parent = node next_node.action = action fringe.append(next_node) fringe_states.add((x, y, angle))