#implementation of function “breadthFirstSearch” (for graduate students)def bfs(self,goalState):    queue = self    queueNoNodesPop = 0    queueMaxLen = 1        depthOfTheQueue = 0    pathCostQueue = 0    alreadyVisited = set()        while queue:        if len(queue) > queueMaxLen:            queueMaxLen = len(queue)        currentNpdeOfTheQueue = queue.pop(0)        queueNoNodesPop +=1                currentDepthOfTheQueue = depthOfTheQueue.pop(0)        cuurentPathCOstOFQueue = pathCostQueue,pop(0)        alreadyVisited.add(tuple(currentNpdeOfTheQueue.state.reshape(1,9)0))                #after gettng goal state        if np.array_equal(currentNpdeOfTheQueue,state,goalState):            currentDepthOfTheQueue.printPathToGoal()                        print (‘Time performance to get to the goal’, str(queueNoNodesPop), ‘are the nodes pooped off the queue.’)            print (‘Time spent to get to the goal:% 0.2fs’ %(time.time()-start))                    else:            if currentNpdeOfTheQueue.isMovingDownValid():                destinationState,upValuePosition  = currentNpdeOfTheQueue.isMovingDownValid()                if tuple(destinationState.reshape(1,9)0) not in alreadyVisited:                    currentNpdeOfTheQueue.moveDownDirection = Node(state=destinationState,parent=currentNpdeOfTheQueue,actionResulted=’down’,depthValue=currentDepthOfTheQueue+1,stepCost=upValuePosition,pathCost=cuurentPathCOstOFQueue+upValuePosition,heuristicCost=0)                    queue.append(currentNpdeOfTheQueue.moveDownDirection)                    depthOfTheQueue.append(currentDepthOfTheQueue+1)                    pathCostQueue.append(cuurentPathCOstOFQueue+upValuePosition)                        if currentNpdeOfTheQueue.isMovingRightValid():                destinationState,leftValuePosition  = currentNpdeOfTheQueue.isMovingRightValid()                if tuple(destinationState.reshape(1,9)0) not in alreadyVisited:                    currentNpdeOfTheQueue.moveRightDirection = Node(state=destinationState,parent=currentNpdeOfTheQueue,actionResulted=’right’,depthValue=currentDepthOfTheQueue+1,stepCost=leftValuePosition,pathCost=cuurentPathCOstOFQueue+leftValuePosition,heuristicCost=0)                    queue.append(currentNpdeOfTheQueue.moveRightDirection)                    depthOfTheQueue.append(currentDepthOfTheQueue+1)                    pathCostQueue.append(cuurentPathCOstOFQueue+leftValuePosition)            if currentNpdeOfTheQueue.isMovingUpValid():                destinationState,lowerValuePosition  = currentNpdeOfTheQueue.isMovingUpValid()                if tuple(destinationState.reshape(1,9)0) not in alreadyVisited:                    currentNpdeOfTheQueue.moveUpDirection = Node(state=destinationState,parent=currentNpdeOfTheQueue,actionResulted=’up’,depthValue=currentDepthOfTheQueue+1,stepCost=lowerValuePosition,pathCost=cuurentPathCOstOFQueue+lowerValuePosition,heuristicCost=0)                    queue.append(currentNpdeOfTheQueue.moveUpDirection)                    depthOfTheQueue.append(currentDepthOfTheQueue+1)                    pathCostQueue.append(cuurentPathCOstOFQueue+lowerValuePosition)                                if currentNpdeOfTheQueue.isLeftUpValid():                destinationState,rightValuePosition  = currentNpdeOfTheQueue.isLeftUpValid()                if tuple(destinationState.reshape(1,9)0) not in alreadyVisited:                    currentNpdeOfTheQueue.moveLeftDirection = Node(state=destinationState,parent=currentNpdeOfTheQueue,actionResulted=’Left’,depthValue=currentDepthOfTheQueue+1,stepCost=rightValuePosition,pathCost=cuurentPathCOstOFQueue+rightValuePosition,heuristicCost=0)                    queue.append(currentNpdeOfTheQueue.moveLeftDirection)                    depthOfTheQueue.append(currentDepthOfTheQueue+1)                    pathCostQueue.append(cuurentPathCOstOFQueue+rightValuePosition)