Search code examples
pythonalgorithmgraphartificial-intelligence

AttributeError: 'int' object has no attribute 'map' when trying to write a recursive algorithm for a depth limited search


Trying to write a recursive algorithm for a depth limited search for a 6-puzzle game but for some reason i keep getting the above error and cannot understand why. This is my code for the recursve depth limited search:

def rec_dls(node, limit):
    global cutoff_occurred
    cutoff = 0
    failure = -1
    if goal_state == node.state:
        return node
    elif limit == 0:
        return cutoff          # cutoff
    else:
        cutoff_occurred = False
        actions = moves(node.state) # all possibles children of this state
        for action in actions:
            child = State(action, node, node.depth+1, node.cost+1)
            result = rec_dls(child, limit - 1)
            if result == cutoff:
                cutoff_occurred = True
            elif result != failure:
                return result
        if cutoff_occurred:
            return cutoff
        else:
            return failure
        

def dls(limit):
    node = State(initial_state, None, 0, 0)
    return rec_dls(node, limit)

and also the State class:


class State: 
    def __init__(self, state, parent, depth, cost): 
        self.state = state 
        self.parent = parent 
        self.depth = depth 
        self.cost = cost 
        if self.state: 
            self.map = ''.join(str(e) for e in self.state) 
            
    def __eq__(self, other): 
        return self.map == other.map 
    def __lt__(self, other): 
        return self.map < other.map

this is the error i have in more details:

enter image description here

for reference, i am basing the logic of my work on this (from "Artificial Intelligence, A Modern Approach"):

enter image description here


Solution

  • The problem isn't when rec_dls returns an int. It's when it returns one of your State objects.

    Consider the following lines of code:

               result = rec_dls(child, limit - 1)
               if result == cutoff:
                   # ...
    

    Suppose rec_dls here returns one of your State objects. You then compare your State object against cutoff, which contains the int value 0, and because you override __eq__ in your State class, this comparison causes State.__eq__ to be called with other set to 0.

    Being an int, 0 doesn't have a map attribute, hence your error.

    Perhaps you want to include in your __eq__ method a check that other is another State object:

        def __eq__(self, other): 
            return isinstance(other, State) and self.map == other.map