Esempio n. 1
0
    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)
        }
Esempio n. 2
0
 def Heuristic(self,loc,destination):
   """
   Use Manhattan distance to calculate the heuristic distance.
   """
   from util import manhattanDistance
   dist = manhattanDistance(loc,destination)
   return dist
Esempio n. 3
0
    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))
Esempio n. 4
0
    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
Esempio n. 5
0
    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
Esempio n. 6
0
    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
Esempio n. 7
0
    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
Esempio n. 8
0
    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)
Esempio n. 9
0
    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
Esempio n. 10
0
    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
Esempio n. 11
0
 def Heuristic(self, loc, destination):
     from util import manhattanDistance
     dist = manhattanDistance(loc, destination)
     # print "manhattanDistance: ", dist
     return dist
Esempio n. 12
0
    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)
Esempio n. 13
0
  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
Esempio n. 14
0
    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
Esempio n. 15
0
    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