I am using PVS and have found a with Problem with my PVS-Search.
I wanted to test PVS (without Transposition tables or any other pruning that could effect the PV) on some testPositions to see wheter i always get the full Principal-Variation. Turns out that this wasnt the case. I would get the full Principal Variation almost all of the time but it sometimes happend that I got a short PV.
Here is my implementation of PVS:
Code: Select all
public static int principal(CheckerBoard board, int alpha, int beta, int depth, int ply, PVLine cLine, boolean inPVLine, long endingTime) {
final boolean silentPosition =board.isSilentPosition();
if (depth <= 0 || board.isTerminalState() || (endingTime - System.currentTimeMillis()) <= 0) {
return quiesceneSearch2(board, alpha, beta, endingTime);
}
final int sideToMove = (board.color == -1) ? 0 : 1;
final ArrayList<Move> sucessors = MGenerator.getMoves(board);
int bestScore = -10000000;
final PVLine localPV = new PVLine(depth);
final int size=sucessors.size();
Move currentBest = null;
if (size >= 1) {
board.makeMove(sucessors.get(0));
bestScore = -principal(board, -beta, -alpha, depth -1, ply+1, localPV, inPVLine, endingTime);
board.undoMove(sucessors.get(0));
if (bestScore > alpha) {
currentBest = sucessors.get(0);
if (bestScore >= beta) {
if (silentPosition) {
killer[1][ply] = killer[0][ply];
killer[0][ply] = sucessors.get(0);
history[sideToMove][sucessors.get(0).getFrom()][sucessors.get(0).getTo()] += depth * depth;
}
return bestScore;
} else {
history[sideToMove][sucessors.get(0).getFrom()][sucessors.get(0).getTo()] -= depth ;
}
alpha = bestScore;
cLine.line[0] = sucessors.get(0);
for (int p = 1; p <localPV.line.length; p++) {
cLine.line[p] = localPV.line[p - 1];
}
}
}
for (int i = 1; i < size; i++) {
board.makeMove(sucessors.get(i));
int score = -principal(board, -alpha - 1, -alpha, depth - 1, ply + 1, localPV, false, endingTime);
if (score > alpha && score < beta) {
score = -principal(board, -beta, -alpha, depth - 1, ply+1, localPV, false, endingTime);
if (score > alpha) {
alpha = score;
}
}
board.undoMove(sucessors.get(i));
if (score > bestScore) {
currentBest = sucessors.get(i);
bestScore = score;
if (score >= beta) {
if (silentPosition) {
killer[1][ply] = killer[0][ply];
killer[0][ply] = sucessors.get(i);
history[sideToMove][sucessors.get(i).getFrom()][sucessors.get(i).getTo()] += depth*depth ;
}
break;
} else {
history[sideToMove][sucessors.get(i).getFrom()][sucessors.get(i).getTo()] -= depth ;
}
cLine.line[0] = sucessors.get(i);
for (int p = 1; p <localPV.line.length; p++) {
cLine.line[p] = localPV.line[p - 1];
}
}
}
return bestScore;
}