Version 1.0.1
============= Couple of minor changes
This commit is contained in:
@ -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,8 +607,22 @@ 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()) ) {
|
||||
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_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.getSquareWeightMidgame()[squareNb]*
|
||||
ConfigFile.getPieceValuesMidgame()[pieceOnSquare.getPieceNumber()];
|
||||
}
|
||||
}
|
||||
boardValue += ((mobilityMidgame(Piece.WHITE)-mobilityMidgame(Piece.BLACK)));
|
||||
} else {
|
||||
//System.out.println("Playing endgame");
|
||||
/*for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
|
||||
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_ENDGAME[i];
|
||||
@ -622,21 +635,7 @@ public class Board {
|
||||
ConfigFile.getPieceValuesEndgame()[pieceOnSquare.getPieceNumber()];
|
||||
}
|
||||
}
|
||||
boardValue += ((mobilityEnd(Piece.WHITE)-mobilityEnd(Piece.BLACK)));
|
||||
} else {
|
||||
//System.out.println("Playing midgame");
|
||||
/*for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
|
||||
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_MIDDLEGAME[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 += ((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;
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Reference in New Issue
Block a user