简体   繁体   中英

TypeError: unsupported operand type(s) for *: 'function' and 'float'

I can't seem to figure out why I keep getting this error. The command line error traceback looks like this:

Windows Powershell 错误回溯

The point of the following code is to essentially give artificial intelligence to Pacman; keep him away from unscared ghosts, while eating all the food and capsules on a map. Most of code for this was given by the prof for an AI class, which can be found here .

The evaluationFunction method returns a very simple heuristic value that takes into consideration the distances to ghosts, food and capsules. The getAction function is found within my ExpectimaxAgent class (passed arg is MulitAgentSearchAgent), and it gathers all relevant information together, iterates through all possible actions and passes the info along to expectimax. The expectimax function is supposed to calculate a heuristic value which when returned to getAction is compared to the other action-heuristic values, and the one with the highest heuristic is chosen as the best action.

This should be all the relevant code for this error (if not I'll add more, also a quick apology for the noob mistakes in this question, I'm first time poster):

class ReflexAgent(Agent):
    def getAction(self, gameState):
         # Collect legal moves and successor states
         legalMoves = gameState.getLegalActions()
         # Choose one of the best actions
         scores = [self.evaluationFunction(gameState, action) for action in legalMoves]
         bestScore = max(scores)
         bestIndices = [index for index in range(len(scores)) if scores[index] == bestScore]
         chosenIndex = random.choice(bestIndices) # Pick randomly among the best
         return legalMoves[chosenIndex]

     def evaluationFunction(self, currentGameState, action):
        successorGameState = currentGameState.generatePacmanSuccessor(action)
        oldPos = currentGameState.getPacmanPosition()
        newPos = successorGameState.getPacmanPosition()
        newFood = successorGameState.getFood()
        newGhostStates = successorGameState.getGhostStates()
        # heuristic baseline
        heuristic = 0.0
        # ghost heuristic
        for ghost in newGhostStates:
            ghostDist = manhattanDistance(ghost.getPosition(), newPos)
            if ghostDist <= 1:
                if ghost.scaredTimer != 0:
                    heuristic += 2000
                else:
                    heuristic -= 200
        # capsule heuristic
        for capsule in currentGameState.getCapsules():
            capsuleDist = manhattanDistance(capsule, newPos)
            if capsuleDist == 0:
                heuristic += 100
            else:
                heuristic += 10.0/capsuleDist
        # food heuristic
        for x in xrange(newFood.width):
            for y in xrange(newFood.height):
                if (newFood[x][y]):
                    foodDist = manhattanDistance(newPos, (x,y))
                    if foodDist == 0:
                        heuristic += 100
                    else:
                        heuristic += 1.0/(foodDist ** 2)
         if currentGameState.getNumFood() > successorGameState.getNumFood():
             heuristic += 100
         if action == Directions.STOP:
             heuristic -= 5
         return heuristic

def scoreEvaluationFunction(currentGameState):
    return currentGameState.getScore()

class MultiAgentSearchAgent(Agent):
    def __init__(self, evalFn = 'scoreEvaluationFunction', depth = '2'):
        self.index = 0 # Pacman is always agent index 0
        self.evaluationFunction = util.lookup(evalFn, globals())
        self.depth = int(depth)

class ExpectimaxAgent(MultiAgentSearchAgent):
    def getAction(self, gameState):
        # Set v to smallest float value (-infinity)
        v = float("-inf")
        bestAction = []
        # Pacman is agent == 0
        agent = 0
        # All legal actions which Pacman can make from his current location
        actions = gameState.getLegalActions(agent)
        # All successors determined from all the legal actions
        successors = [(action, gameState.generateSuccessor(agent, action)) for action in actions]
        # Iterate through all successors
        for successor in successors:
            # Expectimax function call (actor = 1, agentList = total number of agents, state = successor[1], depth = self.depth, evalFunct = self.evaluationFunction)
            temp = expectimax(1, range(gameState.getNumAgents()), successor[1], self.depth, self.evaluationFunction)
            # temp is greater than -infinity (or previously set value)
            if temp > v:
                # Set v to the new value of temp
                v = temp
                # Make the best action equal to successor[0]
                bestAction = successor[0]
        return bestAction

def expectimax(agent, agentList, state, depth, evalFunct):
    # Check if won, lost or depth is less than/equal to 0
    if depth <= 0 or state.isWin() == True or state.isLose() == True:
        # return evalFunct
        return evalFunct
    # Check to see if agent is Pacman
    if agent == 0:
        # Set v to smallest float value (-infinity)
        v = float("-inf")
    # Otherwise, agent is ghost
    else:
        # Set v to 0
        v = 0
    # All possible legal actions for Pacman/Ghost(s)
    actions = state.getLegalActions(agent)
    # All successors determined from all the legal actions for the passed actor (either Pacman or Ghost(s))
    successors = [state.generateSuccessor(agent, action) for action in actions]
    # Find the inverse of the length of successors
    p = 1.0/len(successors)
    # Iterate through the length of successors
    for j in range(len(successors)):
        # Temp var to store the current successor at location j
        successor = successors[j]
        # Check if agent is Pacman
        if agent == 0:
            # Set v to the max of its previous value or recursive call to expectimax
            v = max(v, expectimax(agentList[agent + 1], agentList, successor, depth, evalFunct))
        # Check if agent is equal to ghost 2
        elif agent == agentList[-1]:
            # Increment v by the recursive call to p times expectimax (with agent=agentlist[0], agentList, state=successor, depth-=1, evalFunct)
            v += expectimax(agentList[0], agentList, successor, depth - 1, evalFunct) * p
        # Otherwise
        else:
            # Increment v by p times the recursive call to expectimax (with agent=agentList[agent+1], agentList, state=successor, depth, evalFunct)
            v += expectimax(agentList[agent + 1], agentList, successor, depth, evalFunct) * p
    return v

I've looked at a few other posts on here, and around the inter-webs, but have found nothing that seems to be similar to my issue. I've tried to pass the value to a temp variable, even tried to move the multiplication before the function call, but those changes have given me the exact same error, on the exact same line.

The error was the first return inside of the expectimax function. Instead of:

def expectimax(agent, agentList, state, depth, evalFunct):
    # Check if won, lost or depth is less than/equal to 0
    if depth <= 0 or state.isWin() == True or state.isLose() == True:
        # return evalFunct
        return evalFunct <--- cause of the error

It should have been:

return evalFunct(state)

This is because (as was pointed out) evalFunct only points to the evaluation function the user chose (from the command line arguments).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM