From 7dc781c25e7896bf9cc73af373623296d5b7cb7f Mon Sep 17 00:00:00 2001 From: djib Date: Tue, 4 Jul 2006 18:24:40 +0000 Subject: [PATCH] Version 0.9.2 ============= External config file. Move ordering. --- src/suicideChess/Board.java | 8 ++++- src/suicideChess/ComputerPlayer.java | 46 ++++++++++++++++++------ src/suicideChess/MoveComparator.java | 52 ++++++++++++++++++++++++++++ src/suicideChess/OpeningBook.java | 9 ++++- src/suicideChess/SuicideChess.java | 17 ++++++++- 5 files changed, 119 insertions(+), 13 deletions(-) create mode 100644 src/suicideChess/MoveComparator.java diff --git a/src/suicideChess/Board.java b/src/suicideChess/Board.java index 5ca18ca..000b67f 100644 --- a/src/suicideChess/Board.java +++ b/src/suicideChess/Board.java @@ -270,7 +270,7 @@ public class Board { /*================* * PUBLIC METHODS * *================*/ - + /** * This methods takes a {@link Move} and applies it (updating the bitboard) @@ -649,4 +649,10 @@ public class Board { } } + + public int compare(Object arg0, Object arg1) { + // TODO Auto-generated method stub + return 0; + } + } \ No newline at end of file diff --git a/src/suicideChess/ComputerPlayer.java b/src/suicideChess/ComputerPlayer.java index 694194c..45a02a3 100644 --- a/src/suicideChess/ComputerPlayer.java +++ b/src/suicideChess/ComputerPlayer.java @@ -1,6 +1,7 @@ package suicideChess; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.Random; @@ -175,7 +176,8 @@ public class ComputerPlayer { private static Date thinkingBeginingTime; private static int maxDepth; - private static ArrayList bestMoves=new ArrayList(); + private static ArrayList bestMoves=new ArrayList(); + //this class is used to return two arguments in the next function, the two arguments being //an integer representing the value of alpha or beta //an integer representing the real value of the branch (alpha-beta only give boundaries) @@ -194,19 +196,41 @@ public class ComputerPlayer { }; private static ReturnWrapper AlphaBeta(Board bitboard, int currentDepth, int alpha, int beta) throws NotAValidSquare, NoPieceOnSquare { nodesSearched++; + int currentMaxDepth = maxDepth; //this is when intelligent depth is on, the computer may search one step further - if(bitboard.isADraw()) { - return new ReturnWrapper(Board.DRAW_BOARD,Board.DRAW_BOARD,""); + if(!SuicideChess.QUIESCENCE_SEARCH || currentMaxDepth>=SuicideChess.MAX_PLY_DEPTH) { //stop if we are getting to deep + if(bitboard.isADraw()) { + return new ReturnWrapper(Board.DRAW_BOARD,Board.DRAW_BOARD,""); + } + if (currentDepth >= currentMaxDepth) { + //System.out.println("'-> Evaluate: "+bitboard.getBoardValue()); + return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),""); + } } - if (currentDepth >= maxDepth) { - //System.out.println("'-> Evaluate: "+bitboard.getBoardValue()); - return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),""); - } - Rules.legalMovesForPlayer(bitboard); ArrayList allLegalMoves = Rules.getLegalMovesCapture(); if (allLegalMoves.size()==0) { + if(SuicideChess.QUIESCENCE_SEARCH) { + if(bitboard.isADraw()) { + return new ReturnWrapper(Board.DRAW_BOARD,Board.DRAW_BOARD,""); + } + if (currentDepth >= currentMaxDepth) { + //System.out.println("'-> Evaluate: "+bitboard.getBoardValue()); + return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),""); + } + } allLegalMoves = Rules.getLegalMovesNonCapture(); + } else { //if there are captures, see if we can just abandon search here + if (SuicideChess.INTELLIGENT_DEPTH) { + currentMaxDepth++; //go one step further in depth + if(currentDepth==0 && allLegalMoves.size()==1) { + bestMoves.clear(); + bestMoves.add(allLegalMoves.get(0)); + Board boardCopy = new Board(bitboard); + boardCopy.doMove(allLegalMoves.get(0)); + return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),allLegalMoves.get(0).toString()); + } + } } if (allLegalMoves.size()==0) { if (bitboard.getCurrentPlayer()==Piece.BLACK) { @@ -221,7 +245,10 @@ public class ComputerPlayer { int bestScoreSoFar; int currentAlphaBeta; String bestVariationSoFar=""; - if (bitboard.getCurrentPlayer()==Piece.BLACK) { + if (SuicideChess.MOVE_ORDERING) { + Collections.sort(allLegalMoves,new MoveCompare(bitboard)); + } + if (bitboard.getCurrentPlayer()==Piece.BLACK) { bestScoreSoFar=Board.MAX_VALUE; //black tries to minimise for (int i=0; i { + + private Board bitboard; //the bitboard to do the moves from + private int sortOrder; //increasing or decreasing order + + /** + * Constructor + * @param bitboard, the bitboard to do the moves from + * @param order, who is playing (black or white) -> will give the order in which to sort (black minimises and white maximises) + */ + public MoveCompare(Board bitboard) { + this.bitboard = bitboard; + if(this.bitboard.getCurrentPlayer()==Piece.BLACK) { + sortOrder= +1; + } else { + sortOrder= -1; + } + } + + public int compare(Move one, Move another) { + Board oneBoardCopy = new Board(bitboard); + Board anotherBoardCopy = new Board(bitboard); + try { + oneBoardCopy.doMove(one); + anotherBoardCopy.doMove(another); + } catch (NoPieceOnSquare e) { + e.printStackTrace(); + } catch (NotAValidSquare e) { + e.printStackTrace(); + } + if(oneBoardCopy.getBoardValue()>anotherBoardCopy.getBoardValue()) { + return sortOrder; + } else if (oneBoardCopy.getBoardValue()>anotherBoardCopy.getBoardValue()) { + return 0; + } + return -sortOrder; + } +} diff --git a/src/suicideChess/OpeningBook.java b/src/suicideChess/OpeningBook.java index e12d303..8462a09 100644 --- a/src/suicideChess/OpeningBook.java +++ b/src/suicideChess/OpeningBook.java @@ -96,7 +96,14 @@ public class OpeningBook { nbOfMovesThatHaveBeenPlayed++; } - + /** + * Returns a move from the book if available, given a bitboard. + * @param bitboard + * @return + * @throws NotAValidMoveException + * @throws NotAValidSquare + * @throws NoOpeningMovesLeft + */ public static Move getMove(Board bitboard) throws NotAValidMoveException, NotAValidSquare, NoOpeningMovesLeft { ArrayList possibleMoves = new ArrayList(); for (int i=0; i ie: when only one possible move, don't search. When very few moves, add one to depth. + */ + public static final boolean INTELLIGENT_DEPTH = false; + + /** + * Quiescence search -> don't evaluate if captures are possible. + */ + public static final boolean QUIESCENCE_SEARCH = false; + /** * The name to be displayed */ - public static final String NAME = "djib's SuShi v0.8.9"; + public static final String NAME = "djib's SuShi v0.9.2"; /** * Displays informations in the console.