0

I am writing 3D tic tac toe game using minimax algorithm with alpha beta pruning, but the algorithm doesnt give optimal solution, it goes and chooses next possible solution from winning states, not taking into concern what is on the board, meaning it wont block my moves. This is the code: `

int Game::miniMax(char marker, int depth, int alpha, int beta){
    // Initialize best move
    bestMove = std::make_tuple(-1, -1, -1);
    
        // If we hit a terminal state (leaf node), return the best score and move
    if (isBoardFull() || getBoardState('O')!=0 || depth>5)
        return getBoardState('O');


    auto allowedMoves = getAllowedMoves();

    for (int i = 0; i < allowedMoves.size(); i++){
        auto move = allowedMoves[i];
        board[std::get<0>(move)][std::get<1>(move)][std::get<2>(move)] = marker;

        // Maximizing player's turn 
        if (marker == 'O'){
            int bestScore = INT32_MIN;
            int score = miniMax('X', depth + 1, alpha, beta);

            // Get the best scoring move
            if (bestScore <= score){
                bestScore = score - depth * 10;
                bestMove = move;
                // Check if this branch's best move is worse than the best
                // option of a previously search branch. If it is, skip it
                alpha = std::max(alpha, bestScore);
                board[std::get<0>(move)][std::get<1>(move)][std::get<2>(move)] = '-';
                if (beta <= alpha){ 
                    break; 
                }
            }

        } // Minimizing opponent's turn
        else{
            int bestScore = INT32_MAX;
            int score = miniMax('O', depth + 1, alpha, beta);

            if (bestScore >= score){
                bestScore = score + depth * 10;
                bestMove = move;

                // Check if this branch's best move is worse than the best
                // option of a previously search branch. If it is, skip it
                beta = std::min(beta, bestScore);
                board[std::get<0>(move)][std::get<1>(move)][std::get<2>(move)] = '-';
                if (beta <= alpha){ 
                    break; 
                }
            }

        }

        board[std::get<0>(move)][std::get<1>(move)][std::get<2>(move)] = '-'; // Undo move

    }

    if(marker== 'O') 
        return INT32_MIN;
    else 
        return INT32_MAX;
}

` What do I need to change to make it work?

I tried other ways to implement minimax, but it doesnt give optimal, or any, solution. The limit on depth is because it is too slow for bigger depths, but still not giving solution, also increasing the value of the constant that multiplies the depth in the score part is only slowing the program

Filip
  • 1
  • 1
    Have you tried to [step through this code line-by-line in a debugger](https://stackoverflow.com/questions/25385173) to see where exactly the program behaves differently than you expected? Using a debugger is often the first step when a program does not behave the way you want it to. – Drew Dormann Dec 23 '22 at 23:33
  • This is not related to the question but just noting that since C++17 you can avoid the verbosity of std::get by using structured binding like this: `auto [m1, m2, m3] = move;` `board[m1][m2][m3] = marker;` – Chiara Coetzee Dec 23 '22 at 23:39
  • You'll be glad to hear you don't need anyone's help to figure this out, just a tool you already have: your debugger! This is exactly what a debugger is for. It [runs your program, one line at a time, and shows you what's happening](https://stackoverflow.com/questions/25385173/), this is something that's every C++ developer must know how to do. With your debugger's help you'll able to quickly find all problems in this and all future programs you write, without having to ask anyone for help. Have you tried using your debugger, already? If not, why not? What did your debugger show you? – Sam Varshavchik Dec 23 '22 at 23:39
  • *meaning it wont block my moves* -- What is "it"? You wrote the program, it is doing exactly as you've written. The program isn't angry at you and thus isn't doing as you want. If the program doesn't work correctly, then you should debug your code. – PaulMcKenzie Dec 23 '22 at 23:47
  • I tried to debug, but I didnt come to any conclusion using that, I watched bestMove value, but couldnt understand why it changed the way it did at the end, can anybody confirm if the minimax function is correct so I know where to look for the mistake, in this function or some other? – Filip Dec 24 '22 at 13:26

0 Answers0