I'm currently implementing an AI controller class that is being used to determine the moves that ms.pacman should make to collect pills and avoid ghosts. In order to determine which is the best move to make in each state (configuration) of the game, I'm using Breadth-First Search to search the decision tree at each state. I've gotten the controller to work (at least somewhat) for Depth-First Search so I was trying to apply the same logic here.
The idea for DFS was to start with a "root" or driver function which would iterate through the possible moves ms. pacman could make at each state in the decision tree and then make a call to a recursive function that searches the tree to find the terminal state (point at which all pills have been eaten) with the highest value (e.g. highest score). This value is returned from the recursive function and stored in a variable in the root function. The root function the returns the move (out of possible moves) that had the highest value in the tree.
Since BFS is not recursive, I was thinking that it wouldn't be necessary to have a driver function like this, so I decided to put it all in one function. Based on DFS, I'm implementing BFS using a queue which stores all of the neighboring states of the current state and visits each state in FIFO order. Once a state is reached in which all pills have been eaten, the current Move should be returned. I'm not sure if this is the best approach, but its what I could come up with. The problem is that the code for the function takes too long to run and ms.Pacman immediately just goes left and runs into a wall. I'm assuming this is because the terminal state is never being found. Here is the function (in Java):
public MOVE bfs(Game state){
EnumMap<GHOST,MOVE> ghostMove = new EnumMap<>(GHOST.class);
MOVE bestMove = MOVE.NEUTRAL;
Queue<Game> q = new LinkedList<>();
q.add(state.copy());
while(!q.isEmpty()){
Game current = q.peek();
q.remove();
for (MOVE move : current.getPossibleMoves (current.getPacmanCurrentNodeIndex())) {
Game neighbor = state.copy();
neighbor.advanceGame(move, ghostMove);
q.add(neighbor);
if ((current.getNumberOfActivePills() == 0) && (current.getNumberOfActivePowerPills() == 0)) {
return move;
}
}
}
return bestMove;
}
Is there anything wrong with the design of the algorithm that could be causing this problem?