From feea4b103b515d9fad4929755abd178c3b89d52f Mon Sep 17 00:00:00 2001 From: djib Date: Sun, 25 Jun 2006 13:26:08 +0000 Subject: [PATCH] Version 5.0 =========== Alpha-beta pruning is the only main change. --- src/suicideChess/Board.java | 8 +- src/suicideChess/ComputerPlayer.java | 124 +++++++++++++++++++++++++-- src/suicideChess/SuicideChess.java | 6 +- 3 files changed, 125 insertions(+), 13 deletions(-) diff --git a/src/suicideChess/Board.java b/src/suicideChess/Board.java index 82b5420..49cd5d2 100644 --- a/src/suicideChess/Board.java +++ b/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); diff --git a/src/suicideChess/ComputerPlayer.java b/src/suicideChess/ComputerPlayer.java index 298d3ac..f605b38 100644 --- a/src/suicideChess/ComputerPlayer.java +++ b/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 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 bestMoveIndex=new ArrayList(); + 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= 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; + } + } + } + } \ No newline at end of file diff --git a/src/suicideChess/SuicideChess.java b/src/suicideChess/SuicideChess.java index eeea6ee..5b7e5ee 100644 --- a/src/suicideChess/SuicideChess.java +++ b/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);