0

I'm creating the 8 puzzle AI game in bfs and it always ends up in an infinite loop , i'm using a queue to store the explored (not yet visited nodes) , and a list to store the explored and visited nodes to avoid visiting the same state multiple times , also im using getNextStates() function to get all of the possible next states depending on the position of "0" , switch() is responsible for creating the next state , my code :

goalState=[0, 1, 2, 3, 4, 5, 6, 7, 8]
def switch(list,index1,index2):
    newList=[]
    for i in range(len(list)):
        newList.append(list[i])

    temp=newList[index1]
    newList[index1]=newList[index2]
    newList[index2]=temp
    return newList

def getNextStates(state):
    nextStates=[]
    length=len(state)
    emptyTile=0
    for i in range(length):
        if state[i]==0:
            emptyTile=i
            #    1
            # 0  3
    print('empty tile in position : ' , emptyTile)
    if emptyTile==0:
        nextStates.append(switch(state,0,1))
        nextStates.append(switch(state, 0, 3))
    elif emptyTile==1:
        nextStates.append(switch(state, 1, 0))
        nextStates.append(switch(state, 1, 4))
        nextStates.append(switch(state, 1, 2))
    elif emptyTile==2:
        nextStates.append(switch(state, 2, 1))
        nextStates.append(switch(state, 2, 5))
    elif emptyTile==3:
        nextStates.append(switch(state, 3, 0))
        nextStates.append(switch(state, 3, 4))
        nextStates.append(switch(state, 3, 6))
    elif emptyTile==4:
        nextStates.append(switch(state, 4, 3))
        nextStates.append(switch(state, 4, 1))
        nextStates.append(switch(state, 4, 5))
        nextStates.append(switch(state, 4, 7))
    elif emptyTile==5:
        nextStates.append(switch(state, 5, 2))
        nextStates.append(switch(state, 5, 4))
        nextStates.append(switch(state, 5, 8))
    elif emptyTile==6:
        nextStates.append(switch(state, 6, 3))
        nextStates.append(switch(state, 6, 7))
    elif emptyTile==7:
        nextStates.append(switch(state, 7, 6))
        nextStates.append(switch(state, 7, 4))
        nextStates.append(switch(state, 7, 8))
    else:
        nextStates.append(switch(state, 8, 7))
        nextStates.append(switch(state, 8, 5))

    return nextStates


def breadthFirst(initialState,goal):
    global exploredCount , visitedCount
    exploredCount = 1
    visitedCount = 0
    frontier = []
    frontier.append(initialState)
    explored=[]
    print("Staring Dequing....")
    while len(frontier) > 0:
        print(len(frontier))
        state=frontier.pop(0)
        print("dequed : " , state)
        explored.append(state)
        print("appended in explored and visitedCount incremented")
        visitedCount += 1
        if state==goal:
            print("State Is Accomplished")
            return state
        nextStates=getNextStates(state)
        print("possible Next States : " , nextStates)
        for i in range(len(nextStates)):
            print('Checking Child states , current : ' , nextStates[i])
            if  not nextStates[i] in explored:
                if not nextStates[i] in frontier:
                    print("not in visited or explored , enqueue")
                    frontier.append(nextStates[i])
                    exploredCount += 1
 
    return initialState
h0sny
  • 11
  • 5
  • And how do you execute your `bfs`? I tried adding `breadthFirst(0, 8)` at the end of your code but a `TypeError: object of type 'int' has no len()` is thrown. – qouify Nov 24 '21 at 12:12

1 Answers1

1

The issue was that there are initial states which are unsolvable , if this is the case the algorithm will keep exploring in an infinite loop. The solution was to count the number of inversions (empty tile not included) and if its odd then its unsolvable , if its even then its solvable , this resource helped me understand : https://www.cs.princeton.edu/courses/archive/fall12/cos226/assignments/8puzzle.html

h0sny
  • 11
  • 5