Version 5.1

===========
Corrected bug in alpha-beta.
This commit is contained in:
2006-06-28 16:59:07 +00:00
parent feea4b103b
commit 4dc083acc1
2 changed files with 82 additions and 51 deletions

View File

@ -139,22 +139,43 @@ public class ComputerPlayer {
bestMove = null; bestMove = null;
nodesSearched = 0; nodesSearched = 0;
int bestScore = AlphaBeta(bitboard, 0, Board.BLACK_WINS-1, Board.WHITE_WINS+1); ReturnWrapper bestScore = AlphaBeta(bitboard, 0, Board.BLACK_WINS-1, Board.WHITE_WINS+1);
//select one of the best moves randomly
Random generator = new Random();
//if (currentDepth == 0) { System.out.println(bestMoveIndex.size()); }
bestMove = bestMoves.get(generator.nextInt(bestMoves.size()));
System.out.println("Found "+bestMoves.size()+" good moves.");
if (SuicideChess.postThinkingOutput()) { if (SuicideChess.postThinkingOutput()) {
System.out.println(SuicideChess.PLY_DEPTH+" "+bestScore*100+" 0 "+nodesSearched+" "+bestMove); System.out.println(SuicideChess.PLY_DEPTH+" "+bestScore.getAlphaBeta()*100+" 0 "+nodesSearched+" "+bestMove);
} }
return bestMove; return bestMove;
} }
private static int AlphaBeta(Board bitboard, int currentDepth, int alpha, int beta) throws NotAValidSquare, NoPieceOnSquare { private static ArrayList<Move> bestMoves=new ArrayList<Move>();
if (currentDepth >= SuicideChess.PLY_DEPTH) { //this class is used to return two arguments in the next function, the two arguments being
return bitboard.getBoardValue(); //an integer representing the value of alpha or beta
//an integer representing the real value of the branch (alpha-beta only give boundaries)
private static class ReturnWrapper {
private int alphaBeta;
private int branchValue;
public ReturnWrapper(int alphaBeta, int branchValue) {
this.alphaBeta = alphaBeta;
this.branchValue = branchValue;
}
public int getAlphaBeta() {return this.alphaBeta;}
public int getBranchValue() {return this.branchValue;}
};
private static ReturnWrapper AlphaBeta(Board bitboard, int currentDepth, int alpha, int beta) throws NotAValidSquare, NoPieceOnSquare {
if (currentDepth >= SuicideChess.PLY_DEPTH) {
System.out.println("Evaluate :" + bitboard.getBoardValue());
return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue());
} }
nodesSearched++; nodesSearched++;
//System.out.println(currentDepth + " : " + alpha + " " + beta);
Rules.legalMovesForPlayer(bitboard); Rules.legalMovesForPlayer(bitboard);
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture(); ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
@ -163,74 +184,84 @@ public class ComputerPlayer {
} }
if (allLegalMoves.size()==0) { if (allLegalMoves.size()==0) {
if (bitboard.getCurrentPlayer()==Piece.BLACK) { if (bitboard.getCurrentPlayer()==Piece.BLACK) {
return Board.BLACK_WINS; System.out.println("Evaluate :" + bitboard.getBoardValue());
return new ReturnWrapper(Board.BLACK_WINS,Board.BLACK_WINS);
} else { } else {
return Board.WHITE_WINS; System.out.println("Evaluate :" + bitboard.getBoardValue());
return new ReturnWrapper(Board.WHITE_WINS,Board.BLACK_WINS);
} }
} else { } else {
ArrayList<Integer> bestMoveIndex=new ArrayList<Integer>();
int bestScoreSoFar;
int currentScore; int currentScore;
int bestScoreSoFar;
int currentAlphaBeta;
if (bitboard.getCurrentPlayer()==Piece.BLACK) { if (bitboard.getCurrentPlayer()==Piece.BLACK) {
bestScoreSoFar=Board.WHITE_WINS+1; //any move even a WHITE_WINS will be better than that bestScoreSoFar=Board.WHITE_WINS+1; //any move even a WHITE_WINS will be better than that
for (int i=0; i<allLegalMoves.size(); i++) { for (int i=0; i<allLegalMoves.size(); i++) {
Board boardCopy = new Board(bitboard); Board boardCopy = new Board(bitboard);
System.out.println(currentDepth + ": " + allLegalMoves.get(i));
boardCopy.doMove(allLegalMoves.get(i)); boardCopy.doMove(allLegalMoves.get(i));
currentScore=AlphaBeta(boardCopy,currentDepth+1,alpha,beta); ReturnWrapper returnValue = AlphaBeta(boardCopy,currentDepth+1,alpha,beta);
beta = Math.min(beta,currentScore); currentScore = returnValue.getBranchValue();
if ((currentScore <= bestScoreSoFar)) { //black tries to minimise his score currentAlphaBeta = returnValue.getAlphaBeta();
if (currentScore<bestScoreSoFar) { System.out.println(currentScore + " " + currentAlphaBeta);
bestScoreSoFar = currentScore; //calculating new value of beta
bestMoveIndex.clear(); if (currentAlphaBeta<beta) {
beta = currentAlphaBeta;
if (currentDepth==0) {
bestMoves.clear();
}
}
//calculating branch value
if (currentScore <= bestScoreSoFar) {
if (currentScore < bestScoreSoFar) {
bestScoreSoFar=currentScore;
}
if(currentDepth==0) {
System.out.println("Adding move");
bestMoves.add(allLegalMoves.get(i));
} }
bestMoveIndex.add(i);
} }
//select one of the best moves randomly
Random generator = new Random();
//if (currentDepth == 0) { System.out.println(bestMoveIndex.size()); }
bestMove = allLegalMoves.get(bestMoveIndex.get(generator.nextInt(bestMoveIndex.size())));
//System.out.println(currentDepth + " : " + alpha + " " + beta);
if(beta<=alpha) { if(beta<=alpha) {
return alpha; //pruning System.out.println("pruning");
return new ReturnWrapper(alpha,bestScoreSoFar); //pruning
} }
} }
return beta; return new ReturnWrapper(beta,bestScoreSoFar);
} else { //white piece } else { //white piece
bestScoreSoFar=Board.BLACK_WINS-1; //any move even a BLACK_WINS will be better than that bestScoreSoFar=Board.BLACK_WINS-1; //any move even a BLACK_WINS will be better than that
//alpha, highest score seen so far by Max in minmax
alpha = Board.BLACK_WINS-1;
for (int i=0; i<allLegalMoves.size(); i++) { for (int i=0; i<allLegalMoves.size(); i++) {
Board boardCopy = new Board(bitboard); Board boardCopy = new Board(bitboard);
boardCopy.doMove(allLegalMoves.get(i)); boardCopy.doMove(allLegalMoves.get(i));
currentScore=AlphaBeta(boardCopy,currentDepth+1,alpha,beta); System.out.println(currentDepth + ": " + allLegalMoves.get(i));
alpha = Math.max(alpha,currentScore); ReturnWrapper returnValue = AlphaBeta(boardCopy,currentDepth+1,alpha,beta);
if ((currentScore >= bestScoreSoFar)) { //white tries to maximise his score currentScore = returnValue.getBranchValue();
if (currentScore>bestScoreSoFar) { currentAlphaBeta = returnValue.getAlphaBeta();
bestScoreSoFar = currentScore; System.out.println(currentScore + " " + currentAlphaBeta);
bestMoveIndex.clear(); //calculating new value of beta
if (currentAlphaBeta>alpha) {
alpha = currentAlphaBeta;
if (currentDepth==0) {
bestMoves.clear();
}
}
//calculating branch value
if (currentScore >= bestScoreSoFar) {
if (currentScore > bestScoreSoFar) {
bestScoreSoFar=currentScore;
}
if(currentDepth==0) {
System.out.println("Adding move");
bestMoves.add(allLegalMoves.get(i));
} }
bestMoveIndex.add(i);
} }
//select one of the best moves randomly
Random generator = new Random();
//if (currentDepth == 0) { System.out.println(bestMoveIndex.size()); }
bestMove = allLegalMoves.get(bestMoveIndex.get(generator.nextInt(bestMoveIndex.size())));
//System.out.println(currentDepth + " : " + alpha + " " + beta);
if(alpha>=beta) { if(alpha>=beta) {
return beta; //pruning System.out.println("pruning");
return new ReturnWrapper(beta,bestScoreSoFar); //pruning
} }
} }
return alpha; return new ReturnWrapper(alpha,bestScoreSoFar);
} }
} }
} }

View File

@ -38,12 +38,12 @@ public class SuicideChess {
/** /**
* Displays informations in the console. * Displays informations in the console.
*/ */
public static final boolean ASCII_GAME = false; public static final boolean ASCII_GAME = true;
/** /**
* Number of Plies the computes searches to * Number of Plies the computes searches to
*/ */
public static final int PLY_DEPTH = 6; public static final int PLY_DEPTH = 2;
/** /**
* Test and display if the board is in a winning state. * Test and display if the board is in a winning state.