Return bestMove in minimax algorithm for tictactoe

前端 未结 3 2068
遥遥无期
遥遥无期 2020-12-29 00:35

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

3条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-29 01:35

    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* best_moves 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.

提交回复
热议问题