Browse Source

Version 5.0

===========
Alpha-beta pruning is the only main change.
master
djib 16 years ago
parent
commit
feea4b103b
  1. 8
      src/suicideChess/Board.java
  2. 124
      src/suicideChess/ComputerPlayer.java
  3. 6
      src/suicideChess/SuicideChess.java

8
src/suicideChess/Board.java

@ -264,12 +264,12 @@ public class Board {
if(currentPlayer==Piece.WHITE) {
currentPlayer=Piece.BLACK;
if (SuicideChess.ASCII_GAME)
System.out.println("Black: ");
//if (SuicideChess.ASCII_GAME)
// System.out.println("Black: ");
} else {
currentPlayer=Piece.WHITE;
if (SuicideChess.ASCII_GAME)
System.out.println("White: ");
//if (SuicideChess.ASCII_GAME)
// System.out.println("White: ");
}
evaluateNewBoardValue(move);

124
src/suicideChess/ComputerPlayer.java

@ -14,12 +14,16 @@ import suicideChess.Square.NotAValidSquare;
public class ComputerPlayer {
//best move found
private static Move bestMove = null;
//to tell the number of nodes searched
private static int nodesSearched;
/**
* This asks the computer to compute a move
* @param bitboard The current status of the {@link Board}
* @param color The color to play
* @return move A {@link Move}
* @throws NotAValidSquare
* @see Board
@ -43,7 +47,6 @@ public class ComputerPlayer {
/**
* Basic MinMax
* @param bitboard The bitboard
* @param color The color to play
* @return The best Move found
* @throws NotAValidSquare
* @throws NoPieceOnSquare
@ -53,6 +56,7 @@ public class ComputerPlayer {
public static Move doMinMaxMove(Board bitboard) throws NotAValidSquare, NoPieceOnSquare {
bestMove = null;
nodesSearched = 0;
int bestScore = MinMax(bitboard, 0);
if (SuicideChess.postThinkingOutput()) {
System.out.println(SuicideChess.PLY_DEPTH+" "+bestScore*100+" 0 "+nodesSearched+" "+bestMove);
@ -115,12 +119,120 @@ public class ComputerPlayer {
//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())));
return bestScoreSoFar;
}
}
/**
* Alpha-Beta
* @param bitboard The bitboard
* @return The best Move found
* @throws NotAValidSquare
* @throws NoPieceOnSquare
* @see Board
* @see Move
*/
public static Move doAlphaBetaMove(Board bitboard) throws NotAValidSquare, NoPieceOnSquare {
bestMove = null;
nodesSearched = 0;
int bestScore = AlphaBeta(bitboard, 0, Board.BLACK_WINS-1, Board.WHITE_WINS+1);
if (SuicideChess.postThinkingOutput()) {
System.out.println(SuicideChess.PLY_DEPTH+" "+bestScore*100+" 0 "+nodesSearched+" "+bestMove);
}
return bestMove;
}
private static Move bestMove = null;
private static int nodesSearched;
private static int AlphaBeta(Board bitboard, int currentDepth, int alpha, int beta) throws NotAValidSquare, NoPieceOnSquare {
if (currentDepth >= SuicideChess.PLY_DEPTH) {
return bitboard.getBoardValue();
}
nodesSearched++;
//System.out.println(currentDepth + " : " + alpha + " " + beta);
Rules.legalMovesForPlayer(bitboard);
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
if (allLegalMoves.size()==0) {
allLegalMoves = Rules.getLegalMovesNonCapture();
}
if (allLegalMoves.size()==0) {
if (bitboard.getCurrentPlayer()==Piece.BLACK) {
return Board.BLACK_WINS;
} else {
return Board.WHITE_WINS;
}
} else {
ArrayList<Integer> bestMoveIndex=new ArrayList<Integer>();
int bestScoreSoFar;
int currentScore;
if (bitboard.getCurrentPlayer()==Piece.BLACK) {
bestScoreSoFar=Board.WHITE_WINS+1; //any move even a WHITE_WINS will be better than that
for (int i=0; i<allLegalMoves.size(); i++) {
Board boardCopy = new Board(bitboard);
boardCopy.doMove(allLegalMoves.get(i));
currentScore=AlphaBeta(boardCopy,currentDepth+1,alpha,beta);
beta = Math.min(beta,currentScore);
if ((currentScore <= bestScoreSoFar)) { //black tries to minimise his score
if (currentScore<bestScoreSoFar) {
bestScoreSoFar = currentScore;
bestMoveIndex.clear();
}
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) {
return alpha; //pruning
}
}
return beta;
} else { //white piece
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++) {
Board boardCopy = new Board(bitboard);
boardCopy.doMove(allLegalMoves.get(i));
currentScore=AlphaBeta(boardCopy,currentDepth+1,alpha,beta);
alpha = Math.max(alpha,currentScore);
if ((currentScore >= bestScoreSoFar)) { //white tries to maximise his score
if (currentScore>bestScoreSoFar) {
bestScoreSoFar = currentScore;
bestMoveIndex.clear();
}
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) {
return beta; //pruning
}
}
return alpha;
}
}
}
}

6
src/suicideChess/SuicideChess.java

@ -33,7 +33,7 @@ public class SuicideChess {
/**
* The name to be displayed
*/
public static final String NAME = "djib's SuShi (Suicide Chess) v0.4.3";
public static final String NAME = "djib's SuShi (Suicide Chess) v0.5";
/**
* Displays informations in the console.
@ -43,7 +43,7 @@ public class SuicideChess {
/**
* Number of Plies the computes searches to
*/
public static final int PLY_DEPTH = 4;
public static final int PLY_DEPTH = 6;
/**
* Test and display if the board is in a winning state.
@ -276,7 +276,7 @@ public class SuicideChess {
}
if (computerPlaying) {
Move computerMove = ComputerPlayer.doMinMaxMove(bitboard);
Move computerMove = ComputerPlayer.doAlphaBetaMove(bitboard);
bitboard.doMove(computerMove);
addPlayedPosition(bitboard);
XBoardProtocol.doMove(computerMove);

Loading…
Cancel
Save