I have tried to code the minimax algorithm for tic-tac-toe given in Russel Norvig\'s book on Artificial Intelligence. It had everything except that the way to return the bes
Well, it looks like MiniMax correctly chooses it for you, just call it with an initial state and a depth. (Unless the first player according to the state is the second player, then you should call min_move in MiniMax.)
EDIT: yes, I overlooked something, bestMove currently does not make much sense. In the program within max_move you change the loop like this:
for(int i = 0 ; i < nMoves ; i++)
{
moveT move = moveList[i];
MakeMove(state, move);
int new_value = min_move(state, depth+1);
if(new_value > v)
{
v=new_value;
}
RetractMove(state, move);
}
After that you can think about you what bestMove means? My idea is that you are interested in finding one of the "best possible" series of moves for tic-tac-toe. For that you need a vector or even better a stack. But that also means having std::stack as the last parameter.
For the stack implementation, in min_move you return the next moves and if their value is the best, you will push your move on the top of the best_moves stack. Of course at the end of the game you just return the empty stack. It takes an OOP approach to pull it off properly, I'll do it when I have some time.
If all you need is merely the best next move then I suggest you change the return types of min_move and max_moe to some struct like this:
struct Value_move{
int value;
moveT best_move;
};
Then the new implementation of max_move looks like the following:
const int MOVE_INVALID = -12345;
const int MOVE_NOTHING = -12346;
Value_move max_move(stateT state, int depth)
{
Value_move best;
best.value = -10000; best.best_move = MOVE_INVALID;
if(GameIsOver(state))
{
best.value = EvaluateStaticPosition(state);
best.best_move = MOVE_NOTHING;
return best;
}
vector moveList;
GenerateMoveList(state, moveList);
int nMoves = moveList.size();
for(int i = 0 ; i < nMoves ; i++)
{
moveT move = moveList[i];
MakeMove(state, move);
Value_move curr = min_move(state, depth+1);
if(curr.value > best.value)
{
best.value = curr.value;
best.best_move = move;
}
RetractMove(state, move);
}
return v;
}
You only need to pick up the best_move field in the returned struct in the MiniMax function.
REMARK:
You have to admit though this does not resemble a c++ program in many aspects but rather a c program. Otherwise, all the functions in CapitalCamelCase should be class methods, you should pass states by (const) ref instead of value -- but this whole code makes sense only if the status is really a pointer behind a typedef.