def __init__(self, startingGameState: pacman.GameState): """ Stores the walls, pacman's starting position and corners. """ self.walls = startingGameState.getWalls() self.startingPosition = startingGameState.getPacmanPosition() top, right = self.walls.height - 2, self.walls.width - 2 self.corners = ((1, 1), (1, top), (right, 1), (right, top)) for corner in self.corners: if not startingGameState.hasFood(*corner): print('Warning: no food in corner ' + str(corner)) self._expanded = 0 # DO NOT CHANGE; Number of search nodes expanded # Please add any code here which you would like to use # in initializing the problem "*** YOUR CODE HERE ***" self.startState = PositionWithFoods(self.startingPosition, self.corners) self.to_foods: Dict[Coordinate, Dict[Coordinate, float]] = {} for c in self.corners: queue = util.Queue() queue.push((c, 0)) distances = {} while not queue.isEmpty(): pos, dis = queue.pop() x, y = pos if pos in distances: continue distances[pos] = dis for action in DIRECTIONS: dx, dy = Actions.directionToVector(action) next_pos = int(x + dx), int(y + dy) nextx, nexty = next_pos if next_pos not in distances and not self.walls[nextx][ nexty]: queue.push((next_pos, dis + 1)) self.to_foods[c] = distances self.to_other_foods = {} def tmp(foods, curr): key = (curr, tuple(sorted(foods))) if len(foods) == 1: self.to_other_foods[key] = 0 return 0 if key in self.to_other_foods: return self.to_other_foods[key] left_overs = list(foods) left_overs.remove(curr) self.to_other_foods[key] = min( map(lambda c: self.to_foods[curr][c] + tmp(left_overs, c), left_overs)) return self.to_other_foods[key] for c in self.corners: tmp(self.corners, c)