1

I'm struggling to get this code working, there is a problem somewhere but I can't understand where.

I'm developing a simple AI for a generalized TicTacToe and I would like to use negamax instead of MiniMax, with alpha-beta pruning.

The problem is that the algorithm works fine if I don't prune at the end, but as soon as I uncomment the pruning it stops working.

This is the main cicle where I call the minimax algorithm:

//Cycle through all possible cells
    for(MNKCell d : FC) {

        B.markCell(d.i, d.j);

        //Apply minimax algorithm on the cell
        Integer MoveVal = -negaMax(-1, Integer.MAX_VALUE, Integer.MIN_VALUE);

        B.unmarkCell();

        //DEBUG
        Debug.PrintMiddleCicle(B, d, MoveVal);

        //Check if found a better move
        if(MoveVal > MaxMoveValue){
            MaxMoveValue = MoveVal;
            BestMove = d;
        }

    }

This is the algorithm:

public Integer negaMax(int sign, int alpha, int beta){

    //Base case, evaluation detected gameover or timeout soon
    if(B.gameState() != MNKGameState.OPEN || utility.isTimeExpiring())// || depth == 0)
    {
        return utility.evaluateBoard(B,0)*sign;
    }

        //Relax technique, assume the worst case scenario and relax on each step
        Integer bestValue = Integer.MIN_VALUE;

        //Cycle through all possible moves
        MNKCell FC[] = B.getFreeCells();
        for(MNKCell current : FC) {

            //Mark this cell as player move
            B.markCell(current.i, current.j);

            //Recursively call minmax on this board scenario
            bestValue = Math.max(bestValue, -negaMax(-sign, -alpha, -beta));
            alpha = Math.max(alpha, bestValue);

            //Revert move 
            B.unmarkCell();
    
            //if(alpha >= beta)
            //  break;
        }

        //Return the best value obtained
        return bestValue;
}

I know that there is a problem because I implemented a function that outputs the best possible evaluation for each cell (PrintMiddleCicle in the main cicle), these are the outputs with pruning off in a 3x3 game:

Pruning off

And these are the outputs with pruning on:

Pruning on

I know the first one is correct because with an empty table in a 3x3 game, assuming both players with perfect strategy, every cell should point to a draw (evaluation=0)

  • Are you sure that it works correctly without pruning, more than checking just the starting position? You should make sure that your evaluation function is correct and that it plays correctly with normal negamax. Alpha/beta pruning should be super easy to implement after you get everything else to work, it is basically 2-3 lines of code, and it looks to me like you wrote them correctly, given the "template" from e.g. Wikipedia. – eligolf Sep 17 '22 at 06:13

0 Answers0