def getFeatures(self, state, action): # Extract the grid of food and wall locations and get the ghost locations. food = state.getFood() walls = state.getWalls() ghosts = state.getGhostPositions() features = counter.Counter() features["bias"] = 1.0 # Compute the location of pacman after he takes the action. x, y = state.getPacmanPosition() dx, dy = Actions.directionToVector(action) next_x, next_y = int(x + dx), int(y + dy) # Count the number of ghosts 1-step away. features["#-of-ghosts-1-step-away"] = sum( (next_x, next_y) in Actions.getLegalNeighbors(g, walls) for g in ghosts) # If there is no danger of ghosts then add the food feature. if not features["#-of-ghosts-1-step-away"] and food[next_x][next_y]: features["eats-food"] = 1.0 prob = AnyFoodSearchProblem(state, start=(next_x, next_y)) dist = len(search.bfs(prob)) if dist is not None: # Make the distance a number less than one otherwise the update will diverge wildly. features["closest-food"] = float(dist) / (walls.getWidth() * walls.getHeight()) features.divideAll(10.0) return features
def successorStates(self, state): successors = [] for action in Directions.CARDINAL: x, y = state[0] dx, dy = Actions.directionToVector(action) nextx, nexty = int(x + dx), int(y + dy) hitsWall = self.walls[nextx][nexty] if (not hitsWall): # Construct the successor. nextPosition = (nextx, nexty) if state[0] in self.cornersCheck: self.cornersVisitedList.append(state[0]) self.cornersCheck.remove(state[0]) nextState = ((nextPosition), state[1]) successors.append((nextState, action)) # if nextPosition in self.cornersCheck: # self.cornersVisitedList.append(nextPosition) # self.cornersCheck.remove(nextPosition) self._numExpanded += 1 if (state[0] not in self._visitedLocations): self._visitedLocations.add(state[0]) self._visitHistory.append(state[0]) return successors raise NotImplementedError()
def successorStates(self, state): """ Returns successor states, the actions they require, and a constant cost of 1. """ successors = [] for action in Directions.CARDINAL: pendingCor = state[1] x, y = state[0] dx, dy = Actions.directionToVector(action) nextx, nexty = int(x + dx), int(y + dy) if not self.walls[nextx][nexty]: if (nextx, nexty) in pendingCor: # Operations to remove corner from the tuple t = tuple() for i in range(len(pendingCor)): if i != pendingCor.index((nextx, nexty)): t = t + (pendingCor[i], ) pendingCor = t nextState = ((nextx, nexty), pendingCor) cost = 1 successors.append((nextState, action, cost)) # Bookkeeping for display purposes (the highlight in the GUI). self._numExpanded += 1 return successors
def applyAction(state, action, agentIndex): """ Edits the state to reflect the results of the action. """ legal = AgentRules.getLegalActions(state, agentIndex) if (action not in legal): raise ValueError('Illegal action: ' + str(action)) agentState = state.getAgentState(agentIndex) # Update position. vector = Actions.directionToVector(action, AgentRules.AGENT_SPEED) agentState.updatePosition(vector) # Eat. nextPosition = agentState.getPosition() nearest = nearestPoint(nextPosition) if (agentState.isPacman() and manhattan(nearest, nextPosition) <= 0.9): AgentRules.consume(nearest, state, state.isOnRedTeam(agentIndex)) # Potentially change agent type. if (nextPosition == nearest): # Agents are pacmen when they are not on their own side. position = agentState.getPosition() agentState.setIsPacman(state.isOnRedTeam(agentIndex) != state.isOnRedSide(position))
def successorStates(self, state): successors = [] for action in Directions.CARDINAL: pos, corners = state x, y = pos dx, dy = Actions.directionToVector(action) nextx, nexty = int(x + dx), int(y + dy) if (not self.walls[nextx][nexty]): nextState = ( (nextx, nexty), ((nextx, nexty) == self.corners[0] or corners[0], (nextx, nexty) == self.corners[1] or corners[1], (nextx, nexty) == self.corners[2] or corners[2], (nextx, nexty) == self.corners[3] or corners[3]) ) cost = 1 successors.append((nextState, action, cost)) # Bookkeeping for display purposes (the highlight in the GUI). self._numExpanded += 1 if (state not in self._visitedLocations): self._visitedLocations.add(state[0]) self._visitHistory.append(state[0]) return successors
def successorStates(self, state): """ Returns successor states, the actions they require, and a constant cost of 1. """ successors = [] for action in Directions.CARDINAL: x, y = state dx, dy = Actions.directionToVector(action) nextx, nexty = int(x + dx), int(y + dy) if (not self.walls[nextx][nexty]): nextState = (nextx, nexty) cost = self.costFn(nextState) successors.append((nextState, action, cost)) # Bookkeeping for display purposes (the highlight in the GUI). self._numExpanded += 1 if (state not in self._visitedLocations): self._visitedLocations.add(state) self._visitHistory.append(state) return successors
def getLegalActions(state, agentIndex): """ Returns a list of possible actions. """ agentState = state.getAgentState(agentIndex) return Actions.getPossibleActions(agentState.getPosition(), agentState.getDirection(), state.getWalls())
def getLegalActions(state, ghostIndex): """ Ghosts cannot stop, and cannot turn around unless they reach a dead end, but can turn 90 degrees at intersections. """ agentState = state.getGhostState(ghostIndex) possibleActions = Actions.getPossibleActions(agentState.getPosition(), agentState.getDirection(), state.getWalls()) reverse = Actions.reverseDirection(agentState.getDirection()) if (Directions.STOP in possibleActions): possibleActions.remove(Directions.STOP) if (reverse in possibleActions and len(possibleActions) > 1): possibleActions.remove(reverse) return possibleActions
def applyAction(state, action, ghostIndex): legal = GhostRules.getLegalActions(state, ghostIndex) if (action not in legal): raise ValueError('Illegal ghost action: ' + str(action)) ghostState = state.getGhostState(ghostIndex) speed = GhostRules.GHOST_SPEED if (ghostState.isScared()): speed /= 2.0 vector = Actions.directionToVector(action, speed) ghostState.updatePosition(vector)
def updatePosition(self, vector): """ Update the position and direction with the given movement vector. """ x, y = self._position dx, dy = vector self._position = (x + dx, y + dy) direction = Actions.vectorToDirection(vector) if (direction != Directions.STOP): # If this is a zero vector, face the same direction as before. self._direction = direction
def actionsCost(self, actions): """ Returns the cost of a particular sequence of actions. If those actions include an illegal move, return 999999. """ x, y = self.startingState()[0] cost = 0 for action in actions: # figure out the next state and see whether it's legal dx, dy = Actions.directionToVector(action) x, y = int(x + dx), int(y + dy) if self.walls[x][y]: return 999999 cost += 1 return cost
def actionsCost(self, actions): """ Returns the cost of a particular sequence of actions. If those actions include an illegal move, return 999999. This is implemented for you. """ if (actions is None): return 999999 x, y = self.startingPosition for action in actions: dx, dy = Actions.directionToVector(action) x, y = int(x + dx), int(y + dy) if self.walls[x][y]: return 999999 return len(actions)
def successorStates(self, state): successors = [] for action in Directions.CARDINAL: x, y = state[0] corners = state[2] dx, dy = Actions.directionToVector(action) nextx, nexty = int(x + dx), int(y + dy) if (not self.walls[nextx][nexty]): successors.append(((nextx, nexty), action, corners.copy())) self._numExpanded += 1 if (state[0] not in self._visitedLocations): self._visitedLocations.add(state[0]) self._visitHistory.append(state[0]) return successors
def successorStates(self, state): successors = [] for action in Directions.CARDINAL: x, y = state[0] dx, dy = Actions.directionToVector(action) nextx, nexty = int(x + dx), int(y + dy) hitsWall = self.walls[nextx][nexty] if (not hitsWall): nextState = (nextx, nexty) if (nextState in self.corners): successors.append( ((nextState, state[1] | {nextState}), action, 1)) else: successors.append(((nextState, state[1]), action, 1)) self._numExpanded += 1 return successors
def getDistribution(self, state): # Read variables from state. ghostState = state.getGhostState(self.index) legalActions = state.getLegalActions(self.index) pos = state.getGhostPosition(self.index) isScared = ghostState.isScared() speed = 1 if (isScared): speed = 0.5 actionVectors = [ Actions.directionToVector(a, speed) for a in legalActions ] newPositions = [(pos[0] + a[0], pos[1] + a[1]) for a in actionVectors] pacmanPosition = state.getPacmanPosition() # Select best actions given the state. distancesToPacman = [ distance.manhattan(pos, pacmanPosition) for pos in newPositions ] if (isScared): bestScore = max(distancesToPacman) bestProb = self.prob_scaredFlee else: bestScore = min(distancesToPacman) bestProb = self.prob_attack zipActions = zip(legalActions, distancesToPacman) bestActions = [ action for action, distance in zipActions if distance == bestScore ] # Construct distribution. dist = counter.Counter() for a in bestActions: dist[a] = float(bestProb) / len(bestActions) for a in legalActions: dist[a] += float(1 - bestProb) / len(legalActions) dist.normalize() return dist
def successorStates(self, state): """ Returns successor states, the actions they require, and a cost of 1. """ successors = [] self._numExpanded += 1 for direction in [ Directions.NORTH, Directions.SOUTH, Directions.EAST, Directions.WEST ]: x, y = state[0] dx, dy = Actions.directionToVector(direction) nextx, nexty = int(x + dx), int(y + dy) if not self.walls[nextx][nexty]: nextFood = state[1].copy() nextFood[nextx][nexty] = False successors.append((((nextx, nexty), nextFood), direction, 1)) return successors
def applyAction(state, action): """ Edits the state to reflect the results of the action. """ legal = PacmanRules.getLegalActions(state) if (action not in legal): raise ValueError('Illegal pacman action: ' + str(action)) pacmanState = state.getPacmanState() # Update position. vector = Actions.directionToVector(action, PacmanRules.PACMAN_SPEED) pacmanState.updatePosition(vector) # Eat. nextPosition = pacmanState.getPosition() nearest = nearestPoint(nextPosition) if (manhattan(nearest, nextPosition) <= 0.5): # Remove food PacmanRules.consume(nearest, state)
def actionsCost(self, actions): """ Returns the cost of a particular sequence of actions. If those actions include an illegal move, return 999999. """ if (actions is None): return 999999 x, y = self.startingState() cost = 0 for action in actions: # Check figure out the next state and see whether its' legal dx, dy = Actions.directionToVector(action) x, y = int(x + dx), int(y + dy) if (self.walls[x][y]): return 999999 cost += self.costFn((x, y)) return cost