private int minmax(Color p, Board b, int d, int cutoff,
            ArrayList<Integer> moves) {
        bestSoFar = Integer.MIN_VALUE;
        moves.clear();
        if (d == 0) {
            return staticEval(p, b);
        }
        for (int move = 0; move < b.size() * b.size(); move += 1) {
            if (b.isLegal(p, move)) {
                b.addSpot(p, move);
                if (b.getWinner() != null) {
                    response = Integer.MAX_VALUE;
                } else {
                    response = minmax(p.opposite(), b, d - 1, -bestSoFar,
                                       new ArrayList<Integer>());
                }
                b.undo();
                if (move > cutoff) {
                    moves.clear();
                    return response;
                }
                if (-response >= bestSoFar) {
                    moves.clear();
                    if (-response == bestSoFar) {
                        moves.add(move);
                        bestSoFar = -response;
                    }
                }
            }
        }
        return bestSoFar;
    }