def allManhattanHeuristic(state, problem): position, foodGrid = state foodPositions = foodGrid.asList() if len(foodPositions)==0:return 0 allManhattan = 0 allPositions = [position] + foodPositions for pos in foodPositions: minManhattan = 999999 for pos2 in allPositions: dist = util.manhattanDistance( pos2, pos ) if dist == 0: continue if dist < minManhattan: minManhattan = dist allManhattan += minManhattan minManhattan = 999999 for pos in foodPositions: dist = util.manhattanDistance( position, pos ) if dist < minManhattan: minManhattan = dist allManhattan = (allManhattan + minManhattan)/2 return allManhattan
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] "*** YOUR CODE HERE ***" yo = newFood.height/2 xo = newFood.width/2 origin = (xo, yo) q1 = [] q2 = [] q3 = [] q4 = [] for x in range(0, newFood.width): for y in range (0, newFood.height): if newFood[x][y] == True: if x > xo: if y > yo: q1.append((x, y)) else: q4.append((x, y)) else: if y > yo: q2.append((x, y)) else: q3.append((x, y)) q = [q1, q2, q3, q4] z = max(q) tot = len(z) avgx = 0 avgy = 0 for i in z: avgx += (float(i[0])/tot) avgy += (float(i[1])/tot) n = manhattanDistance((avgx, avgy), newPos) z1 = [manhattanDistance(i.getPosition(), newPos) for i in newGhostStates] t = 0 for i in q: if len(i) == 0: t += 100 if min(z1) < 2: t -= 300 return successorGameState.getScore()*4 - n*(2) + t
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] heuristic = 0 for st in newScaredTimes: heuristic += st ghostDistances = [] for gs in newGhostStates: ghostDistances += [manhattanDistance(gs.getPosition(),newPos)] foodList = newFood.asList() wallList = currentGameState.getWalls().asList() emptyFoodNeighbors = 0 foodDistances = [] def foodNeighbors(foodPos): foodNeighbors = [] foodNeighbors.append((foodPos[0]-1,foodPos[1])) foodNeighbors.append((foodPos[0],foodPos[1]-1)) foodNeighbors.append((foodPos[0],foodPos[1]+1)) foodNeighbors.append((foodPos[0]+1,foodPos[1])) return foodNeighbors for f in foodList: neighbors = foodNeighbors(f) for fn in neighbors: if fn not in wallList and fn not in foodList: emptyFoodNeighbors += 1 foodDistances += [manhattanDistance(newPos,f)] inverseFoodDist = 0 if len(foodDistances) > 0: inverseFoodDist = 1.0/(min(foodDistances)) heuristic += (min(ghostDistances)*((inverseFoodDist**4))) heuristic += successorGameState.getScore()-(float(emptyFoodNeighbors)*4.5) return heuristic
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (oldFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() oldFood = currentGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] "*** YOUR CODE HERE ***" foodDistance = [manhattanDistance(newPos, foodPos) for foodPos in oldFood.asList()] minFoodDistance = min(foodDistance) ghostsPositions = [ghost.getPosition() for ghost in newGhostStates] ghostsDistance = [manhattanDistance(newPos, ghostPos) for ghostPos in ghostsPositions] minGhostDistance = min(ghostsDistance) return 1/(minFoodDistance+0.1) - 1/(minGhostDistance+0.1)
def cornersHeuristic(state, problem): """ A heuristic for the CornersProblem that you defined. state: The current search state (a data structure you chose in your search problem) problem: The CornersProblem instance for this layout. This function should always return a number that is a lower bound on the shortest path from the state to a goal of the problem; i.e. it should be admissible (as well as consistent). """ corners = problem.corners # These are the corner coordinates walls = problem.walls # These are the walls of the maze, as a Grid (game.py) "*** YOUR CODE HERE ***" cornersBoolean = state[1] currentPosition = state[0] maxManhattan = 0 for cornerPosition, visited in cornersBoolean.iteritems(): if (visited == False) & (util.manhattanDistance(currentPosition, cornerPosition) > maxManhattan): maxManhattan = util.manhattanDistance(currentPosition, cornerPosition) return maxManhattan
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <I add the score of the scared time of the ghosts when counting the final score of the currentGameState and use almost exactly the same evaluation function as question one(I thought we have to come up with a very good evaluation function there, so I did a lot of work there. The distance of the food and the distance between the current position between pacman and ghost are the two significant factor in deciding the score. And I sum the reciprocal of food distance and then minus the sum of reciprocal of the suitable ghost distance. For scared times, because the longer the time is, the higher winning rate the pacman has. Therefore I use the result add the summation of the scared time > """ "*** YOUR CODE HERE ***" newPos = currentGameState.getPacmanPosition() newFood = currentGameState.getFood() newGhostStates = currentGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] Foodlist = newFood.asList() listDis1 = [] listDis2 = [] for elem in Foodlist: listDis1.append(1.0/util.manhattanDistance(newPos, elem)) for elem in newGhostStates: dis = util.manhattanDistance(newPos, elem.getPosition()) if dis!=0.0 and dis<3: listDis2.append(1.0/dis) foodTotal = sum(listDis1) ghostTotal = sum(listDis2) scaredScore = sum(newScaredTimes) return currentGameState.getScore()+foodTotal-28*ghostTotal+scaredScore*1.2
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] "*** YOUR CODE HERE ***" Foodlist = newFood.asList() listDis1 = [] listDis2 = [] for elem in Foodlist: listDis1.append(1.0/util.manhattanDistance(newPos, elem)) for elem in newGhostStates: dis = util.manhattanDistance(newPos, elem.getPosition()) if dis!=0.0 and dis<3: listDis2.append(1.0/dis) foodTotal = sum(listDis1) ghostTotal = sum(listDis2) return successorGameState.getScore()+foodTotal-28*ghostTotal
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] newFoodPositions = newFood.asList() score = 0 if newFoodPositions: closestFoodPos, closestFoodDist = min([(foodPos,util.manhattanDistance(newPos, foodPos)) for foodPos in newFoodPositions], key = lambda x: x[1]) closestGhostPos, closestGhostDist = min([(ghostState.getPosition(), util.manhattanDistance(newPos, ghostState.getPosition()) ) for ghostState in newGhostStates], key = lambda x: x[1]) score = (1.0/(closestFoodDist + 1)) - (2.0/(closestGhostDist + 1)) return successorGameState.getScore() + score
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> """ "*** YOUR CODE HERE ***" newPos = currentGameState.getPacmanPosition() newFood = currentGameState.getFood() newGhostStates = currentGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] ghostDis = util.manhattanDistance(newPos, newGhostStates[0].getPosition()) disFood = dict() foodDis = 0 if (len(newFood.asList())!=0): for f in newFood.asList(): disFood[f] = util.manhattanDistance(newPos, f) minFood = min(disFood, key=disFood.get) foodDis = disFood[minFood] return -0.05*foodDis-len(newFood.asList())-2**(2-ghostDis) #return currentGameState.getScore() util.raiseNotDefined()
def checkDeath( state, agentIndex): agentState = state.data.agentStates[agentIndex] if state.isOnRedTeam(agentIndex): otherTeam = state.getBlueTeamIndices() else: otherTeam = state.getRedTeamIndices() if agentState.isPacman: for index in otherTeam: otherAgentState = state.data.agentStates[index] if otherAgentState.isPacman: continue ghostPosition = otherAgentState.getPosition() if ghostPosition == None: continue if manhattanDistance( ghostPosition, agentState.getPosition() ) <= COLLISION_TOLERANCE: # award points to the other team for killing Pacmen if otherAgentState.scaredTimer <= 0: AgentRules.dumpFoodFromDeath(state, agentState, agentIndex) score = KILL_POINTS if state.isOnRedTeam(agentIndex): score = -score state.data.scoreChange += score agentState.isPacman = False agentState.configuration = agentState.start agentState.scaredTimer = 0 break else: score = KILL_POINTS if state.isOnRedTeam(agentIndex): score = -score state.data.scoreChange += score otherAgentState.isPacman = False otherAgentState.configuration = otherAgentState.start otherAgentState.scaredTimer = 0 else: # Agent is a ghost for index in otherTeam: otherAgentState = state.data.agentStates[index] if not otherAgentState.isPacman: continue pacPos = otherAgentState.getPosition() if pacPos == None: continue if manhattanDistance( pacPos, agentState.getPosition() ) <= COLLISION_TOLERANCE: #award points to the other team for killing Pacmen if agentState.scaredTimer <= 0: AgentRules.dumpFoodFromDeath(state, otherAgentState, agentIndex) score = KILL_POINTS if not state.isOnRedTeam(agentIndex): score = -score state.data.scoreChange += score otherAgentState.isPacman = False otherAgentState.configuration = otherAgentState.start otherAgentState.scaredTimer = 0 break else: score = KILL_POINTS if state.isOnRedTeam(agentIndex): score = -score state.data.scoreChange += score agentState.isPacman = False agentState.configuration = agentState.start agentState.scaredTimer = 0
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> """ "*** YOUR CODE HERE ***" newPos = currentGameState.getPacmanPosition() newFood = currentGameState.getFood() newGhostStates = currentGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] newFoodPositions = newFood.asList() score = 0 if newFoodPositions: closestFoodPos, closestFoodDist = min([(foodPos,util.manhattanDistance(newPos, foodPos)) for foodPos in newFoodPositions], key = lambda x: x[1]) closestGhostPos, closestGhostDist = min([(ghostState.getPosition(), util.manhattanDistance(newPos, ghostState.getPosition()) ) for ghostState in newGhostStates], key = lambda x: x[1]) if closestFoodDist >= 2*closestGhostDist: a = 100.0 b = 2.0 else: a = 5.0 b = 2.0 score = (a/(closestFoodDist + 1)) - (b/(closestGhostDist + 1)) return currentGameState.getScore() + score
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] food=[] for x in newFood.asList(): food.append(manhattanDistance(newPos,x)) score=0 if len(food)>0 : score=1/sum(food)+5/min(food)+successorGameState.getScore() for x in newGhostStates: if manhattanDistance(newPos,x.getPosition())<2: return -10 if score > 0: return score return successorGameState.getScore()
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (oldFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() oldFood = currentGameState.getFood().asList() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] capsules = currentGameState.getCapsules() oldFood += capsules ghostDistances = [manhattanDistance(newPos, ghost.getPosition()) for ghost in newGhostStates] closestFood = min([manhattanDistance(newPos, food) for food in oldFood]) minIndex = 0 for i in range(len(ghostDistances)): if ghostDistances[i] < ghostDistances[minIndex]: minIndex = i time = newScaredTimes[minIndex] eval = time + ghostDistances[minIndex]/float(closestFood + 1) return eval
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> """ newPos = currentGameState.getPacmanPosition() newFood = currentGameState.getFood() newGhostStates = currentGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] farest_food = 0 nearest_food = 99999 if newFood.count() > 0: for food in newFood.asList(): farest_food = max(farest_food, manhattanDistance(newPos, food)) nearest_food = min(nearest_food, manhattanDistance(newPos, food)) else: nearest_food = 0 ng = 99999 fg = 0 for ghost in newGhostStates: ng = min(ng, manhattanDistance(newPos, ghost.getPosition())) fg = max(fg, manhattanDistance(newPos, ghost.getPosition())) evaluation = currentGameState.getScore() - newFood.count(False) - 0.7 * nearest_food + 0.5 * ng return evaluation
def evaluationFunction(self, currentgameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor gameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a gameState (pacman.py) successorgameState = currentgameState.generatePacmanSuccessor(action) newPos = successorgameState.getPacmanPosition() newFood = successorgameState.getFood() newGhostStates = successorgameState.getGhostStates() foodNum = currentgameState.getFood().count() if len(newFood.asList()) == foodNum: # if this action does not eat a food dis = BIGNUM for pt in newFood.asList(): if manhattanDistance(pt , newPos) < dis : dis = manhattanDistance(pt, newPos) else: dis = 0 for ghost in newGhostStates: # the impact of ghost surges as distance get close dis += 4 ** (2 - manhattanDistance(ghost.getPosition(), newPos)) return -dis
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) oldPos = currentGameState.getPacmanPosition() newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newG = successorGameState.getGhostPositions() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] food = newFood.asList() a = [util.manhattanDistance(newPos,df) for df in food] b = [util.manhattanDistance(oldPos,df) for df in food] g = min([util.manhattanDistance(newG[i],newPos) for i in range(len(newG))]) #print action if (len(a) ==len(b)): return -1/g + 1 else: return 1/a -1/g '''if b in set(newG):
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> """ "*** YOUR CODE HERE ***" newPos = currentGameState.getPacmanPosition() newFood = currentGameState.getFood() newGhostStates = currentGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] score = 0 min_dis = float('inf') for pos in newFood.asList(): temp = manhattanDistance(pos, newPos) if temp < min_dis: min_dis = temp if (min_dis < float('inf')): score -= min_dis score -= 1000*currentGameState.getNumFood() score -= len(currentGameState.getCapsules())*10 for pos in currentGameState.getGhostPositions(): dis = manhattanDistance(pos, newPos) if (dis <= 3): score = -float('inf') score += currentGameState.getScore()*10 return score
def enhancedPacmanFeatures(state, action): """ For each state, this function is called with each legal action. It should return a counter with { <feature name> : <feature value>, ... } """ features = util.Counter() "*** YOUR CODE HERE ***" # util.raiseNotDefined() state = state.generateSuccessor(0, action) pacLocation = state.getPacmanPosition() features['numFoodLeft'] = state.getNumFood() foodLocs = state.getFood().asList() nearestFoodDist = 0 if foodLocs: nearestFoodDist = min([util.manhattanDistance(pacLocation, food) for food in foodLocs]) nearestFoodDist = 10.0/nearestFoodDist if nearestFoodDist else nearestFoodDist features['nearestFoodDist'] = nearestFoodDist ghostLocs = state.getGhostPositions() nearestGhostDist = 0 if ghostLocs: nearestGhostDist = min(util.manhattanDistance(loc, pacLocation) for loc in ghostLocs) nearestGhostDist = 10.0/nearestGhostDist if nearestGhostDist else nearestGhostDist features['nearestGhostDist'] = nearestGhostDist return features
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> """ pos = currentGameState.getPacmanPosition() lfood = currentGameState.getFood() ghostStates = currentGameState.getGhostStates() gpos =currentGameState.getGhostPositions() nfood=currentGameState.getNumFood() caps=currentGameState.getCapsules() st = [ghostState.scaredTimer for ghostState in ghostStates] food = lfood.asList() minfoodd = min([util.manhattanDistance(pos,df) for df in food]) mincapsd=min([util.manhattanDistance(pos,d) for d in caps]) g =sum([1.0/(util.manhattanDistance(gpos[i],pos)+0.1) for i in range(len(gpos))]) numOfScaredGhosts = 0 m = 0 print nfood,minfoodd,mincapsd for ghostState in ghostStates: if ghostState.scaredTimer is 0: numOfScaredGhosts += 1 if numOfScaredGhosts > 0 : m = -300.0 else: m = 300.0 return -100.0*len(caps) -20.0*len(food) +1.0/minfoodd +m*g util.raiseNotDefined()
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> I want to incentivize winning so I return infinity if that is a win state. A large part of my strategy was "don't die." Dying gives you usually ~300 or less points, which will hurt your average. Winning usually gives you more points than losing. Here are the things I considered, along with some commentary on my decision making regarding them:1 distance to the closest ghost: (disttoghost): I wanted pacman to run away from ghosts if they got too close. I did this by doing score += max(disttoghost, 4) * 2. If the ghost is more than distance 4 away, I didn't really care, and there is no difference between the ghost being 5 away and 500 away, because it's not close enough to threaten pacman. I added the max because my pacman would sometimes try to get farther away from a ghost already a long way away instead of going for food. That led to a lot of pacman idling in corners, wasting time and points. I added the * 2 so that the penalty for being near a ghost would be more severe and hopefully cause pacman to tend away from getting too close. closest food: I wanted to reward heading towards food, but not to the extent that it overrode the penalty of getting too close to a ghost. Thus, the score will be higher the closer pacman goes towards a food. By subtracting 1.5 * the distance, I got further distances to food to receive lower scores. This, however, introduced a problem where sometimes pacman would refuse to eat an isolated food because that would make the next turn's distance to food much higher. Thus, I had to add the next thing. bonus for eating food: I subtracted 4 times the number of remaining foods, so that eating food would cause a more markedly higher score. You can only eat one food per move, so this made eating food preferable over not eating food. capsules: I thought that eating ghosts would increase my score, so I tried to slightly incentivize moving onto a capsule so that eating ghosts could increase my score. Thus, I subtracted 3.5 from scores for each existing capsule. This would only make a difference near the capsule. I then watched pacman's actions and adjusted the weights and numbers to visible strategic flaws. When I last submitted this, this averaged slightly over 1000. Let's hope it does so again. """ "*** YOUR CODE HERE ***" if currentGameState.isWin(): return float("inf") if currentGameState.isLose(): return -float("inf") score = scoreEvaluationFunction(currentGameState) newFood = currentGameState.getFood() foodPos = newFood.asList() closestfood = float("inf") for pos in foodPos: thisdist = util.manhattanDistance(pos, currentGameState.getPacmanPosition()) if thisdist < closestfood: closestfood = thisdist numghosts = currentGameState.getNumAgents() - 1 i = 1 disttoghost = float("inf") while i <= numghosts: nextdist = util.manhattanDistance(currentGameState.getPacmanPosition(), currentGameState.getGhostPosition(i)) disttoghost = min(disttoghost, nextdist) i += 1 score += max(disttoghost, 4) * 2 score -= closestfood * 1.5 capsulelocations = currentGameState.getCapsules() score -= 4 * len(foodPos) score -= 3.5 * len(capsulelocations) return score
def ddist_ghost(self,state,action): pacState = state.getPacmanState() legalActions = state.getLegalPacmanActions() pacpos = pacState.getPosition() speed = 1.0 actionVector = Actions.directionToVector( action , speed ) ghostsPositions = [self.ghostsdict['bad'][0].getPosition()] for i in range(3): ghostsPositions.append(self.ghostsdict['good'][i][0].getPosition()) newPosition = (pacpos[0]+actionVector[0], pacpos[1]+actionVector[1]) curDistancesG = [manhattanDistance(pacpos,ghostPosition) for ghostPosition in ghostsPositions] distanceGhosts = [manhattanDistance(newPosition,ghostPosition) for ghostPosition in ghostsPositions] capsulesPositions = [cap[0] for cap in self.capsules] curDistancesC = [manhattanDistance(pacpos,capsulePosition) for capsulePosition in capsulesPositions] distanceCapsules = [manhattanDistance(newPosition,capsulePosition) for capsulePosition in capsulesPositions] distances = np.array(distanceGhosts+distanceCapsules) curDistances = np.array(curDistancesG+curDistancesC) candiAns = (distances-curDistances)/np.absolute(curDistances.clip(1)) if state.scaredGhostPresent(): candiAns[0] = -candiAns[0] candiAns[-2] = 0 candiAns[-1] = 0 return candiAns
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> """ "*** YOUR CODE HERE ***" newPos = currentGameState.getPacmanPosition() newFood = currentGameState.getFood().asList() newGhostStates = currentGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] newCapsules = currentGameState.getCapsules() score = currentGameState.getScore() scared = sum(newScaredTimes) dist2food = 100 if len(newFood) > 0: dist2food = min(dist2food, min([manhattanDistance(newPos, food) for food in newFood])) dist2food = 1.0/dist2food dist2cap = 100 if len(newCapsules) > 0: dist2cap = min(dist2cap, min([manhattanDistance(newPos, cap) for cap in newCapsules])) dist2cap = 1.0/dist2cap return score + dist2food + dist2cap + scared
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: Score more if we have less food left Score more if the distance to all the remaining food is less Score more if the nerest ghost is further away (up to a point, effectively ignore them once they get far enough away) """ food = currentGameState.getFood() foodList = food.asList() foodDistance = 0.001 # Make sure we don't have divide by zero pacmanPos = currentGameState.getPacmanPosition() for food in foodList: foodDistance += manhattanDistance(pacmanPos, food) minGhostDistance = None for ghostPos in currentGameState.getGhostPositions(): ghostDistance = manhattanDistance(pacmanPos, ghostPos) if minGhostDistance == None or minGhostDistance > ghostDistance: minGhostDistance = ghostDistance if minGhostDistance > 3: minGhostDistance = 0 return currentGameState.getScore() + 10.0 * (1.0 / foodDistance) + 10.0 * (2.0 / (currentGameState.getNumFood() + 1.0)) + 0.1 * minGhostDistance
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> """ "*** YOUR CODE HERE ***" # precalculamos algunas variables pacmanPos = currentGameState.getPacmanPosition() ghostStates = currentGameState.getGhostStates() food = currentGameState.getFood() # por defect retornamos el score propio del estado score = currentGameState.getScore() # si el estado es ganador retornamos directamente un score muy bueno if currentGameState.isWin(): return 100 + score # cuanta mas comida queda por comer menos score if food.count() > 0: score += (1.0 / food.count()) * 20 # si un fantasma esta asustado nos lo comemos, sino huimos for ghost in ghostStates: ghostPos = ghost.getPosition() if ghost.scaredTimer < 1: if manhattanDistance(pacmanPos, ghostPos) == 1: score = -100 else: score += (1.0 / manhattanDistance(pacmanPos, ghostPos)) * 10 # cuanto mas cerca estemos de la comida mas cercana mas score d2f = float("inf") for f in food.asList(): d2f = min(d2f, manhattanDistance(pacmanPos, f)) score -= d2f return score
def cornersHeuristic(state, problem): """ A heuristic for the CornersProblem that you defined. state: The current search state (a data structure you chose in your search problem) problem: The CornersProblem instance for this layout. This function should always return a number that is a lower bound on the shortest path from the state to a goal of the problem; i.e. it should be admissible (as well as consistent). """ corners = problem.corners walls = problem.walls currPos, cornersLeft = state dist = [] weights = [ (util.manhattanDistance(currPos, corner), corner) for corner in cornersLeft ] while weights: curMin = min(weights, key=lambda a: a[0]) weights.remove(curMin) dist.append(curMin[0]) weights = [ (util.manhattanDistance(curMin[1], corner), corner) for w, corner in weights ] return sum(dist)
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> """ pos = currentGameState.getPacmanPosition() foodGrid = currentGameState.getFood() ghostStates = currentGameState.getGhostStates() closet_ghost_pos = None ghostContrib = 0 for ghost in ghostStates: ghost_pos = util.manhattanDistance(pos, ghost.getPosition()) closet_ghost_pos = ghost_pos if not closet_ghost_pos or ghost_pos < closet_ghost_pos else closet_ghost_pos ghostContrib = -0.5*1.0/(closet_ghost_pos + 1) if ghost.scaredTimer: ghostContrib *= -2 # compute food contrib closest_food = None closest_food_distance = None for food in foodGrid.asList(): food_distance = util.manhattanDistance(pos, food) if not closest_food or closest_food_distance > food_distance: closest_food_distance = food_distance closest_food = food if not closest_food_distance: closest_food_distance = 1000000 foodContrib = 1.0/closest_food_distance - 2.1*len(foodGrid.asList()) # is a wall in our way? wall_contrib = 0 if closest_food: if closest_food[0] < pos[0]: if currentGameState.hasWall(pos[0] - 1, pos[1]): wall_contrib -= 1 elif closest_food[0] > pos[0]: if currentGameState.hasWall(pos[0] + 1, pos[1]): wall_contrib -= 1 elif closest_food[1] < pos[1]: if currentGameState.hasWall(pos[0], pos[1] - 1): wall_contrib -= 1 elif closest_food[1] > pos[1]: if currentGameState.hasWall(pos[0], pos[1] + 1): wall_contrib -= 1 # find closest power pellet powerPelletContrib = [1.0/util.manhattanDistance(pos, pellet) for pellet in currentGameState.getCapsules()] if not powerPelletContrib: powerPelletContrib = 0 else: powerPelletContrib = 0.9*min(powerPelletContrib) value = 0.5*wall_contrib + foodContrib + ghostContrib + 10*currentGameState.getScore() + powerPelletContrib return value
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() ghostContrib = -1*min([1.0/(util.manhattanDistance(newPos, ghost.getPosition()) + 1) for ghost in newGhostStates]) foodArray = [1.0/(util.manhattanDistance(newPos, food) + 1) for food in newFood.asList()] if not foodArray: foodArray = [1] foodContrib = max(foodArray) scoreContrib = (successorGameState.getScore() - currentGameState.getScore()) value = scoreContrib + ghostContrib + foodContrib return value
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] "*** YOUR CODE HERE ***" foodList = newFood.asList() minFoodDist, minGhostDist = 0, 0 if len(foodList) > 0: minFoodDist, closestFood = min((manhattanDistance(newPos, food), food) for food in foodList) if len(newGhostStates) > 0: minGhostDist, closestGhost = min((manhattanDistance(newPos, ghost.getPosition()), ghost) for ghost in newGhostStates) ghostScore = 0 if minGhostDist < 3 and closestGhost.scaredTimer <= 0: ghostScore = -100 score = 1.0 / (minFoodDist + len(foodList) + 1) + ghostScore return score + successorGameState.getScore()
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <write something here so we know what you did> """ "*** YOUR CODE HERE ***" #util.raiseNotDefined() #successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = currentGameState.getPacmanPosition() newFood = currentGameState.getFood() newGhostStates = currentGameState.getGhostStates() #newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] ghostScore = 0 foodDistance = [] minFoodDistance = 10000000 for food in newFood.asList(): foodDistance.append(manhattanDistance(food, newPos)) if len(foodDistance)>=1: minFoodDistance = min(foodDistance) foodScore = 1.0/(100+minFoodDistance) foodScore += 5.0/(len(newFood.asList())+1) for ghost in newGhostStates: dist = manhattanDistance(newPos, ghost.getPosition()) if dist <= 1 and ghost.scaredTimer <= 0: return -100000000000 elif dist < 3 and ghost.scaredTimer > 0: ghostScore += 1000000 return foodScore + ghostScore
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood().asList() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] "*** YOUR CODE HERE ***" dist2ghost = min([manhattanDistance(newPos, ghost.getPosition()) for ghost in newGhostStates]) dist2food = newFood and min([manhattanDistance(newPos, food) for food in newFood]) or 0 scaredScore = sum(newScaredTimes) dist2food = (1.0/dist2food) if (dist2food) else dist2food return successorGameState.getScore() + dist2food * dist2ghost + scaredScore
def strategyOne(state, problem): position, foodGrid = state if len(foodGrid.asList())==0: return 0 nextTarger=minDistPoint(position,foodGrid.asList()) return util.manhattanDistance(position,nextTarger)
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ ghostState.scaredTimer for ghostState in newGhostStates ] "*** YOUR CODE HERE ***" #to calculate the final score score = 0 #current gamestate data currentPos = successorGameState.getPacmanPosition() ghostStates = currentGameState.getGhostStates() currentFood = currentGameState.getFood() currentGhostStates = currentGameState.getGhostStates() ScaredTimes = [ ghostState.scaredTimer for ghostState in currentGhostStates ] newFoodNum = len(newFood.asList()) curFoodNum = len(currentFood.asList()) #calculate pos to nearest food curFoodDist = [] for food in currentFood.asList(): curFoodDist.append(manhattanDistance(currentPos, food)) #select the min minFoodDist = min(curFoodDist) #do the same for newPos newFoodDist = [] for food in newFood.asList(): newFoodDist.append(manhattanDistance(newPos, food)) #select the min minNewFoodDist = min(curFoodDist) #if is gonna eat add the score if (newFoodNum < curFoodNum): score += 200 #if you get closer to a food add score else: if (minNewFoodDist < minFoodDist): score += minNewFoodDist * 10 else: score -= minNewFoodDist * 30 #calculate current disctance from the nearest ghost curGhostDist = [] for ghost in currentGhostStates: curGhostDist.append( manhattanDistance(currentPos, ghost.getPosition())) minDist = min(curGhostDist) #do it again for newpos newGhostDist = [] for ghost in newGhostStates: newGhostDist.append(manhattanDistance(newPos, ghost.getPosition())) minNewDist = min(curGhostDist) #if the ghosts are scared in the current position #prefer the closest distance if (sum(ScaredTimes) > 0): if (minNewDist < minDist): score += (minDist - minNewDist) * 20 #if you are going to get closer remove score else: #this is a lose state so return very low score if (minNewDist <= 1): score = -100000 #if the new dist is very close to a ghost remove points elif (minNewDist <= 10): score -= minNewDist * (minDist - minNewDist) #penalty for stop if action == Directions.STOP: score -= 100 #add score if you are gonna eat a capsule if (newPos in successorGameState.getCapsules()): score += 200 return score
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: <return a score for each state based on some factors> factors: distance to closest food (40 %) distance to closest ghost (30 %) distance to pelet (30 %) """ "*** YOUR CODE HERE ***" #to calculate the final score score = 0.0 foodScore = 0 ghostScore = 0 peletScore = 0 #current gamestate data currentPos = currentGameState.getPacmanPosition() ghostStates = currentGameState.getGhostStates() currentFood = currentGameState.getFood() currentGhostStates = currentGameState.getGhostStates() ScaredTimes = [ghostState.scaredTimer for ghostState in currentGhostStates] curFoodNum = len(currentFood.asList()) currentPelets = currentGameState.getCapsules() if (currentGameState.isWin()): return 1000000 elif (currentGameState.isLose()): return -1000000 #assign score basted on food distance (the closer the better) #calculate pos to nearest food curFoodDist = [] for food in currentFood.asList(): curFoodDist.append(manhattanDistance(currentPos, food)) #select the min minFoodDist = float(min(curFoodDist)) #multiplier mult = 1.0 / minFoodDist * 100 #add score foodScore = (mult * minFoodDist) #assign score basted on ghost distance (the closer the worse) #calculate current disctance from the nearest ghost curGhostDist = [] for ghost in currentGhostStates: curGhostDist.append(manhattanDistance(currentPos, ghost.getPosition())) #select the min minDist = float(min(curGhostDist)) #if the ghosts are scared in the current position #prefer the closest distance if (sum(ScaredTimes) > 0): #fix multiplier mult = 1.0 / minDist * 100 ghostScore = (mult * minDist) #sign is 1 cause we want to add it to the score sign = 1 else: #fix multiplier mult = 0.5 ghostScore = (mult * minDist) #sign is -1 cause we want to substract it from the score sign = -1 #calculate pos to nearest pellet if (len(currentPelets) >= 1): curPeletDist = [] for pel in currentPelets: curPeletDist.append(manhattanDistance(currentPos, pel)) #select the min minPeletDist = float(min(curPeletDist)) #multiplier mult = 1.0 / minPeletDist * 100 #add score peletScore = (mult * minPeletDist) else: peletScore = 0 #calculate the total score score = foodScore * 60 / 100 + peletScore * 30 / 100 + sign * ghostScore * 30 / 100 return score
def getFurthestCorner(self, pacPos): poses = [(1, 1), (1, self.height - 2), (self.width - 2, 1), (self.width - 2, self.height - 2)] dist, pos = max([(manhattanDistance(p, pacPos), p) for p in poses]) return pos
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition( ) #This tells you the position that pacman will be in newFood = successorGameState.getFood() #What does this do? newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ ghostState.scaredTimer for ghostState in newGhostStates ] newScore = successorGameState.getScore() newGhostPositions = successorGameState.getGhostPositions() print(currentGameState.getNumAgents()) ghostDistanceArray = [] hitghost = 0 for pos in newGhostPositions: distance = util.manhattanDistance(pos, newPos) ghostDistanceArray.append(distance) if distance == 1: hitghost += 1 ghostDistanceMax = min(ghostDistanceArray) if ghostDistanceMax == 0: ghostDistanceMax = 1 foodList = newFood.asList() arrayofFood = [10000000] for food in foodList: foodDistance = util.manhattanDistance(food, newPos) arrayofFood.append(foodDistance) foodMin = min(arrayofFood) if foodMin == 0: foodMin = 1 total = 1 / float(foodMin) - 1 / float( ghostDistanceMax) - hitghost + newScore return total
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" ''' tempParticles = util.Counter() if noisyDistance == None: self.allParticles = [self.getJailPosition()]*self.numParticles else: for particlePosition in self.allParticles: trueDistance = util.manhattanDistance(particlePosition,pacmanPosition) tempParticles[particlePosition] += emissionModel[trueDistance] if tempParticles.values() == [0]*len(tempParticles.values()): self.initializeUniformly(gameState) else: tempParticles.normalize() for i in range(self.numParticles): self.allParticles[i] = util.sample(tempParticles) ''' tempParticles = util.Counter() for j, particle in enumerate(self.allParticles): multiDistribute = 1.0 tempPar = particle for i, dis in enumerate(noisyDistances): if dis == None: tempPar = self.getParticleWithGhostInJail(particle, i) self.allParticles[j] = tempPar else: trueDistance = util.manhattanDistance( particle[i], pacmanPosition) multiDistribute *= emissionModels[i][trueDistance] tempParticles[tempPar] += multiDistribute if (tempParticles.values() == [0] * len(tempParticles.values())): self.initializeParticles() else: tempParticles.normalize() for i in range(self.numParticles): self.allParticles[i] = util.sample(tempParticles)
def canKill(pacmanPosition, ghostPosition): return manhattanDistance(ghostPosition, pacmanPosition) <= COLLISION_TOLERANCE
def noisyDistance(pos1, pos2): return int( util.manhattanDistance(pos1, pos2) + random.choice(SONAR_NOISE_VALUES))
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. ** Remember ** We store particles as tuples, but to edit a specific particle, it must be converted to a list, edited, and then converted back to a tuple. Since this is a common operation when placing a ghost in the jail for a particle, we have provided a helper method named self.getParticleWithGhostInJail(particle, ghostIndex) that performs these three operations for you. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" count = 0 possible = util.Counter() while count < len(self.particles): w = 1 second_count = 0 while second_count < self.numGhosts: if noisyDistances[second_count] is not None: w *= emissionModels[second_count][util.manhattanDistance( self.particles[count][second_count], pacmanPosition)] else: self.particles[count] = self.getParticleWithGhostInJail( self.particles[count], second_count) second_count += 1 possible[self.particles[count]] += w count += 1 if possible.totalCount() != 0: part_list = [] possible.normalize() count = 0 while count < self.numParticles: data = util.sample(possible) part_list.append(data) count += 1 self.particles = part_list else: self.initializeParticles() count = 0 while count < len(self.particles): second_count = 0 while second_count < self.numGhosts: if noisyDistances is None: self.particles[ count] = self.getParticleWithGhostInJail( self.particles[count], second_count) second_count += 1 count += 1
def evaluate(self, gameState, action): width, height = gameState.data.layout.width, gameState.data.layout.height features = { 'nearestFood': 1.0 / min( self.getMazeDistance(gameState.getAgentPosition(self.index), p) for p in self.getFood(gameState).asList()), 'nearestPellet': 100.0 if len(self.getCapsules(gameState)) == 0 else 1.0 / min( self.getMazeDistance(gameState.getAgentPosition(self.index), p) for p in self.getCapsules(gameState)), 'opponent': (1.0 / (10 * self.powerTimer) if self.isPowered() else 1.0) * self.sideEval( gameState, min([ self.inferenceMods[i].getMostLikelyPosition() for i in self.inferenceMods ], key=lambda x: self.getMazeDistance( gameState.getAgentPosition(self.index), x))) * 1.0 / (1 + min([ self.getMazeDistance( gameState.getAgentPosition(self.index), self.inferenceMods[i].getMostLikelyPosition()) for i in self.inferenceMods ])), 'score': gameState.getScore(), 'ally': (1.0 - self.sideEval( gameState, gameState.getAgentPosition( [i for i in self.getTeam(gameState) if i != self.index][0]))) * 1.0 / (1 + self.getMazeDistance( gameState.getAgentPosition([ i for i in self.getTeam(gameState) if i != self.index ][0]), gameState.getAgentPosition(self.index))), 'immediateOpponent': (0.0 if self.isPowered() else 1.0) * self.side(gameState) * (1.0 if 1.0 == util.manhattanDistance( min([ self.inferenceMods[i].getMostLikelyPosition() for i in self.inferenceMods ], key=lambda x: self.getMazeDistance( gameState.getAgentPosition(self.index), x)), gameState.getAgentPosition(self.index)) else 0.0), 'isPowered': 1.0 if self.isPowered() else 0.0, 'isDeadEnd': 1.0 if len(gameState.getLegalActions(self.index)) <= 2 else 0.0, 'holdFood': self.foodNum * (min([ self.distancer.getDistance( gameState.getAgentPosition(self.index), p) for p in [(width / 2, i) for i in range(1, height) if not gameState.hasWall(width / 2, i)] ])) * self.side(gameState), 'dropFood': self.foodNum * (1.0 - self.side(gameState)), 'isStop': 1.0 if action == Directions.STOP else 0.0 } for i in self.inferenceMods: self.inferenceMods[i].step(gameState) return sum([self.weights[i] * features[i] for i in features])
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ ghostState.scaredTimer for ghostState in newGhostStates ] #====Get the closest food to pacman using manhattan distance==== our_food_list = newFood.asList() #Initialize the closest food manhattan distance first_food = True closest_food = 0 #Find the closest food by iterating through the new food list for food in our_food_list: if first_food is True: closest_food = manhattanDistance(food, newPos) first_food = False else: distance_to_food = manhattanDistance(food, newPos) if distance_to_food < closest_food: closest_food = distance_to_food #closest_food now contains the food closest to pacman #====Get the closest ghost to pacman using manhattan distance==== first_ghost = True closest_ghost = 0 #Find the closest ghost by iterating through the new ghost list for ghost in newGhostStates: if first_ghost is True: closest_ghost = manhattanDistance(ghost.getPosition(), newPos) first_ghost = False else: distance_to_ghost = manhattanDistance(ghost.getPosition(), newPos) if distance_to_ghost < closest_ghost: closest_ghost = distance_to_ghost #closest_ghost now contains the food closest to pacman #====Determine the score==== #If the new position of pacman is not in the current state's food list, then we must make the score the #"reciprocal" (negative) of the closest food so far (as recommended) if newPos not in currentGameState.getFood().asList(): score = -closest_food #If it is, just zero it out because we just moved on top of the new food in newPos else: score = 0 #Check if any of the ghosts are scared because pacman has eaten a power pellet not_scared = True for scaredTimes in newScaredTimes: #This means there is at 1 scared ghost if scaredTimes != 0: not_scared = False #If none of the ghosts are scared, they can potentially kill pacman because pacman has not eaten a power pellet if not_scared and closest_ghost <= 1: #If the closest ghost is within 1 of pacman, this state is potentially doomed so return the reciprocal of the #largest possible number on the machine (negative infinity) score = -float("inf") return score
def checkDeath(state, agentIndex): agentState = state.data.agentStates[agentIndex] if state.isOnRedTeam(agentIndex): otherTeam = state.getBlueTeamIndices() else: otherTeam = state.getRedTeamIndices() if agentState.isPacman: for index in otherTeam: otherAgentState = state.data.agentStates[index] if otherAgentState.isPacman: continue ghostPosition = otherAgentState.getPosition() if ghostPosition == None: continue if manhattanDistance( ghostPosition, agentState.getPosition()) <= COLLISION_TOLERANCE: # award points to the other team for killing Pacmen if otherAgentState.scaredTimer <= 0: AgentRules.dumpFoodFromDeath(state, agentState, agentIndex) score = KILL_POINTS if state.isOnRedTeam(agentIndex): score = -score state.data.scoreChange += score agentState.isPacman = False agentState.configuration = agentState.start agentState.scaredTimer = 0 else: score = KILL_POINTS if state.isOnRedTeam(agentIndex): score = -score state.data.scoreChange += score otherAgentState.isPacman = False otherAgentState.configuration = otherAgentState.start otherAgentState.scaredTimer = 0 else: # Agent is a ghost for index in otherTeam: otherAgentState = state.data.agentStates[index] if not otherAgentState.isPacman: continue pacPos = otherAgentState.getPosition() if pacPos == None: continue if manhattanDistance( pacPos, agentState.getPosition()) <= COLLISION_TOLERANCE: #award points to the other team for killing Pacmen if agentState.scaredTimer <= 0: AgentRules.dumpFoodFromDeath(state, otherAgentState, agentIndex) score = KILL_POINTS if not state.isOnRedTeam(agentIndex): score = -score state.data.scoreChange += score otherAgentState.isPacman = False otherAgentState.configuration = otherAgentState.start otherAgentState.scaredTimer = 0 else: score = KILL_POINTS if state.isOnRedTeam(agentIndex): score = -score state.data.scoreChange += score agentState.isPacman = False agentState.configuration = agentState.start agentState.scaredTimer = 0
def getFeatures(self, state, action, agentIndex): if (agentIndex == 2): features = util.Counter() ghostPos1 = state.getGhostPosition(1) ghostPos2 = state.getGhostPosition(2) pacmanPos = state.getPacmanPosition() ghostState2 = state.getGhostState(2) pacmanState = state.getPacmanState() walls = state.getWalls() scaredTimer = ghostState2.scaredTimer dx, dy = Actions.directionToVector(action) if scaredTimer > 0: dx /= 2 dy /= 2 ghost2x = ghostPos2[0]+dx ghost2y = ghostPos2[1]+dy ghostPos2 = (ghost2x, ghost2y) ghostDistance2 = util.manhattanDistance(pacmanPos, ghostPos2) # print(state) # print(self.shortestDistAStar(walls, pacmanPos, ghostPos2)) features["bias"] = 1.0 features["stepsToOtherGhost"] = util.manhattanDistance(ghostPos1, ghostPos2) / (walls.width + walls.height) if scaredTimer > 0: features["stepsFromScaredGhostToPacman"] = ghostDistance2 / (walls.width + walls.height) else: # minDistanceToCapsule = 999999999 # closestCapsuleLoc = [] # for capsuleLoc in state.getCapsules(): # distance = util.manhattanDistance(pacmanPos, capsuleLoc) # if(distance < minDistanceToCapsule): # closestCapsuleLoc = capsuleLoc # minDistanceToCapsule = distance # features["minDistanceBetweenGhostPacman"] = (11 - minDistanceToCapsule) / (walls.width + walls.height) min_dist = ghostDistance2 features["stepsFromGhostToPacman"] = min_dist / (walls.width + walls.height) features["danger"] = 0 if (len(state.getCapsules()) > 0 and ghostDistance2 > 0): closestCapsuleLoc = [] distances = [] for capsuleLoc in state.getCapsules(): distance = util.manhattanDistance(pacmanPos, capsuleLoc) distances.append(distance) distances.sort() minDistanceOfPacmanToCapsule = distances[0] if (minDistanceOfPacmanToCapsule > 0): if min_dist < 11: features["danger"] = 1 - min_dist/11 if min_dist > 12 : features["keepwithinrange"] = 1.0 else: features["keepwithinrange"] = 0 if ((features["danger"] == 0) and (min_dist <= 12)): features["trap"] = 1 - min_dist/99 else: features["trap"] = 0 return features else: features = util.Counter() ghostPos1 = state.getGhostPosition(2) ghostPos2 = state.getGhostPosition(1) pacmanPos = state.getPacmanPosition() ghostState2 = state.getGhostState(2) pacmanState = state.getPacmanState() walls = state.getWalls() scaredTimer = ghostState2.scaredTimer dx, dy = Actions.directionToVector(action) if scaredTimer > 0: dx /= 2 dy /= 2 ghost2x = ghostPos2[0]+dx ghost2y = ghostPos2[1]+dy ghostPos2 = (ghost2x, ghost2y) ghostDistance2 = util.manhattanDistance(pacmanPos, ghostPos2) # print(state) # print(self.shortestDistAStar(walls, pacmanPos, ghostPos2)) features["bias"] = 1.0 features["stepsToOtherGhost"] = util.manhattanDistance(ghostPos1, ghostPos2) / (walls.width + walls.height) if scaredTimer > 0: features["stepsFromScaredGhostToPacman"] = ghostDistance2 / (walls.width + walls.height) else: # minDistanceToCapsule = 999999999 # closestCapsuleLoc = [] # for capsuleLoc in state.getCapsules(): # distance = util.manhattanDistance(pacmanPos, capsuleLoc) # if(distance < minDistanceToCapsule): # closestCapsuleLoc = capsuleLoc # minDistanceToCapsule = distance # features["minDistanceBetweenGhostPacman"] = (11 - minDistanceToCapsule) / (walls.width + walls.height) min_dist = ghostDistance2 features["stepsFromGhostToPacman"] = min_dist / (walls.width + walls.height) features["danger"] = 0 if (len(state.getCapsules()) > 0 and ghostDistance2 > 0): closestCapsuleLoc = [] distances = [] for capsuleLoc in state.getCapsules(): distance = util.manhattanDistance(pacmanPos, capsuleLoc) distances.append(distance) distances.sort() minDistanceOfPacmanToCapsule = distances[0] if (minDistanceOfPacmanToCapsule > 0): if min_dist < 11: features["danger"] = 1 - min_dist/11 if min_dist > 12 : features["keepwithinrange"] = 1.0 else: features["keepwithinrange"] = 0 if ((features["danger"] == 0) and (min_dist <= 12)): features["trap"] = 1 - min_dist/99 else: features["trap"] = 0 return features
def enhancedPacmanFeatures(state, action): """ For each state, this function is called with each legal action. It should return a counter with { <feature name> : <feature value>, ... } python dataClassifier.py -c perceptron -d pacman -f -g ContestAgent #sets 1 for the position of pacman and 0 otherwise for x in range(20): for y in range(20): if (x,y) == state.getPacmanPosition(): features[(x,y)] = 1 else: features[(x,y)] = 0 """ features = util.Counter() successor = state.generateSuccessor(0, action) agent_pos = successor.getPacmanPosition() ghosts = successor.getGhostPositions() ghost_state = successor.getGhostStates() capsules = successor.getCapsules() state_food = state.getFood() food = [(x, y) for x, row in enumerate(state_food) for y, food in enumerate(row) if food] nearest_ghosts = sorted( [util.manhattanDistance(agent_pos, i) for i in ghosts]) features["nearest_ghost"] = nearest_ghosts[0] #print(ghost_state) #if state.data.agentStates[nearest_ghosts[0]].scaredTimer > 0: # features[("ghost_scared", ghost_state)] = 1 #else: features[("ghost_scared", ghost_state)] = 0 #for i in xrange(min(len(nearest_ghosts), 1)): #features[("ghost", i)] = 5 / (0.1 + nearest_ghosts[i]) nearest_caps = sorted( [util.manhattanDistance(agent_pos, i) for i in capsules]) for i in xrange(min(len(nearest_caps), 1)): features[("capsule", i)] = 15 / (1 + nearest_caps[i]) nearest_food = sorted([util.manhattanDistance(agent_pos, i) for i in food]) for i, weight in zip(xrange(min(len(nearest_food), 5)), [1.3, 0.8] + [0.9] * 3): features[("food", i)] = weight * nearest_food[i] #features["capsule count"] = len(capsules) * 10 features["iswin"] = state.isWin() features["islose"] = state.isLose() features["score"] = state.getScore() #* 10 #features["pacman"]= agent_pos implemnteren werkt niet! return features
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. As in elapseTime, to loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. Remember to change ghosts' positions to jail if called for. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] "*** YOUR CODE HERE ***" ## make sure yo ghosts in jail bro for i in range(self.numGhosts): if noisyDistances[i] == None: for j in range(self.numParticles): thisGhostParticle = list(self.particles[j]) thisGhostParticle[i] = self.getJailPosition(i) self.particles[j] = tuple(thisGhostParticle) ## check yo weights bro updatedWeights = util.Counter() for i in range(self.numParticles): # 1.0 not 1 haha I love ints and never make that mistake currentWeight = 1.0 thisParticle = list(self.particles[i]) for j in range(self.numGhosts): # if they are in jail if (noisyDistances[j] != None): manDist = util.manhattanDistance(thisParticle[j], pacmanPosition) currentWeight *= emissionModels[j][manDist] # new weights bro! getting nice and strong I love it updatedWeights[tuple(thisParticle)] += currentWeight zeroParticleCheck = True for i in range(self.numParticles): thisParticle = self.particles[i] # if this one isnt zero, how can all of them be zero? if (updatedWeights[thisParticle] > 0): zeroParticleCheck = False break # if they all zero take a step back and restart if zeroParticleCheck: self.initializeParticles() # otherwise keep chuggin else: for i in range(self.numParticles): self.particles[i] = util.sampleFromCounter(updatedWeights)
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: As recommended, a linear combination of crucial pacman states was taken in order to determine our final score. Based on what was learned in question 1, I found the closest food, and closest ghosts to pacman to determine score. If the game is over, return a corresponding infinity depending on what ended the game. Number of food was given a weighting of 70 by default. We also add the closest food to the score. For the closest ghost, since it is very significant, we will multiply it by itself. We do this to quickly amplify the danger of a close ghost. If a ghost is within two of pacman, we need to eat a power pellet ASAP to kill it so we give a weighting of 50 when a ghost is near, else just a weight of 10. Finally, we return the negative reciprocal as we did in question 1. Note: we subtract the current score because it is score that has already been counted in previous turns. """ #First, check if the game is over by win or loss. If so, return the appropriate infinity #Negative infinity for an instant lose state # First, check if the game is over by win or loss. If so, return the appropriate infinity # Negative infinity for an instant lose state if currentGameState.isLose(): return -float("inf") # Positive infinity for a instant win state elif currentGameState.isWin(): return float("inf") # Based on question 1 # Current pacman position pacman_pos = currentGameState.getPacmanPosition() # Current food list food_list = currentGameState.getFood() # Current ghost states ghost_states = currentGameState.getGhostStates() # Current scared times scared_times = [ghostState.scaredTimer for ghostState in ghost_states] #Our final score final_score = 0 our_food_list = food_list.asList() # Initialize the closest food manhattan distance first_food = True closest_food = 0 # Find the closest food by iterating through the new food list for food in our_food_list: if first_food is True: closest_food = manhattanDistance(food, pacman_pos) first_food = False else: distance_to_food = manhattanDistance(food, pacman_pos) if distance_to_food < closest_food: closest_food = distance_to_food # closest_food now contains the food closest to pacman # ====Get the closest ghost to pacman using manhattan distance==== first_ghost = True closest_ghost = 0 # Find the closest ghost by iterating through the new ghost list for ghost in ghost_states: if first_ghost is True: closest_ghost = manhattanDistance(ghost.getPosition(), pacman_pos) first_ghost = False else: distance_to_ghost = manhattanDistance(ghost.getPosition(), pacman_pos) if distance_to_ghost < closest_ghost: closest_ghost = distance_to_ghost # Check if any of the ghosts are scared because pacman has eaten a power pellet not_scared = True for scaredTimes in scared_times: # This means there is at 1 scared ghost if scaredTimes != 0: not_scared = False # If none of the ghosts are scared, they can potentially kill pacman because pacman has not eaten a power pellet # If there is a scared ghost within 2 of pacman, we need to eat a power pellet ASAP if not_scared and closest_ghost <= 2: # If the closest ghost is within 1 of pacman, this state is potentially doomed so return the reciprocal of the # largest possible number on the machine (negative infinity) # Add the number of power pellets according to a custom weight power_pellet_weight = 50 # If not, not much weight should be put on power pellets else: # Add the number of power pellets according to a custom weight power_pellet_weight = 10 #Linear combination of all our values final_score += closest_food + \ closest_ghost ** 2 + \ 70 * currentGameState.getNumFood() + \ power_pellet_weight * len(currentGameState.getCapsules()) - \ currentGameState.getScore() # Return the negative reciprocol of the linear combination of all of our score determiners like in question 1 return -final_score
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) Pos = currentGameState.getPacmanPosition() successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ ghostState.scaredTimer for ghostState in newGhostStates ] walls = successorGameState.getWalls() m, n = walls.height, walls.width "*** YOUR CODE HERE ***" foodList = currentGameState.getFood().asList() alpha = (m - 2) * (n - 2) value = 0.0 if (action == 'Stop'): value -= 1.1 nearestFood = (-1, -1) foodDis = m * n for food in foodList: tmpdis = manhattanDistance(Pos, food) if (tmpdis < foodDis or nearestFood == (-1, -1)): foodDis = tmpdis nearestFood = food #print "nearest food: ", nearestFood #if nearestFood != (-1,-1): dis = manhattanDistance(newPos, nearestFood) #print "next distance: ", dis for ghost in newGhostStates: ghostDis = manhattanDistance(newPos, ghost.getPosition()) scared = ghost.scaredTimer if scared == 0: if ghostDis <= 3: value += -(4 - ghostDis)**2 else: if currentGameState.hasFood(newPos[0], newPos[1]): value += 1.5 else: value += scared / (ghostDis + 1) value = value - dis #print"value", value return value
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] beliefs = self.getBeliefDistribution() possibles = [] ghostInJail = [] ghostJailPositions = [] for i in range(self.numGhosts): allPossible = util.Counter() if noisyDistances[i] is None: jailPos = self.getJailPosition(i) allPossible[jailPos] = 1.0 ghostInJail.append(True) ghostJailPositions.append(jailPos) else: ghostInJail.append(False) #P(x_t|e_1:t) = P(e_t|x_t) * sum_x_t-1 (P(x_t|x_t-1) * P(x_t-1,e_t:t-1)) for p in self.legalPositions: trueDistance = util.manhattanDistance(p, pacmanPosition) cond_prob_ev_t = emissionModels[i][ trueDistance] #p(e_t|x_t) # assume ghost is standing still? allPossible[p] = cond_prob_ev_t * self.computeMarginal( beliefs, i, p) allPossible.normalize() possibles.append(allPossible) # First handle the case where all particles get zero weight currentPositions = list( set(self.legalPositions).union(ghostJailPositions)) permutations = list( itertools.product(currentPositions, repeat=self.numGhosts)) #probs = [self.computeJoint(p, possibles) for p in permutations] #print "probs = ", probs nonZero = [ p for p in permutations if self.computeJoint(p, possibles) > 0.0 ] if len(nonZero) == 0: print "Ru roh, need to re-initialize." #print "Marginals=", possibles self.initializeParticles() # Now we need to update the marginals of any ghosts that are in jail. for i in range(self.numGhosts): if ghostInJail[i]: print "ghost ", i, " is in jail - adjusting." probs = [(p, self.computeJoint(p, possibles)) for p in permutations] print "Marginal=", possibles print "Joint=", probs for j in range(self.numParticles): self.particles[j] = self.getParticleWithGhostInJail( self.particles[j], i) else: weights = [self.computeJoint(p, possibles) for p in permutations] positions = [p for p in permutations] self.particles = util.nSample(weights, positions, self.numParticles)
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where `i` is the index of the ghost. As before, you can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None. 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of None) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. self.getParticleWithGhostInJail is a helper method to edit a specific particle. Since we store particles as tuples, they must be converted to a list, edited, and then converted back to a tuple. This is a common operation when placing a ghost in jail. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] currentBeliefs = util.Counter() #temp list of beliefs (weights) "*** YOUR CODE HERE ***" #Local Declarations count = 0 count2 = 0 count3 = 0 finalTemp = 1.0 sad = 0 total = 0 #loop through particles while (count < len(self.particleList)): temp = 1.0 particle = self.particleList[count] #get particle #loop to go through for i in range(self.numGhosts): emissionModel = emissionModels[i] #emission array noisyDistance = noisyDistances[i] #noisy array #if not noisy then compute the weights, also called "currentBeliefs" if not (noisyDistance == None): trueDistance = util.manhattanDistance( particle[i], pacmanPosition) temp *= emissionModel[trueDistance] currentBeliefs[ particle] += temp #update currentBeliefs with the weights total += temp count += 1 #increment loop #if sum of weights == 0 then handle case two, where weights could be 0 if (total == 0): self.handleCaseTwoJP(currentBeliefs, gameState, noisyDistances) else: #loop through particles and resample them count = 0 while (count < len(self.particleList)): self.particleList[count] = util.sample( currentBeliefs ) #set particle to jail position and return it count += 1 #increment loop #go through each ghosts in range, check for noisyDistance truth, then place jail position into particles for i in range(self.numGhosts): if (noisyDistances[i] == None): count = 0 #loop through the particle list and update the particle with ghosts in their jail position(s) while (count < len(self.particleList)): self.particleList[count] = self.getParticleWithGhostInJail( self.particleList[count], i) #set particle to jail position and return it count += 1 #increment loop
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() currentCapsules = currentGameState.getCapsules() newCapsules = successorGameState.getCapsules() newCapsuleDists = [manhattanDistance(capsule, newPos) for capsule in newCapsules] newFoodDists = [manhattanDistance(food, newPos) for food in newFood.asList()] currentGhostStates = currentGameState.getGhostStates() newGhostStates = successorGameState.getGhostStates() newGhostDists = [manhattanDistance(ghostState.getPosition(), newPos) for ghostState in newGhostStates] newScaredTimes = [ghostState.scaredTimer for ghostState in newGhostStates] "*** YOUR CODE HERE ***" # find the closest ghost closestGhost = min(newGhostDists) # if we've eaten a power pellet go after it if newScaredTimes[0] != 0: if closestGhost != 0: ghostTerm = 1./closestGhost else: ghostTerm = 1./0.0001 # otherwise don't worry about it unless it's within # 4 steps of us, then take evasive action else: ghostTerm = min(4, closestGhost) # try to go after power pellets # add in a big bonuse for eating one if len(currentCapsules) > len(newCapsules): capsuleTerm = 50 elif len(newCapsuleDists): closestCapsule = min(newCapsuleDists) if closestCapsule > 1: capsuleTerm = 1./closestCapsule else: capsuleTerm = 20 else: capsuleTerm = 20 # try to get closer to food if len(newFoodDists): foodTerm = 1./(sum(newFoodDists)/len(newFoodDists)) else: foodTerm = 0 return 1.5*successorGameState.getScore() + ghostTerm + foodTerm + capsuleTerm
def cornersHeuristic(state, problem): """ Q2.2 A heuristic for the CornersProblem that you defined. state: The current search state (a data structure you chose in your search problem) problem: The CornersProblem instance for this layout. This function should always return a number that is a lower bound on the shortest path from the state to a goal of the problem; i.e. it should be admissible (as well as consistent). """ corners = problem.corners # These are the corner coordinates walls = problem.walls # These are the walls of the maze, as a Grid (game.py) "*** YOUR CODE HERE ***" startPos = state[0] cornersState = state[1] top, right = walls.height - 2, walls.width - 2 # top and right bounds - storing these values to speed up runtime exploredCorner = [] # print ("corners[0]: ", corners[0]) # print ("corners[1]: ", corners[1]) # print ("corners[2]: ", corners[2]) # print ("corners[3]: ", corners[3]) # go through each item in corners to ensure if False, that it's appended to exploredCorner for use in manhattan distance heuristic for item in corners: print("items: ", item) if item == (right, 1): if cornersState[0] == False: exploredCorner.append(item) elif item == (right, top): if cornersState[1] == False: exploredCorner.append(item) elif item == (1, top): if cornersState[2] == False: exploredCorner.append(item) elif item == (1, 1): if cornersState[3] == False: exploredCorner.append(item) # Keep a list of Unvisited Corners - exploredCorner # Return the Manhattan distance of corner that's # closest to you by doing a min() over all the Manhattan distances. totalCost = 0 currPosition = startPos # check while exploredCorner still had corners to calculate manhattan distance to while len(exploredCorner) > 0: manDistArr = [ ] # list to keep track of manhattan distance from currPosition to corner i = 0 for items in range(len(exploredCorner)): corner = exploredCorner[items] i += 1 manDistance = util.manhattanDistance(currPosition, corner) manDistArr.append(manDistance) minManDistance = min( manDistArr ) # taking the min of manhattan distance list to find closest corner to currPosition totalCost += minManDistance # grab index of minimum in manhattan distance array so that we can # remove the corner that corresponds to that distance from our list # of explored corners from above minManDistancePos = manDistArr.index(minManDistance) currPosition = exploredCorner[minManDistancePos] del exploredCorner[ minManDistancePos] # remove the corner from array in order to ensure that while loop ends return totalCost
def foodHeuristic(state, problem): """ Your heuristic for the FoodSearchProblem goes here. This heuristic must be consistent to ensure correctness. First, try to come up with an admissible heuristic; almost all admissible heuristics will be consistent as well. If using A* ever finds a solution that is worse uniform cost search finds, your heuristic is *not* consistent, and probably not admissible! On the other hand, inadmissible or inconsistent heuristics may find optimal solutions, so be careful. The state is a tuple ( pacmanPosition, foodGrid ) where foodGrid is a Grid (see game.py) of either True or False. You can call foodGrid.asList() to get a list of food coordinates instead. If you want access to info like walls, capsules, etc., you can query the problem. For example, problem.walls gives you a Grid of where the walls are. If you want to *store* information to be reused in other calls to the heuristic, there is a dictionary called problem.heuristicInfo that you can use. For example, if you only want to count the walls once and store that value, try: problem.heuristicInfo['wallCount'] = problem.walls.count() Subsequent calls to this heuristic can access problem.heuristicInfo['wallCount'] """ position, foodGrid = state "*** YOUR CODE HERE ***" if (problem.isGoalState(state)): return 0 verticesINMST = set() verticesNOTMST = set() for i, item in enumerate(foodGrid): for j, foodItem in enumerate(item): if (foodItem): verticesNOTMST.add((i, j)) closest_dist = min( [util.manhattanDistance(position, item) for item in verticesNOTMST]) # verticesNOTMST.add(position) edges = util.PriorityQueue() cost = 0 # edges.push((verticesNOTMST[i], verticesNOTMST[j]), util.manhattanDistance(verticesNOTMST[i], verticesNOTMST[j])) poppedEdge = None inV, outV = 0, 0 spanCost = closest_dist spanEdges = [] currentVert = verticesNOTMST.pop() verticesINMST.add(currentVert) while len(verticesNOTMST) != 0: for vert in verticesNOTMST: cost = util.manhattanDistance(currentVert, vert) edges.push(((currentVert, vert), cost), cost) while (True): poppedEdge, cost = edges.pop() if (poppedEdge[1] in verticesNOTMST): inV, outV = poppedEdge break spanCost += cost verticesNOTMST.remove(outV) verticesINMST.add(outV) spanEdges.append((poppedEdge, cost)) currentVert = outV # print "pos:", position, " h:", spanCost return spanCost
def evaluationFunction(self, currentGameState, action): """ Design a better evaluation function here. The evaluation function takes in the current and proposed successor GameStates (pacman.py) and returns a number, where higher numbers are better. The code below extracts some useful information from the state, like the remaining food (newFood) and Pacman position after moving (newPos). newScaredTimes holds the number of moves that each ghost will remain scared because of Pacman having eaten a power pellet. Print out these variables to see what you're getting, then combine them to create a masterful evaluation function. """ # Useful information you can extract from a GameState (pacman.py) successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ ghostState.scaredTimer for ghostState in newGhostStates ] "*** YOUR CODE HERE ***" #Local Declarations newWalls = successorGameState.getWalls() # foodList = list() foodDist = 0.0 foodCoord = (0, 0) ghostPositions = successorGameState.getGhostPositions() ghostDist = 0.0 ghostCoord = (0, 0) dom = 0 rng = 0 resultScore = 0 targetDistance = 0 oldDistance = 999999 #Game win/lose evaluation if (successorGameState.isLose()): return -999999 if (successorGameState.isWin()): return 999999 first = False foodCount = 0 for i in range(0, newFood.width): for j in range(0, newFood.height): if newFood[i][j]: foodCount += 1 #loop through food list to find lowest min value (closest to food by pacman) for i in range(0, newFood.width): for j in range(0, newFood.height): if not (newWalls[i][j]): if not first: temp1 = util.manhattanDistance(newPos, (i, j)) # print ("Food_Man_Dist: ", temp1) if temp1 == 1: first = True foodDist -= 1000000 #foodDist += util.manhattanDistance(newPos, (i, j)) if util.manhattanDistance(newPos, (i, j)) <= 100: foodDist += 1000000 - util.manhattanDistance( newPos, (i, j)) * 10000 if newFood[i][j]: #update to smallest variable if true if (foodDist < oldDistance): oldDistance = foodDist foodDist = 0 foodDist = oldDistance # print "FoodDist: ", foodDist for i in range(0, len(ghostPositions)): temp2 = util.manhattanDistance(newPos, ghostPositions[i]) if (temp2 <= 1): ghostDist -= 999999 if (temp2 > 1 and temp2 < 8): ghostDist -= temp2 + 10000 ghostDist -= temp2 + 100 #update to smallest variable if true if (ghostDist <= oldDistance): oldDistance = ghostDist ghostDist = 0 ghostDist = oldDistance resultScore += (ghostDist / foodDist) + successorGameState.getScore() return resultScore
def observeState(self, gameState): """ Resamples the set of particles using the likelihood of the noisy observations. To loop over the ghosts, use: for i in range(self.numGhosts): ... A correct implementation will handle two special cases: 1) When a ghost is captured by Pacman, all particles should be updated so that the ghost appears in its prison cell, position self.getJailPosition(i) where "i" is the index of the ghost. You can check if a ghost has been captured by Pacman by checking if it has a noisyDistance of None (a noisy distance of None will be returned if, and only if, the ghost is captured). 2) When all particles receive 0 weight, they should be recreated from the prior distribution by calling initializeParticles. After all particles are generated randomly, any ghosts that are eaten (have noisyDistance of 0) must be changed to the jail Position. This will involve changing each particle if a ghost has been eaten. ** Remember ** We store particles as tuples, but to edit a specific particle, it must be converted to a list, edited, and then converted back to a tuple. Since this is a common operation when placing a ghost in the jail for a particle, we have provided a helper method named self.getParticleWithGhostInJail(particle, ghostIndex) that performs these three operations for you. """ pacmanPosition = gameState.getPacmanPosition() noisyDistances = gameState.getNoisyGhostDistances() if len(noisyDistances) < self.numGhosts: return emissionModels = [ busters.getObservationDistribution(dist) for dist in noisyDistances ] # find the indices of ghosts in jail injail = [] for i in range(self.numGhosts): if noisyDistances[i] == None: injail.append(i) tempCounter = util.Counter() #weight every particle for p in self.particles: #weight a specific particle # fix the particle to put the ghosts in jail for ghostIndex in injail: x = list(p) x[ghostIndex] = self.getJailPosition(ghostIndex) p = tuple(x) #create a probability variable for this particle prob = 1 # check the truedistance of a particle ghost with its respective # emission model for i in range(self.numGhosts): # we know that our ghost is in jail, so there's no probability factor if i not in injail: trueDistance = util.manhattanDistance(p[i], pacmanPosition) prob = prob * emissionModels[i][trueDistance] # add this probability to the overall particle table tempCounter[p] += prob # assign beliefs to this counter self.beliefs = tempCounter # resample if tempCounter.totalCount() == 0: self.initializeParticles() else: self.beliefs.normalize() for i in range(len(self.particles)): newPos = util.sample(self.beliefs) self.particles[i] = newPos
def uctSimulation(self): # simulate the moves from the current game state # and updates self.plays and self.wins stateCopy = self.states[:] state = stateCopy[-1] statesPath = [state] # get the ghost and invaders the agent can see at the current game state enemies = [state.getAgentState(i) for i in self.enemies if state.getAgentState(i).scaredTimer < 6] ghosts = [enemy for enemy in enemies if enemy.getPosition() and not enemy.isPacman] invaders = [enemy for enemy in enemies if enemy.isPacman] c, d = state.getAgentState(self.index).getPosition() currentScore = state.getScore() expand = True for i in xrange(1, self.maxMoves + 1): state = stateCopy[-1] # make i evaluates lazily actions = state.getLegalActions(self.index) actions.remove(Directions.STOP) # Bail out early if there is no real choice to be made. if not actions: return moveStates = [(action, state.generateSuccessor(self.index, action)) for action in actions] # check if all the results in the actions are in the plays dictionary # if they are, use UBT1 to make choice if all(self.plays.get(S.getAgentState(self.index).getPosition()) for a, S in moveStates): # the number of times state has been visited. if self.plays[state.getAgentState(self.index).getPosition()] == 0.0: logTotal = 0.5 else: logTotal = float( 2.0 * log(self.plays[state.getAgentState(self.index).getPosition()])) value, move, nstate = max( ((float(self.wins[S.getAgentState(self.index).getPosition()]) / float( self.plays[S.getAgentState(self.index).getPosition()])) + 2 * self.C * sqrt( logTotal / float(self.plays[S.getAgentState(self.index).getPosition()])), a, S) for a, S in moveStates ) else: # if not, make a random choice move, nstate = choice(moveStates) stateCopy.append(nstate) statesPath.append(nstate) if expand and nstate.getAgentState(self.index).getPosition() not in self.plays: # expand the tree expand = False self.plays[nstate.getAgentState(self.index).getPosition()] = 0.0 self.wins[nstate.getAgentState(self.index).getPosition()] = 0.0 ''' if len(invaders) != 0: # if see a invader and ate it, win +1 ate = False for a in invaders: if nstate.getAgentState(self.index).getPosition() == a.getPosition(): ate = True break if ate: # record number of wins for s in statesPath: if s.getAgentState(self.index).getPosition() not in self.plays: continue self.wins[s.getAgentState(self.index).getPosition()] += 1.0 # print self.index, "EAT GHOST +1" break ''' x, y = nstate.getAgentState(self.index).getPosition() if len(ghosts) > 0: currentDistanceToGhost, a = min([(self.getMazeDistance((c, d), g.getPosition()), g) for g in ghosts]) if util.manhattanDistance((c, d), a.getPosition()) < 6: nextDistanceToGhost = min((self.getMazeDistance((x, y), g.getPosition()) for g in ghosts)) if nextDistanceToGhost < currentDistanceToGhost: break if nextDistanceToGhost - currentDistanceToGhost > 3 and abs(nstate.getScore() - currentScore) > 0: # record number of wins for s in statesPath: if s.getAgentState(self.index).getPosition() not in self.plays: continue self.wins[s.getAgentState(self.index).getPosition()] += 1.0 break if nextDistanceToGhost - currentDistanceToGhost > 4: # record number of wins for s in statesPath: if s.getAgentState(self.index).getPosition() not in self.plays: continue self.wins[s.getAgentState(self.index).getPosition()] += 0.7 break if len(self.capsule) != 0: distanceToCapsule, cap = min([(self.getMazeDistance((x, y), cap), cap) for cap in self.capsule]) if nstate.getAgentState(self.index).getPosition() == cap: # record number of wins for s in statesPath: if s.getAgentState(self.index).getPosition() not in self.plays: continue self.wins[s.getAgentState(self.index).getPosition()] += 0.002 break if abs(nstate.getScore() - currentScore) > 3: # record number of wins for s in statesPath: if s.getAgentState(self.index).getPosition() not in self.plays: continue self.wins[s.getAgentState(self.index).getPosition()] += 0.4 break for s in statesPath: # record number of plays if s.getAgentState(self.index).getPosition() not in self.plays: continue self.plays[s.getAgentState(self.index).getPosition()] += 1.0
def positionLogicPlan(problem): """ Given an instance of a PositionSearchProblem, return a list of actions that lead to the goal. Available actions are game.Directions.{NORTH,SOUTH,EAST,WEST} Note that STOP is not an available action. """ "*** YOUR CODE HERE ***" startState = problem.getStartState() goalState = problem.getGoalState() Directions = ['North', 'South', 'East', 'West'] width = problem.getWidth() height = problem.getHeight() allStates = [] for x in xrange(width + 1): for y in xrange(height + 1): if not problem.isWall((x, y)): allStates.append((x, y)) for count in xrange(util.manhattanDistance(startState, goalState), 51): cnfList = [] for time in xrange(count + 1): for state in allStates: actions = problem.actions(state) for action in actions: nextState = problem.result(state, action)[0] # state + action > new state expr_and = logic.PropSymbolExpr( 'P', state[0], state[1], time) & logic.PropSymbolExpr( action, time) expression = expr_and >> logic.PropSymbolExpr( 'P', nextState[0], nextState[1], time + 1) cnfList.append(logic.to_cnf(expression)) # not in two places at once for time in xrange(count + 1): cnfList.append( exactlyOne([ logic.PropSymbolExpr('P', state[0], state[1], time) for state in allStates ])) # must make one move each turn for time in xrange(count): cnfList.append( exactlyOne([ logic.PropSymbolExpr(action, time) for action in Directions ])) # no going back on path for state in allStates: cnfList.append( atMostOne([ logic.PropSymbolExpr('P', state[0], state[1], time) for time in xrange(count + 1) ])) # start at startState cnfList.append( logic.PropSymbolExpr('P', startState[0], startState[1], 0)) # goal state cnfList.append( logic.PropSymbolExpr('P', goalState[0], goalState[1], count)) # no illegal moves for state in allStates: for action in list(set(Directions) - set(problem.actions(state))): for time in xrange(count + 1): # state > not action cnfList.append( logic.to_cnf( logic.PropSymbolExpr('P', state[0], state[1], time) >> ~logic.PropSymbolExpr(action, time))) model = logic.pycoSAT(cnfList) if model: path = extractActionSequence(model, Directions) return path
def getNoisyDistance(pos1, pos2): if pos2[1] == 1: return None distance = util.manhattanDistance(pos1, pos2) # return max(0, distance + util.sample(SONAR_NOISE_PROBS, SONAR_NOISE_VALUES)) return distance
def betterEvaluationFunction(currentGameState): """ Your extreme ghost-hunting, pellet-nabbing, food-gobbling, unstoppable evaluation function (question 5). DESCRIPTION: For all successors of the given state: PacMan scans the field for food while evaluating how far the ghost is from it. It places heavy emphasis on food that is near it, and heavy emphasis when the ghost is near the agent. The distance modifier of the ghost is then divided by the food distance to influence pacman's state choice. return average result per successor state. The dist to the ghost becomes irrelevant if the ghost is scared so any choice is good. We also want to avoid stopping in the direction needlessly and try urge pacman to try a different path. """ "*** YOUR CODE HERE ***" #Local Declarations actionList = currentGameState.getLegalActions(0) resultList = list() count = 0 avgResult = 0.0 #Game win/lose evaluation if (currentGameState.isLose()): return -9999999 if (currentGameState.isWin()): return 9999999 for action in actionList: count = count + 1 successorGameState = currentGameState.generatePacmanSuccessor(action) newPos = successorGameState.getPacmanPosition() newFood = successorGameState.getFood() newGhostStates = successorGameState.getGhostStates() newScaredTimes = [ ghostState.scaredTimer for ghostState in newGhostStates ] newWalls = successorGameState.getWalls() foodDist = 0.0 ghostPositions = successorGameState.getGhostPositions() ghostDist = 0.0 dom = 0 rng = 0 resultScore = 0 oldDistance = 9999999 oldFoodDist = 9999999 first = False foodCount = 0 #Get food left on the grid? for i in range(0, newFood.width): for j in range(0, newFood.height): if newFood[i][j]: foodCount = foodCount + 1 #loop through food list to find lowest min value (closest to food by pacman) for i in range(0, newFood.width): for j in range(0, newFood.height): #check if wall is there or not if not (newWalls[i][j]): if not first: foodDistTemp = util.manhattanDistance(newPos, (i, j)) if foodDistTemp <= 1: first = True foodDist += 1000 if util.manhattanDistance(newPos, (i, j)) <= 100: foodDist += 1000 - util.manhattanDistance( newPos, (i, j)) * 10 if newFood[i][j]: #update to smallest variable if true (closest to food) if (foodDist < oldDistance): oldDistance = foodDist foodDist = oldDistance #Get ghost position and evaluate the distance from ghost for i in range(0, len(ghostPositions)): ghostDistTemp = util.manhattanDistance(newPos, ghostPositions[i]) #different positions evaluate to different output choices for pacman if (ghostDistTemp <= 1): ghostDist -= 1000 elif (ghostDistTemp > 1 and ghostDistTemp < 9): ghostDist -= ghostDistTemp + 10 else: ghostDist = ghostDist * 2.25 ghostDist -= ghostDistTemp #update to smallest variable if true if (ghostDist <= oldDistance): oldDistance = ghostDist ghostDist = abs(oldDistance) #consider Stop condition, bad if pacman stops, must keep moving! if action == Directions.STOP: foodDist = foodDist + 1 ghostDist = ghostDist + 2 #consider scared condition if newScaredTimes < 5: ghostDist = 1 else: ghostDist = ghostDist + 2 #get the result score and append it to the list resultScore += (ghostDist / foodDist) + successorGameState.getScore() resultList.append(resultScore) #avg the results and return the value if len(resultList) != 0: avgResult = sum(resultList) / len(resultList) return avgResult util.raiseNotDefined()
def manhattan_priority(sequence): end_node = sequence[-1] state, cost = end_node[0], end_node[2] f = cost + util.manhattanDistance(state, problem.goal)
def heuristic(p1, p2): # 曼哈顿距离 return util.manhattanDistance(p1, p2)