Browse Source

Version 1.0.1

=============
Couple of minor changes
master
djib 15 years ago
parent
commit
399985789e
  1. 36
      src/suicideChess/Board.java
  2. 71
      src/suicideChess/ComputerPlayer.java
  3. 2
      src/suicideChess/OpeningBook.java
  4. 6
      src/suicideChess/SuicideChess.java

36
src/suicideChess/Board.java

@ -188,7 +188,6 @@ public class Board {
/**
* This constructor is used to create a board with a string in FEN notation
* @param command A string representing the command
* @return A {@link Board} corresponding to the FEN string
* @throws NotAValidSquare
* @throws UnableToParseFENStringException
* @see Board
@ -571,7 +570,7 @@ public class Board {
}
//calculates player's mobility in the endgame
private int mobilityEnd(int colour) throws NotAValidSquare {
private int mobilityEndgame(int colour) throws NotAValidSquare {
Board thisCopy = new Board(this);
thisCopy.currentPlayer=colour;
Rules.legalMovesForPlayer(thisCopy);
@ -584,7 +583,7 @@ public class Board {
}
//calculates player's mobility in the midgame
public int mobilityMiddle(int colour) throws NotAValidSquare {
private int mobilityMidgame(int colour) throws NotAValidSquare {
Board thisCopy = new Board(this);
thisCopy.currentPlayer=colour;
Rules.legalMovesForPlayer(thisCopy);
@ -608,35 +607,35 @@ public class Board {
//this is a very very basic evaluation function that will be changed.
//boardValue = numberOfBlackPieces - numberOfWhitePieces;
boardValue = 0;
if((numberOfPieces[Piece.BLACK_PAWN] <= ConfigFile.getEndGamePawns()) || (numberOfPieces[Piece.WHITE_PAWN] <= ConfigFile.getEndGamePawns())
|| (numberOfPieces[Piece.BLACK_PIECES] <= ConfigFile.getEndGamePieces()) || (numberOfPieces[Piece.WHITE_PIECES] <= ConfigFile.getEndGamePieces()) ) {
//System.out.println("Playing endgame");
if((numberOfPieces[Piece.BLACK_PAWN] > ConfigFile.getEndGamePawns()) && (numberOfPieces[Piece.WHITE_PAWN] > ConfigFile.getEndGamePawns())
&& (numberOfPieces[Piece.BLACK_PIECES] > ConfigFile.getEndGamePieces()) && (numberOfPieces[Piece.WHITE_PIECES] > ConfigFile.getEndGamePieces()) ) {
//System.out.println("Playing midgame");
/*for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_ENDGAME[i];
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_MIDGAME[i];
}*/
for(int squareNb = 0; squareNb<NB_OF_SQUARES; squareNb++) {
Piece pieceOnSquare = getPiece(new Square(squareNb));
if(pieceOnSquare.getPieceNumber()!=Piece.NONE) {
//System.out.println(SQUARE_WEIGHT[squareNb]);
boardValue += ConfigFile.getSquareWeightEndgame()[squareNb]*
ConfigFile.getPieceValuesEndgame()[pieceOnSquare.getPieceNumber()];
boardValue += ConfigFile.getSquareWeightMidgame()[squareNb]*
ConfigFile.getPieceValuesMidgame()[pieceOnSquare.getPieceNumber()];
}
}
boardValue += ((mobilityEnd(Piece.WHITE)-mobilityEnd(Piece.BLACK)));
boardValue += ((mobilityMidgame(Piece.WHITE)-mobilityMidgame(Piece.BLACK)));
} else {
//System.out.println("Playing midgame");
//System.out.println("Playing endgame");
/*for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_MIDDLEGAME[i];
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_ENDGAME[i];
}*/
for(int squareNb = 0; squareNb<NB_OF_SQUARES; squareNb++) {
Piece pieceOnSquare = getPiece(new Square(squareNb));
if(pieceOnSquare.getPieceNumber()!=Piece.NONE) {
//System.out.println(SQUARE_WEIGHT[squareNb]);
boardValue += ConfigFile.getSquareWeightMidgame()[squareNb]*
ConfigFile.getPieceValuesMidgame()[pieceOnSquare.getPieceNumber()];
boardValue += ConfigFile.getSquareWeightEndgame()[squareNb]*
ConfigFile.getPieceValuesEndgame()[pieceOnSquare.getPieceNumber()];
}
}
boardValue += ((mobilityMiddle(Piece.WHITE)-mobilityMiddle(Piece.BLACK)));
boardValue += ((mobilityEndgame(Piece.WHITE)-mobilityEndgame(Piece.BLACK)));
}
}
}
@ -648,11 +647,4 @@ public class Board {
}
}
}
public int compare(Object arg0, Object arg1) {
// TODO Auto-generated method stub
return 0;
}
}

71
src/suicideChess/ComputerPlayer.java

@ -128,7 +128,20 @@ public class ComputerPlayer {
return bestScoreSoFar;
}
}
//variables used in aplha beta pruning
private static boolean quiescenceSearch; //this will be used to determine is quiescence search is needed.
private static boolean adaptativeDepth; //this will
private static String extraSymbol=""; //display an extra symbol after the depth in the output if doing either quiescence search or adaptative depth
private static Date thinkingBeginingTime;
private static int maxDepth;
private static ArrayList<Move> bestMoves=new ArrayList<Move>();
//private static Move[] killerMoves = new Move[SuicideChess.KILLER_SIZE]; //killer
private static Move[] principalVariation;
/**
* Alpha-Beta
* @param bitboard The bitboard
@ -145,6 +158,7 @@ public class ComputerPlayer {
thinkingBeginingTime = new Date();
quiescenceSearch = false;
adaptativeDepth = false;
extraSymbol = "";
principalVariation=new Move[0];
@ -153,15 +167,18 @@ public class ComputerPlayer {
if(maxDepth==SuicideChess.getPlyDepth()) {
if(SuicideChess.QUIESCENCE_SEARCH) {
quiescenceSearch = true; //don't do quiescence search till the last level of iterative deepening
extraSymbol = "+";
extraSymbol = "+"; //display extra symbol in the thinking output
}
if(SuicideChess.ADAPTATIVE_DEPTH) {
adaptativeDepth = true; //don't do adaptative search till the last level of iterative deepening
extraSymbol = "+";
extraSymbol = "+"; //display extra symbol in the thinking output
}
}
//alpha beta pruning.
ReturnWrapper bestScore = AlphaBeta(bitboard, 0, SuicideChess.PRINCIPAL_VARIATION_FIRST
, maxDepth, Board.MIN_VALUE, Board.MAX_VALUE);
Date thinkingEndTime = new Date();
//select one of the best moves randomly
@ -170,12 +187,12 @@ public class ComputerPlayer {
bestMove = bestMoves.get(generator.nextInt(bestMoves.size()));
if (SuicideChess.postThinkingOutput()) {
System.out.println(maxDepth+extraSymbol+"\t"+bestScore.getBranchValue()+
"\t"+((int)(thinkingEndTime.getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
"\t"+nodesSearched+"\t"+bestScore.getPrincipalVariation());
}
//if found a win for black or white.
if((bitboard.getCurrentPlayer()==Piece.BLACK
&& bestScore.getBranchValue()==Board.BLACK_WINS)
|| (bitboard.getCurrentPlayer()==Piece.WHITE
@ -184,17 +201,21 @@ public class ComputerPlayer {
}
if(SuicideChess.PRINCIPAL_VARIATION_FIRST) {
//parsing the principal variation to be able to analyse it first
String principalVariationString[] = bestScore.getPrincipalVariation().split("\\s");
principalVariation = new Move[principalVariationString.length];
Board playing; //need to update bitboard to be able to generate moves
playing = new Board(bitboard);
for (int i = 0; i < principalVariationString.length; i++) {
//playing.display();
//System.out.println(principalVariationString[i]);
principalVariation[i] = new Move(principalVariationString[i],playing);
playing.doMove(principalVariation[i]);
}
}
}
if(SuicideChess.playInACSII()) {
System.out.println("Found "+bestMoves.size()+" good moves.");
}
@ -203,16 +224,6 @@ public class ComputerPlayer {
}
private static boolean quiescenceSearch; //this will be used to determine is quiescence search is needed.
private static boolean adaptativeDepth; //this will
private static String extraSymbol=""; //display an extra symbol after the depth in the output if doing either quiescence search or adaptative depth
private static Date thinkingBeginingTime;
private static int maxDepth;
private static ArrayList<Move> bestMoves=new ArrayList<Move>();
//private static Move[] killerMoves = new Move[SuicideChess.KILLER_SIZE]; //killer
private static Move[] principalVariation;
//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)
@ -229,8 +240,11 @@ public class ComputerPlayer {
public int getBranchValue() {return this.branchValue;}
public String getPrincipalVariation() {return this.principalVariation;}
};
//Alpha beta.
private static ReturnWrapper AlphaBeta(Board bitboard, int currentDepth, boolean inPrincipalVariation, int currentMaxDepth, int alpha, int beta) throws NotAValidSquare, NoPieceOnSquare {
nodesSearched++;
if(bitboard.isADraw()) {
return new ReturnWrapper(Board.DRAW_BOARD,Board.DRAW_BOARD,"");
}
@ -239,25 +253,27 @@ public class ComputerPlayer {
//System.out.println("'-> Evaluate: "+bitboard.getBoardValue());
return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),"");
}
//generate legal moves.
Rules.legalMovesForPlayer(bitboard);
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
if (allLegalMoves.size()==0) {
if (allLegalMoves.size()==0) { //if no capture moves
if((quiescenceSearch) && (currentDepth >= currentMaxDepth)) {
//System.out.println("'-> Evaluate: "+bitboard.getBoardValue());
return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),"");
return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),""); //position is quiet
}
allLegalMoves = Rules.getLegalMovesNonCapture();
} else { //if there are captures, see if we can just abandon search here
} else {
boolean changedMaxDepth = false; //to make sure that quiescence and adaptative don't interfere
if((quiescenceSearch) && (currentDepth >= currentMaxDepth)) {
if((currentMaxDepth<SuicideChess.MAX_QUIESCENCE_DEPTH) && (allLegalMoves.size()<=SuicideChess.QUIESCENCE_LIMIT)) {
currentMaxDepth++;
currentMaxDepth++; //seek a quiet position
changedMaxDepth = true;
} else {
return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),"");
}
}
if (adaptativeDepth) {
if (adaptativeDepth) {//if there are captures, see if we can just abandon search here or go further
if(currentDepth==0 && allLegalMoves.size()==1) {
bestMoves.clear();
bestMoves.add(allLegalMoves.get(0));
@ -269,7 +285,7 @@ public class ComputerPlayer {
currentMaxDepth++; //go one step further in depth
}
}
if (allLegalMoves.size()==0) {
if (allLegalMoves.size()==0) { //if no moves at all
if (bitboard.getCurrentPlayer()==Piece.BLACK) {
//System.out.println("'-> Evaluate *BLACK WINS*: "+Board.BLACK_WINS);
return new ReturnWrapper(Board.BLACK_WINS,Board.BLACK_WINS,"");
@ -295,22 +311,24 @@ public class ComputerPlayer {
continue;
} else {
boardCopy.doMove(principalVariation[currentDepth]);
//System.out.println(i+"bdoingMove"+currentDepth+" "+principalVariation[currentDepth]);
returnValue = AlphaBeta(boardCopy,currentDepth+1,true,currentMaxDepth,Board.MIN_VALUE,beta);
}
} else { //and then don't do it again.
if(SuicideChess.PRINCIPAL_VARIATION_FIRST && (principalVariation.length > currentDepth)) {
if(inPrincipalVariation && (principalVariation.length > currentDepth)) {
if(principalVariation[currentDepth].isSimpleEqualTo(allLegalMoves.get(i))) {
continue;
}
}
boardCopy.doMove(allLegalMoves.get(i));
//System.out.println(i+"bdoingMove"+currentDepth+" "+allLegalMoves.get(i));
returnValue = AlphaBeta(boardCopy,currentDepth+1,false,currentMaxDepth,Board.MIN_VALUE,beta);
}
//System.out.println("Analysing "+currentDepth+":"+allLegalMoves.get(i));
currentScore = returnValue.getBranchValue();
//if(currentDepth==0 || currentDepth==1) System.out.println(returnValue.getPrincipalVariation()+" "+currentScore);
currentAlphaBeta = returnValue.getAlphaBeta();
//System.out.println("| CurrentScore, BestScore:" + currentScore + ", " + bestScoreSoFar);
@ -324,6 +342,7 @@ public class ComputerPlayer {
if (currentScore <= bestScoreSoFar) {
if (currentScore < bestScoreSoFar) {
bestScoreSoFar=currentScore;
//System.out.println(i+" "+currentScore+" "+bestScoreSoFar);
if (i!=-1) {
bestVariationSoFar = allLegalMoves.get(i).toString()+" "+returnValue.getPrincipalVariation();
} else {
@ -373,22 +392,24 @@ public class ComputerPlayer {
continue;
} else {
boardCopy.doMove(principalVariation[currentDepth]);
//System.out.println(i+"wdoingMove"+currentDepth+" "+principalVariation[currentDepth]);
returnValue = AlphaBeta(boardCopy,currentDepth+1,true,currentMaxDepth,alpha,Board.MAX_VALUE);
}
} else { //and then don't do it again.
if(SuicideChess.PRINCIPAL_VARIATION_FIRST && (principalVariation.length > currentDepth)) {
if(inPrincipalVariation && (principalVariation.length > currentDepth)) {
if(principalVariation[currentDepth].isSimpleEqualTo(allLegalMoves.get(i))) {
continue;
}
}
boardCopy.doMove(allLegalMoves.get(i));
//System.out.println(i+"wdoingMove"+currentDepth+" "+allLegalMoves.get(i)+" "+nodesSearched);
returnValue = AlphaBeta(boardCopy,currentDepth+1,false,currentMaxDepth,alpha,Board.MAX_VALUE);
}
//System.out.println("Analysing "+currentDepth+":"+allLegalMoves.get(i));
currentScore = returnValue.getBranchValue();
//if(currentDepth==0 || currentDepth==1) System.out.println(returnValue.getPrincipalVariation()+" "+currentScore);
currentAlphaBeta = returnValue.getAlphaBeta();
//System.out.println("| CurrentScore, BestScore:" + currentScore + ", " + bestScoreSoFar);
@ -399,9 +420,11 @@ public class ComputerPlayer {
alpha = currentAlphaBeta;
}
//calculating branch value
if (currentScore >= bestScoreSoFar) {
if (currentScore > bestScoreSoFar) {
bestScoreSoFar=currentScore;
//System.out.println(i+" "+currentScore+" "+bestScoreSoFar);
if (i!=-1) {
bestVariationSoFar = allLegalMoves.get(i).toString()+" "+returnValue.getPrincipalVariation();
} else {

2
src/suicideChess/OpeningBook.java

@ -99,7 +99,7 @@ public class OpeningBook {
/**
* Returns a move from the book if available, given a bitboard.
* @param bitboard
* @return
* @return A Move
* @throws NotAValidMoveException
* @throws NotAValidSquare
* @throws NoOpeningMovesLeft

6
src/suicideChess/SuicideChess.java

@ -58,7 +58,7 @@ public class SuicideChess {
/**
* Quiescence search -> don't evaluate if captures are possible.
*/
public static final boolean QUIESCENCE_SEARCH = true;
public static final boolean QUIESCENCE_SEARCH = false;
/**
* Quiescence limit (ie. if more than that many possibilities of capturing, don't analyse further.
@ -79,7 +79,7 @@ public class SuicideChess {
/**
* Adaptative branchin limit
*/
public static final int ADAPTATIVE_BRANCHING_LIMIT = 3;
public static final int ADAPTATIVE_BRANCHING_LIMIT = 2;
///**
// * Killer size (nb of killer moves remembered)
@ -94,7 +94,7 @@ public class SuicideChess {
/**
* The name to be displayed
*/
public static final String NAME = "djib's SuShi v0.9.2";
public static final String NAME = "djib's SuShi v1.0.0";
/**
* Displays informations in the console.

Loading…
Cancel
Save