Andy Chen
Andy Chen

Reputation: 1

Alpha Beta pruning does not seem to improve my chess minimax performance

import java.util.ArrayList;
import java.util.HashMap;

public class MiniMax {
    public static final int SUGGESTIVE_MAX_DEPTH = 10;
    public static int counter;
    //AI (white), depth>0
    public static int[]  getComputerMove(Board b, int depth) {
        ArrayList<ArrayList<Integer>> coloredMoves = b.getAllMoves(true);
        int[] currentMove = new int[4];
        int max = Integer.MIN_VALUE;
        int[] bestMove = new int[4];
        for (int k = 0; k < coloredMoves.size(); k++) {
            ArrayList<Integer> a = coloredMoves.get(k);
            for (int i = 2; i < a.size() - 1; i += 2) {
                currentMove[0] = a.get(0);
                currentMove[1] = a.get(1);
                currentMove[2] = a.get(i);
                currentMove[3] = a.get(i + 1);
                int moveSetValue = min(b.simulateMove(currentMove), depth - 1, max, Integer.MAX_VALUE);
                if (moveSetValue > max) {
                    max = moveSetValue;
                    bestMove = currentMove.clone();
                }
            }

        }
        System.out.println(counter);return bestMove; 
    }
    //maximizer (white)
    private static int max(Board b, int depth, int alpha, int beta) {
        if (depth == 0 || Math.abs(b.getSum()) > 999990) { counter++; 
            return b.getSum(); 
        }
        ArrayList<ArrayList<Integer>> coloredMoves = b.getAllMoves(true);
        for (int k = 0; k < coloredMoves.size(); k++) {
            ArrayList<Integer> a = coloredMoves.get(k);
            for (int i = 2; i < a.size() - 1; i += 2) {
                int[] moveSet = new int[4];
                moveSet[0] = a.get(0);
                moveSet[1] = a.get(1);
                moveSet[2] = a.get(i);
                moveSet[3] = a.get(i + 1);
                int moveValue = min(b.simulateMove(moveSet), depth - 1, alpha, beta);
                alpha = (int) Math.max(alpha, moveValue);
                if (alpha >= beta) {
                    return alpha;
                }

            }
        }
        return alpha;
    }
    //minimizer (black)
    private static int min(Board b, int depth, int alpha, int beta) {
        if (depth == 0 || Math.abs(b.getSum()) > 999990) {
            counter++; return b.getSum();
        }
        ArrayList<ArrayList<Integer>> coloredMoves = b.getAllMoves(false);
        for (int k = 0; k < coloredMoves.size(); k++) {
            ArrayList<Integer> a = coloredMoves.get(k);
            for (int i = 0; i < a.size() - 1; i += 2) {
                int[] moveSet = new int[4];
                moveSet[0] = a.get(0);
                moveSet[1] = a.get(1);
                moveSet[2] = a.get(i);
                moveSet[3] = a.get(i + 1);
                int moveValue = max(b.simulateMove(moveSet), depth - 1, alpha, beta);
                beta = (int) Math.min(beta, moveValue);
                if (alpha >= beta) {
                    return beta;
                }
            }
        }
        return beta;
    }
}

I imported HashMap but never actually used it so I have no transposition table here. My implementation of minimax seems to be really slow. I do indeed have an evaluation function that adds or removes value based on the position of every piece so there shouldn't be many board states that have the same value. That being said, my counter variable goes up to the millions when it should stop at ~27000 at depth 6. I think I implemented alpha beta pruning properly with fail hard. I don't think there has been a noticeable improvement in performance after I did however.

Some explanation:

coloredMoves gets every possible chess move. a move is defined as a coordinate position of the moving piece and the coordinates of the location.

EDIT: Depth here means every individual move. Could I possibly be overestimating the performance of alpha beta pruning with minimax? Online shows that it should at least be 6. My algorithm only runs at a realistic time at a depth of 4 which is quite pathetic.

Upvotes: 0

Views: 727

Answers (1)

TheSlater
TheSlater

Reputation: 660

I cannot find any errors in your source code. The speed gain of alpha beta is highly dependent on the order in which the moves are tried. If your move generator e.g. adds the pawn moves first from left to right then the cutoff will be very late. If you implement a good move sorting function then the move count should at least fall to the root of the minimax number.

There are multiple techniques for sorting chess moves. To sort the moves at the root you can use the "iterative deepening". After that the history heuristic and killer heuristic help to sort moves in the game tree.

An improvement additionally to your question can be to shift the

moveSet[0] = a.get(0);
moveSet[1] = a.get(1);

to the front of it's for-loop, if the array is not changed in the simulateMove function.

Upvotes: 0

Related Questions