C++ 4 In a row AlphaBeta algorithm is not very smart

219 Views Asked by At

I'm making an AI controlled alpha-beta algorithm for a school project, but my algorithm is very inconsistent. Sometimes it blocks all my moves successfully, and sometimes it just ignores my 3 in a row as seen here. How could this happen and how can I resolve the issue?

int alphaBeta(const State board, int alpha, int beta, const Player player, int depth)
{
    //Max player = Player::O
    //Min player = Player::X

    std::vector<Move> possibleMoves = getMoves(board);

    if(eval(board)==Player::X){return 9999-depth;}      //Player X wins
    else if(eval(board)==Player::O){return -9999+depth;}    //Player O wins
    else if(possibleMoves.size()==0){return 0;}     //Tie
    else{   //Zoek verder
        depth++;
        State nextBoard = board;
        int result;

        if(player==Player::O){
            for (Move move: possibleMoves) {
                nextBoard = doMove(nextBoard, move);
                result = alphaBeta(nextBoard, alpha, beta, Player::X, depth);
                if (result > alpha){    
                    alpha = result; 
                    if (depth == 1){
                                    choice = move; //The actual move he will do
                    }
                }
                else if (alpha >= beta){ 
                    return alpha; 
                }
            }
            return alpha;
        }

        else{
            for (Move move: possibleMoves) {
                nextBoard = doMove(nextBoard, move);
                result = alphaBeta(nextBoard, alpha, beta, Player::O, depth);
                if (result < beta){ 
                    beta = result;
                    if (depth == 1){
                                    choice = move;
                    }
                }
                else if (beta <= alpha){ 
                    return beta;
                }
            }
            return beta;
        }
    }
}
2

There are 2 best solutions below

6
molbdnilo On BEST ANSWER

You're repeatedly modifying nextBoard, adding (possibly illegal) moves to it:

nextBoard = doMove(nextBoard, move);

but you should try each move in turn on the original board:

State nextBoard = doMove(board, move);

(Disclaimer: there may be other issues, as well.)

0
seccpur On

1) Don't evaluate each and every nodes within the recursive call, that would be too much time expensive. Evaluate only the leaf nodes.

2) Use boundary condition in the minimax recursive call to terminate if the depth is more than certain value; every branches does not lead to a winning move, and the search will be too big, and the program may hang.

3) Consider using multi-thread on the top level branches to speed up the search.

int alphaBeta(const State board, int alpha, int beta, const Player player, int depth)
{
    std::vector<Move> possibleMoves = getMoves(board);

    if(CheckForWinX(board))
    {
        return 9999;
    }      
    else 
        if(CheckForWinO(board))
    {
        return -9999;
    }   
    else 
        if(possibleMoves.size()==0)
    {
        return 0;
    }     
    else 
        if( depth >= 5)   // without this boundary condition, the search tree will too big 
    { 
        return eval(board);    // evaluate ( which is more time expensive than CheckForWin() ) only the leaf node, not every nodes 
    }
    else{   
        depth++;
        State nextBoard = board;
        int result;

        if(player==Player::O){
              /**/
            return alpha;
        }
        else{
             /**/
            return beta;
        }
    }
}