def _observerAgent(self, pos, ndist, agenState): # if the agent is visible return the position directly conf = agenState.configuration if conf is not None: return {conf.pos: 1} # obtain all possible positions with the given distance vp = self._validPos ps = [p for p in vp if manhattanDistance(pos, p) == ndist] # test each point if it is in the noisy distance to the points above freq = {p: [manhattanDistance(p, ip) < 7 for ip in ps] for p in vp} # count the valid points to each possible position then obtain each of # the probabilities sl = len(ps) s = [1 / v / sl for v in reduce(_sum_list, freq.values())] # sum up the probabilities return { k: sum(iv * si for iv, si in zip(v, s)) for k, v in freq.items() # ignore position with probability of 0 if any(v) }
def Heuristic(self,loc,destination): """ Use Manhattan distance to calculate the heuristic distance. """ from util import manhattanDistance dist = manhattanDistance(loc,destination) return dist
def _chase(self, gameState, target): target = tuple(map(int, target)) agent = gameState.data.agentStates[self.index] x, y = pos = tuple(map(int, agent.configuration.pos)) distancer = self.distancer dist = distancer.getDistance(pos, target) cp = self._chasepath # determine if needs to recompute if cp is not None: movement = manhattanDistance(cp[0], target) # insert the target into the last if movement == 1: cp = [target] + cp # only follow the original route if the target didn't change if movement <= 1: if len(cp) <= dist: nx, ny = cp.pop() self._chasepath = cp if cp else None return Actions.vectorToDirection((nx - x, ny - y)) # reset path self._chasepath = None walls = self._walls # A* to chase path = [] q = [(dist, dist, 0, pos, path)] visited = set() while q: _, _, g, pos, path = heappop(q) if pos == target: break visited.add(pos) x, y = pos for dx, dy in self._dirs: npos = nx, ny = x + dx, y + dy if not walls[nx][ny] and npos not in visited: h = distancer.getDistance(pos, target) ng = g + 1 heappush(q, (ng + h, h, ng, npos, path + [npos])) if not path: # TODO: change behaviour return Directions.STOP path.reverse() x, y = agent.configuration.pos nx, ny = path.pop() self._chasepath = path if path else None return Actions.vectorToDirection((nx - x, ny - y))
def _updateDistribution(self, gameState): agentDistances = gameState.agentDistances data = gameState.data layout = data.layout wall = layout.walls.data agentStates = data.agentStates vp = self._validPos dist = {} pos = agentStates[self.index].configuration.pos for agent, adist in self._distribution.items(): agentState = agentStates[agent] conf = agentState.configuration # if the agent is visible if conf is not None: dist[agent] = {tuple(map(int, conf.pos)): 1.0} continue ndist = agentDistances[agent] nd = {} # find all valid positions according to the noisy distance ps = [p for p in vp if -7 < manhattanDistance(pos, p) - ndist < 7] # iterate over all existing positions for k, v in adist.items(): # generate all valid positions after possible move vm = self._validMove(k, wall) # count the number of valid points for each of the possible # position after movement cp = reduce(_sum_list, ([ manhattanDistance(m, p) < 7 for m in vm ] for p in ps)) scp = sum(cp) # normalise to get a vector of probabilities to redistribute the # probability if scp != 0: cp = [c / scp for c in cp] for m, p in zip(vm, cp): nd[m] = nd.get(m, 0) + v * p # remove all zero probability and normalise the probability tp = sum(nd.values()) dist[agent] = {k: v / tp for k, v in nd.items() if v > 0} self._distribution = dist
def survivalCheck(self, gameState): ''' There are servral situations we would set our agents' survivalMode to be True. Otherwise, we return False. Those situations are as following: 1. We ran out of move, we should go home. 2. Food left is less than 2, we go home and win! 3. There is a ghost chasing us or we already eat enough food, go home! ''' self.survivalMode = False enemies = [gameState.getAgentState(i) for i in self.getOpponents(gameState)] chaseGhosts = [a for a in enemies if not a.isPacman and a.getPosition() != None and a.scaredTimer < 5] myState = gameState.getAgentState(self.index) myPos = myState.getPosition() from distanceCalculator import manhattanDistance gDist = 9999 gMdist = 9999 if len(chaseGhosts) > 0: gDist = min([self.getMazeDistance(myPos ,cg.getPosition()) for cg in chaseGhosts]) gMDist = min([manhattanDistance(myPos, cg.getPosition()) for cg in chaseGhosts]) foodNum = myState.numCarrying foodLeft = len(self.getFood(gameState).asList()) if myState.isPacman and foodNum > (self.totalFood / 2 - 1) and len(chaseGhosts) > 0: if gMDist <= 5: self.survivalMode = True self.survivalPoint = self.start elif myState.isPacman and foodNum > 2 and len(chaseGhosts)> 0: if foodNum > (self.totalFood / 4): self.survivalMode = True elif gDist <= 5: self.survivalMode = True elif foodLeft <= 2: self.survivalMode = True self.survivalPoint = self.start elif foodNum > 0 and self.moveCount > 270: self.survivalMode = True self.survivalPoint = self.start if self.survivalMode and len(chaseGhosts) > 0: ghostPos = [a.getPosition() for a in chaseGhosts] homeDis = self.getMazeDistance(myPos, self.survivalPoint) ghostToHome = min([self.getMazeDistance(gp,self.survivalPoint) for gp in ghostPos]) #check survival point valid or not if ghostToHome < homeDis: for hp in self.homePoints: homeDis = self.getMazeDistance(myPos, hp) ghostToHome = min([self.getMazeDistance(gp,hp) for gp in ghostPos]) if homeDis < ghostToHome: self.survivalPoint = hp break
def chooseAction(self, gameState): """ Picks among the actions with the highest Q(s,a). """ print(self.passedPositionWeight) myPos = gameState.getAgentState(self.index).getPosition() self.passedPositionWeight[myPos] += 1 if self.startPostion == myPos: self.negetiveReward += 1 if self.leftMoves == 300: self.startPostion = myPos self.leftMoves -= 1 actions = gameState.getLegalActions(self.index) if not gameState.getAgentState(self.index).isPacman and self.carryDots != 0: self.carryDots = 0 self.backHomeTimes += 1 self.reward += 1 # You can profile your evaluation time by uncommenting these lines start = time.time() enemies = [gameState.getAgentState(i) for i in self.getOpponents(gameState)] invaders = [a for a in enemies if not a.isPacman and a.getPosition() != None] manhattanDistanceToGhost = 0 if len(invaders) > 0: manhattanDistanceToGhost = min([distanceCalculator.manhattanDistance(i.getPosition(), myPos) for i in invaders]) if len(invaders) == 0: self.refreshPassedPositionWeight(gameState) values = [self.evaluate(gameState, a) for a in actions] # print 'eval time for agent %d: %.4f' % (self.index, time.time() - start) maxValue = max(values) bestActions = [a for a, v in zip(actions, values) if v == maxValue] foodLeft = len(self.getFood(gameState).asList()) finalAction = random.choice(bestActions) foodLeft = len(self.getFood(gameState).asList()) finalAction = random.choice(bestActions) # compute the number of dots that carried. successor = self.getFood(self.getSuccessor(gameState, finalAction)).asList() currentFoodList = self.getFood(gameState).asList() if len(currentFoodList) > len(successor): self.carryDots += 1 self.reward += 1 self.refreshPassedPositionWeight(gameState) return finalAction
def updateEnemiesPos(self, gameState): myPos = gameState.getAgentPosition(self.index) # predict pos by last eaten food/capsule enemiesDists = [ self.getMazeDistance(self.enemiesPos[i], myPos) if i in self.getOpponents(gameState) and self.enemiesPos[i] is not None else None for i in range(4) ] if enemiesDists.count(not None) > 0: closedEnemyIndex = enemiesDists.index( min(x for x in enemiesDists if x is not None)) else: closedEnemyIndex = self.getOpponents(gameState)[0] defending = self.getFoodYouAreDefending( gameState).asList() + self.getCapsulesYouAreDefending(gameState) for each in self.lastDefending: if each not in defending: self.enemiesPos[closedEnemyIndex] = each self.lastDefending = defending # observe pos by own vision for i in self.getOpponents(gameState): if gameState.getAgentState(i).getPosition() is not None: self.enemiesPos[i] = gameState.getAgentState(i).getPosition() # remove position of lost enemy when refreshing fog of war visibleEnemiesPos = [] for i in range(4): if i in self.getOpponents(gameState): if gameState.getAgentState(i).getPosition() is not None: visibleEnemiesPos.append(gameState.getAgentPosition(i)) else: visibleEnemiesPos.append(None) else: visibleEnemiesPos.append(None) for i in self.getOpponents(gameState): if self.enemiesPos[i] is not None \ and distanceCalculator.manhattanDistance(myPos, self.enemiesPos[i]) < 5 \ and self.enemiesPos[i] not in visibleEnemiesPos: self.enemiesPos[i] = None
def _offenseAction(self, gameState): index = self.index red = self.red agentStates = gameState.data.agentStates agentState = agentStates[index] distancer = self.distancer pos = agentState.configuration.pos _prevPos = self._prevPos if _prevPos is not None: if manhattanDistance(pos, _prevPos) > 1: self._escapes = None self._actions = None self._chasepath = None # TODO: notify the defensive agent # self._teammate._notifyReborn() self._prevPos = pos # TODO: determine if has capsule beside and perform corresponding action # if escaping, finish escaping if self._escapes: return self._getEscapeNext(gameState) states = [ agentStates[i] for i in (gameState.blueTeam if red else gameState.redTeam) ] # if determine to be in danger and currently carrying food, escape if any(not s.isPacman and s.scaredTimer == 0 and distancer.getDistance(s.configuration.pos, pos) < 4 for s in states): self._actions = None nc = self._prevCarry = agentState.numCarrying if nc > 0: return self._getEscapeNext(gameState) # find the closest food to eat, not necessary to be a TSP, this is just # a greedy strategy to eat the current closest food return self._getFoodNext(gameState)
def observe(self, observationState): myPos = observationState.getAgentPosition(self.index) noisyDistances = observationState.getAgentDistances() newDistribution = dict() for enemy in self.getOpponents(observationState): if self.beliefDistributions[enemy].totalCount( ) == 0: #If the districution for an enemy is not set up, set it up self.initializeDistribution(observationState, enemy) distribution = Counter() if observationState.getAgentPosition(enemy) is not None: #Assuming distribution[observationState.getAgentPosition(enemy)] = 1 else: for position in self.validPositions: dist = manhattanDistance(myPos, position) distribution[position] = self.beliefDistributions[enemy][ position] * observationState.getDistanceProb( dist, noisyDistances[enemy]) distribution.normalize() #Convert values to probabilities newDistribution[enemy] = distribution self.beliefDistributions = newDistribution
def survivalCheck(self, gameState): enemies = [ gameState.getAgentState(i) for i in self.getOpponents(gameState) ] chaseGhosts = [ a for a in enemies if (not a.isPacman) and a.getPosition() != None and a.scaredTimer == 0 ] #min([self.getMazeDistance(myState.getPosition(),cg.getPosition()) for cg in chaseGhosts]) myState = gameState.getAgentState(self.index) foodNum = myState.numCarrying if len(chaseGhosts) > 0: from distanceCalculator import manhattanDistance gDist = min([ manhattanDistance(myState.getPosition(), cg.getPosition()) for cg in chaseGhosts ]) if myState.isPacman: if len(chaseGhosts) > 0 and gDist <= 4 and not self.powerMode: self.survivalMode = True else: self.survivalMode = False
def Heuristic(self, loc, destination): from util import manhattanDistance dist = manhattanDistance(loc, destination) # print "manhattanDistance: ", dist return dist
def _defenseAction(self, gameState): index = self.index red = self.red data = gameState.data agentStates = data.agentStates distancer = self.distancer bounds = self._bound agent = agentStates[index] pos = agent.configuration.pos scare = agent.scaredTimer > 0 walls = data.layout.walls.data _prevPos = self._prevPos if _prevPos is not None: if manhattanDistance(pos, _prevPos) > 1: self._escapes = None self._actions = None self._chasepath = None # TODO: notify the defensive agent # self._teammate._notifyReborn() self._prevPos = pos # first select the target with the highest carrying food target = None rs = [] pnc = 0 for i in (gameState.blueTeam if red else gameState.redTeam): agentState = agentStates[i] nc = agentState.numCarrying npos = agentState.configuration.pos if nc > pnc: pnc = nc target = agentState.configuration.pos rs.append((min(((b, (distancer.getDistance( npos, b), distancer.getDistance(pos, b))) for b in bounds), key=itemgetter(1)), npos, agentState.isPacman)) layout = data.layout height, width = layout.height, layout.width if target is not None: if scare: tx, ty = target sur = [(int(tx + cx), int(ty + cy)) for cx, cy in self._closes] sur = [ (x, y) for x, y in sur if 0 <= x < width and 0 <= y < height and not walls[x][y] ] sel = min( ((s, min(distancer.getDistance(s, b) for b in bounds), distancer.getDistance(pos, s)) for s in sur), key=itemgetter(1, 2))[0] return self._chase(gameState, sel) return self._chase(gameState, target) # if no agent carries food, select the closest one which is currently a # Pacman mb = None mbd = (inf, inf) md = inf for (b, bd), npos, pac in rs: dist = distancer.getDistance(npos, pos) if pac: if dist < md: target = npos md = dist else: if bd < mbd: mb, mbd = b, bd if target is not None: if scare: tx, ty = target sur = [(int(tx + cx), int(ty + cy)) for cx, cy in self._closes] sur = [ (x, y) for x, y in sur if 0 <= x < width and 0 <= y < height and not walls[x][y] ] sel = min( ((s, min(distancer.getDistance(s, b) for b in bounds), distancer.getDistance(pos, s)) for s in sur), key=itemgetter(1, 2))[0] return self._chase(gameState, sel) return self._chase(gameState, target) # if both are still in their sides, just try to reach the closest bound # they could reach if scare: tx, ty = mb sur = [(int(tx + cx), int(ty + cy)) for cx, cy in self._closes] sur = [(x, y) for x, y in sur if 0 <= x < width and 0 <= y < height and not walls[x][y]] sel = min(((s, min(distancer.getDistance(s, b) for b in bounds), distancer.getDistance(pos, s)) for s in sur), key=itemgetter(1, 2))[0] return self._chase(gameState, sel) return self._chase(gameState, mb)
def observe(self, gameState): distances = gameState.getAgentDistances() isRed = self.red actual_distances = {} for i in range(len(distances)): if not isRed and i in gameState.getRedTeamIndices(): actual_distances[i] = distances[i] elif isRed and i in gameState.getBlueTeamIndices(): actual_distances[i] = distances[i] pos = gameState.getAgentState(self.index) pos = pos.getPosition() new_distributions = {} for key in actual_distances: new_distributions[key] = util.Counter() for position in self.legalPositions: dist = distanceCalculator.manhattanDistance(position, pos) new_distributions[key][position] = gameState.getDistanceProb(dist, actual_distances[key]) if hasattr(self, 'distributions'): for key in actual_distances: for entry in new_distributions[key]: self.distributions[key][entry] *= new_distributions[key][entry] else: self.distributions = new_distributions for key in actual_distances: new_d = util.Counter() for position in self.legalPositions: val = self.distributions[key][position] left = (position[0]-1, position[1]) right = (position[0]+1, position[1]) top = (position[0], position[1]-1) bot = (position[0], position[1]+1) new_d[position] += val if left in self.legalPositions: new_d[left] += val if right in self.legalPositions: new_d[right] += val if top in self.legalPositions: new_d[top] += val if bot in self.legalPositions: new_d[bot] += val new_d.normalize() self.distributions[key] = new_d # Printing distribution routine for debugging """ for key in self.distributions: best_positions = [] best_prob = 0 d = self.distributions[key] for entry in self.distributions[key]: if d[entry] > best_prob: best_prob = d[entry] best_positions = [entry] elif d[entry] == best_prob: best_positions.append(entry) predicted = random.choice(best_positions) print predicted arr = [[0 for x in range(31)] for y in range(15)] for element in self.distributions[key]: arr[element[1]][element[0]] = self.distributions[key][element] for r in range(15,0,-1): for c in range(31): if (c,r) == predicted: print '@', elif (c, r) in self.legalPositions: print '-' if arr[r][c] else ' ', else: print "#", print """ for key in self.distributions: allZero = True for entry in self.distributions[key]: if self.distributions[key][entry]: allZero = False if allZero: self.distributions = new_distributions return
def getFeatures(self, gameState, action): features = util.Counter() successor = self.getSuccessor(gameState, action) myState = successor.getAgentState(self.index) myPos = myState.getPosition() # Computes whether we're on defense (1) or offense (0) features['onDefense'] = 1 if myState.isPacman: features['onDefense'] = 0 # Computes distance to invaders we can see enemies = [ successor.getAgentState(i) for i in self.getOpponents(successor) ] invaders = [ a for a in enemies if a.isPacman and a.getPosition() != None ] ghosts = [ a for a in enemies if not a.isPacman and a.getPosition() != None ] features['numInvaders'] = len(invaders) if len(invaders) > 0: dists = [ self.getMazeDistance(myPos, a.getPosition()) for a in invaders ] features['invaderDistance'] = min(dists) if len(invaders) == 0: distanceToCenter = self.getDistanceToCenter(gameState, myPos) features['distanceToCenter'] = distanceToCenter if len(ghosts) > 0: for a in invaders: if distanceCalculator.manhattanDistance( myPos, a.getPosition()) < 5: features['distanceToCenter'] += abs(myPos[1] - a.getPosition()[1]) if action == Directions.STOP: features['stop'] = 1 rev = Directions.REVERSE[gameState.getAgentState( self.index).configuration.direction] if action == rev: features['reverse'] = 1 distanceToLostFood = 0 #before find the invaders, we use lost food position to estimate the position of invaders if len(invaders) == 0: lostFoodPosition = self.getLostFood(gameState) if lostFoodPosition != (0, 0): distanceToLostFood = self.getMazeDistance( myPos, lostFoodPosition) self.lastLostFoodPostion = lostFoodPosition self.lastLostFoodEffect = 10 else: if self.lastLostFoodPostion != ( 0, 0) and self.lastLostFoodEffect > 0: distanceToLostFood = self.getMazeDistance( myPos, self.lastLostFoodPostion) self.lastLostFoodEffect -= 1 features['distanceToLostFood'] = distanceToLostFood return features
def chooseAction(self, gameState): # Get remain food as a list foodLeft = len(self.getFood(gameState).asList()) # food our agent carrying in this gameState foodNum = gameState.getAgentState(self.index).numCarrying # if our agent eat food in last state, set preFoodNum to 1, else 0 # if self.getPreviousObservation() is not None: # preFoodNum = self.getPreviousObservation().getAgentState(self.index).numCarrying # else: # preFoodNum = 0 # enemies = [gameState.getAgentState(i) for i in self.getOpponents(gameState)] # chaseGhosts = [a for a in enemies if not a.isPacman and a.getPosition() != None and a.scaredTimer is 0] # if preFoodNum == foodNum and len(chaseGhosts) == 0: # self.noFoodTimer += 1 # else: # self.noFoodTimer = 0 # Iteration of Monte Carlo Tree # Simulation Depth of Monte Carlo # Timer use to see the performance self.backhome = False chaseGhosts = [] defender = self.getDefenders(gameState) if defender != None: for i in defender: if i.scaredTimer < 5: chaseGhosts.append(i) myState = gameState.getAgentState(self.index) myPos = myState.getPosition() capsuleList = self.getCapsules(gameState) clist = [] closeCapsules = None if len(capsuleList) > 0: for c in capsuleList: clist.append( self.getMazeDistance( c, gameState.getAgentPosition(self.index))) close = min(clist) capsuleDis = [ self.getMazeDistance( gameState.getAgentState(self.index).getPosition(), c) for c in capsuleList ] closeCapsules = [ c for c, d in zip(self.getCapsules(gameState), capsuleDis) if d == min(capsuleDis) ] if len(chaseGhosts) > 0: gDistL = [] gMDistL = [] for i in chaseGhosts: gDistL.append(self.getMazeDistance(myPos, i.getPosition())) for i in chaseGhosts: gMDistL.append(manhattanDistance(myPos, i.getPosition())) gDist = min(gDistL) gMDist = min(gMDistL) if gameState.getAgentState( self.index).numCarrying > 0 and gameState.data.timeleft < 150: self.backhome = True elif len(self.getFood(gameState).asList()) <= 2: self.backhome = True elif myState.isPacman and gameState.getAgentState( self.index).numCarrying >= 6 and len(chaseGhosts) > 0: if gMDist <= 5: self.backhome = True # self.survivalPoint = self.start elif myState.isPacman and gameState.getAgentState( self.index).numCarrying >= 1 and len(chaseGhosts) > 0: if gDist <= 5: self.backhome = True # self.survivalPoint = self.start # elif myState.isPacman and gameState.getAgentState(self.index).numCarrying < 1 and len(chaseGhosts)> 0: # self.backhome = True # elif myState.isPacman and gameState.getAgentState(self.index).numCarrying < 1 and len(chaseGhosts)> 0 and len(capsuleList) <= 0: # print("no move") # if gDist <= 5 or gMDist <= 5: # self.backhome = True # self.survivalPoint = self.start # self.powerCheck(gameState) scareTime = [] if defender != None: for i in defender: scareTime.append(i.scaredTimer) if len(scareTime) > 0: if min(scareTime) >= 15: self.checkScare = True self.backhome = False else: self.checkScare = False # if not gameState.getAgentState(self.index).isPacman: # self.survivalPoint = self.start # Choose an action depending on survivalMode # if survivalMode is on, we use go back home directly, # else, we use MCT to pick a best action for us if self.backhome is False: values = [] MCT = self.MCT(gameState, iter_times=32, simulate_depth=10) childs = MCT.childs for c in childs: values.append(c.reward / c.visited) max_value = max(values) nextNode = [] for m, n in zip(childs, values): if n == max_value: nextNode.append(m) nextState = nextNode[0] return nextState.gameState.getAgentState( self.index).configuration.direction else: action = self.goBackHome(gameState) return action