Version 7.0

===========
Corrected a few bugs from 6.9, like the principal variation.
About to add opening book.
This commit is contained in:
2006-07-02 13:51:14 +00:00
parent 1b500b4421
commit b02755be4e
6 changed files with 183 additions and 80 deletions

View File

@ -71,6 +71,15 @@ public class Board {
*/ */
public static final int DRAW_BOARD = 0; public static final int DRAW_BOARD = 0;
/**
* Importance of real mobility in position evaluation (ie. how many moves can one make compared to the other)
*/
public static final int REAL_MOBILITY_VALUE = 10;
/**
* Importance of relative mobility (mobility of other pieces that may not be able to play because of a compulsory move)
*/
public static final int RELATIVE_MOBILITY_VALUE = 5;
/*======* /*======*
* DATA * * DATA *
*======*/ *======*/
@ -314,13 +323,9 @@ public class Board {
if(currentPlayer==Piece.WHITE) { if(currentPlayer==Piece.WHITE) {
currentPlayer=Piece.BLACK; currentPlayer=Piece.BLACK;
//if (SuicideChess.ASCII_GAME)
// System.out.println("Black: ");
} else { } else {
fullmoveNumber++; //black has just played fullmoveNumber++; //black has just played
currentPlayer=Piece.WHITE; currentPlayer=Piece.WHITE;
//if (SuicideChess.ASCII_GAME)
// System.out.println("White: ");
} }
evaluateNewBoardValue(move); evaluateNewBoardValue(move);
@ -581,6 +586,19 @@ public class Board {
} }
} }
//calculates player's mobility
public int mobility(int colour) throws NotAValidSquare {
Board thisCopy = new Board(this);
thisCopy.currentPlayer=colour;
Rules.legalMovesForPlayer(thisCopy);
if (Rules.getLegalMovesCapture().size()!=0) {
return Rules.getLegalMovesCapture().size()*REAL_MOBILITY_VALUE
+Rules.getLegalMovesNonCapture().size()*RELATIVE_MOBILITY_VALUE;
} else {
return Rules.getLegalMovesNonCapture().size()*REAL_MOBILITY_VALUE;
}
}
private void evaluateNewBoardValue (Move move) throws NotAValidSquare { private void evaluateNewBoardValue (Move move) throws NotAValidSquare {
if (move.isCaptureMove()) { if (move.isCaptureMove()) {
@ -603,6 +621,7 @@ public class Board {
for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) { 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_MIDDLEGAME[i];
} }
boardValue += ((mobility(Piece.WHITE)-mobility(Piece.BLACK)));
} }
} }
} }

View File

@ -60,7 +60,7 @@ public class ComputerPlayer {
int bestScore = MinMax(bitboard, 0); int bestScore = MinMax(bitboard, 0);
if (SuicideChess.postThinkingOutput()) { if (SuicideChess.postThinkingOutput()) {
System.out.println(SuicideChess.PLY_DEPTH+" "+bestScore*100+" 0 "+nodesSearched+" "+bestMove); System.out.println(SuicideChess.getPlyDepth()+" "+bestScore*100+" 0 "+nodesSearched+" "+bestMove);
} }
return bestMove; return bestMove;
} }
@ -69,7 +69,7 @@ public class ComputerPlayer {
private static int MinMax(Board bitboard, int currentDepth) throws NotAValidSquare, NoPieceOnSquare { private static int MinMax(Board bitboard, int currentDepth) throws NotAValidSquare, NoPieceOnSquare {
nodesSearched++; nodesSearched++;
if (currentDepth >= SuicideChess.PLY_DEPTH) { if (currentDepth >= SuicideChess.getPlyDepth()) {
return bitboard.getBoardValue(); return bitboard.getBoardValue();
} }
@ -140,8 +140,11 @@ public class ComputerPlayer {
bestMove = null; bestMove = null;
nodesSearched = 0; nodesSearched = 0;
Date thinkingBeginingTime = new Date(); thinkingBeginingTime = new Date();
ReturnWrapper bestScore = AlphaBeta(bitboard, 0, Board.BLACK_WINS-1, Board.WHITE_WINS+1);
//iterative deepening
for(maxDepth=2; maxDepth<=SuicideChess.getPlyDepth(); maxDepth++) {
ReturnWrapper bestScore = AlphaBeta(bitboard, 0, Board.MIN_VALUE, Board.MAX_VALUE);
Date thinkingEndTime = new Date(); Date thinkingEndTime = new Date();
//select one of the best moves randomly //select one of the best moves randomly
@ -149,18 +152,25 @@ public class ComputerPlayer {
//if (currentDepth == 0) { System.out.println(bestMoveIndex.size()); } //if (currentDepth == 0) { System.out.println(bestMoveIndex.size()); }
bestMove = bestMoves.get(generator.nextInt(bestMoves.size())); bestMove = bestMoves.get(generator.nextInt(bestMoves.size()));
System.out.println("Found "+bestMoves.size()+" good moves.");
if (SuicideChess.postThinkingOutput()) { if (SuicideChess.postThinkingOutput()) {
System.out.println(SuicideChess.PLY_DEPTH+" "+bestScore.getAlphaBeta()*100+ System.out.println(maxDepth+"\t"+bestScore.getBranchValue()*100+
" "+((int)(thinkingEndTime.getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds "\t"+((int)(thinkingEndTime.getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
" "+nodesSearched+" "+bestMove); "\t"+nodesSearched+"\t"+bestScore.getPrincipalVariation());
} }
}
if(SuicideChess.playInACSII()) {
System.out.println("Found "+bestMoves.size()+" good moves.");
}
System.out.println(((bitboard.mobility(Piece.WHITE))));
System.out.println(((-bitboard.mobility(Piece.BLACK))));
return bestMove; return bestMove;
} }
private static Date thinkingBeginingTime;
private static int maxDepth;
private static ArrayList<Move> bestMoves=new ArrayList<Move>(); private static ArrayList<Move> bestMoves=new ArrayList<Move>();
//this class is used to return two arguments in the next function, the two arguments being //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 value of alpha or beta
@ -168,22 +178,25 @@ public class ComputerPlayer {
private static class ReturnWrapper { private static class ReturnWrapper {
private int alphaBeta; private int alphaBeta;
private int branchValue; private int branchValue;
public ReturnWrapper(int alphaBeta, int branchValue) { private String principalVariation;
public ReturnWrapper(int alphaBeta, int branchValue, String principalVariation) {
this.alphaBeta = alphaBeta; this.alphaBeta = alphaBeta;
this.branchValue = branchValue; this.branchValue = branchValue;
this.principalVariation = principalVariation;
} }
public int getAlphaBeta() {return this.alphaBeta;} public int getAlphaBeta() {return this.alphaBeta;}
public int getBranchValue() {return this.branchValue;} public int getBranchValue() {return this.branchValue;}
public String getPrincipalVariation() {return this.principalVariation;}
}; };
private static ReturnWrapper AlphaBeta(Board bitboard, int currentDepth, int alpha, int beta) throws NotAValidSquare, NoPieceOnSquare { private static ReturnWrapper AlphaBeta(Board bitboard, int currentDepth, int alpha, int beta) throws NotAValidSquare, NoPieceOnSquare {
nodesSearched++; nodesSearched++;
if(bitboard.isADraw()) { if(bitboard.isADraw()) {
return new ReturnWrapper(Board.DRAW_BOARD,Board.DRAW_BOARD); return new ReturnWrapper(Board.DRAW_BOARD,Board.DRAW_BOARD,"");
} }
if (currentDepth >= SuicideChess.PLY_DEPTH) { if (currentDepth >= maxDepth) {
//System.out.println("'-> Evaluate: "+bitboard.getBoardValue()); //System.out.println("'-> Evaluate: "+bitboard.getBoardValue());
return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue()); return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),"");
} }
Rules.legalMovesForPlayer(bitboard); Rules.legalMovesForPlayer(bitboard);
@ -194,15 +207,16 @@ public class ComputerPlayer {
if (allLegalMoves.size()==0) { if (allLegalMoves.size()==0) {
if (bitboard.getCurrentPlayer()==Piece.BLACK) { if (bitboard.getCurrentPlayer()==Piece.BLACK) {
//System.out.println("'-> Evaluate *BLACK WINS*: "+Board.BLACK_WINS); //System.out.println("'-> Evaluate *BLACK WINS*: "+Board.BLACK_WINS);
return new ReturnWrapper(Board.BLACK_WINS,Board.BLACK_WINS); return new ReturnWrapper(Board.BLACK_WINS,Board.BLACK_WINS,"");
} else { } else {
//System.out.println("'-> Evaluate *WHITE WINS* : "+Board.WHITE_WINS); //System.out.println("'-> Evaluate *WHITE WINS* : "+Board.WHITE_WINS);
return new ReturnWrapper(Board.WHITE_WINS,Board.WHITE_WINS); return new ReturnWrapper(Board.WHITE_WINS,Board.WHITE_WINS,"");
} }
} else { } else {
int currentScore; int currentScore;
int bestScoreSoFar; int bestScoreSoFar;
int currentAlphaBeta; int currentAlphaBeta;
String bestVariationSoFar="";
if (bitboard.getCurrentPlayer()==Piece.BLACK) { if (bitboard.getCurrentPlayer()==Piece.BLACK) {
bestScoreSoFar=Board.MAX_VALUE; //black tries to minimise bestScoreSoFar=Board.MAX_VALUE; //black tries to minimise
for (int i=0; i<allLegalMoves.size(); i++) { for (int i=0; i<allLegalMoves.size(); i++) {
@ -226,8 +240,14 @@ public class ComputerPlayer {
if (currentScore <= bestScoreSoFar) { if (currentScore <= bestScoreSoFar) {
if (currentScore < bestScoreSoFar) { if (currentScore < bestScoreSoFar) {
bestScoreSoFar=currentScore; bestScoreSoFar=currentScore;
bestVariationSoFar = allLegalMoves.get(i).toString()+" "+returnValue.getPrincipalVariation();
if (currentDepth==0) { if (currentDepth==0) {
bestMoves.clear(); bestMoves.clear();
if (SuicideChess.postThinkingOutput()) {
System.out.println(maxDepth+"\t"+returnValue.getBranchValue()*100+
"\t"+((int)((new Date()).getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
"\t"+nodesSearched+"\t"+bestVariationSoFar);
}
//System.out.println("*** Clear "); //System.out.println("*** Clear ");
} }
} }
@ -238,11 +258,11 @@ public class ComputerPlayer {
} }
if(beta<alpha) { if(beta<alpha) {
//if(currentDepth!=SuicideChess.PLY_DEPTH-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth); //if(currentDepth!=SuicideChess.getPlyDepth()-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
return new ReturnWrapper(alpha,bestScoreSoFar); //pruning return new ReturnWrapper(alpha,bestScoreSoFar,bestVariationSoFar); //pruning
} }
} }
return new ReturnWrapper(beta,bestScoreSoFar); return new ReturnWrapper(beta,bestScoreSoFar,bestVariationSoFar);
} else { //white piece } else { //white piece
bestScoreSoFar=Board.MIN_VALUE; //white tries to maximise bestScoreSoFar=Board.MIN_VALUE; //white tries to maximise
for (int i=0; i<allLegalMoves.size(); i++) { for (int i=0; i<allLegalMoves.size(); i++) {
@ -265,9 +285,15 @@ public class ComputerPlayer {
//calculating branch value //calculating branch value
if (currentScore >= bestScoreSoFar) { if (currentScore >= bestScoreSoFar) {
if (currentScore > bestScoreSoFar) { if (currentScore > bestScoreSoFar) {
bestVariationSoFar = allLegalMoves.get(i).toString()+" "+returnValue.getPrincipalVariation();
bestScoreSoFar=currentScore; bestScoreSoFar=currentScore;
if (currentDepth==0) { if (currentDepth==0) {
bestMoves.clear(); bestMoves.clear();
if (SuicideChess.postThinkingOutput()) {
System.out.println(maxDepth+"\t"+returnValue.getBranchValue()*100+
"\t"+((int)((new Date()).getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
"\t"+nodesSearched+"\t"+bestVariationSoFar);
}
//System.out.println("*** Clear "); //System.out.println("*** Clear ");
} }
} }
@ -278,11 +304,11 @@ public class ComputerPlayer {
} }
if(alpha>beta) { if(alpha>beta) {
//if(currentDepth!=SuicideChess.PLY_DEPTH-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth); //if(currentDepth!=SuicideChess.getPlyDepth()-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
return new ReturnWrapper(beta,bestScoreSoFar); //pruning return new ReturnWrapper(beta,bestScoreSoFar,bestVariationSoFar); //pruning
} }
} }
return new ReturnWrapper(alpha,bestScoreSoFar); return new ReturnWrapper(alpha,bestScoreSoFar,bestVariationSoFar);
} }
} }
} }

View File

@ -77,24 +77,24 @@ public class Piece {
public static final int[] PIECE_VALUE_MIDDLEGAME = new int[Piece.MAX_PIECE_NUMBER+1]; public static final int[] PIECE_VALUE_MIDDLEGAME = new int[Piece.MAX_PIECE_NUMBER+1];
public static final int[] PIECE_VALUE_ENDGAME = new int[Piece.MAX_PIECE_NUMBER+1]; public static final int[] PIECE_VALUE_ENDGAME = new int[Piece.MAX_PIECE_NUMBER+1];
static { static {
PIECE_VALUE_MIDDLEGAME[WHITE_KING]=50; PIECE_VALUE_MIDDLEGAME[WHITE_KING]=500;
PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN]=90; PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN]=900;
PIECE_VALUE_MIDDLEGAME[WHITE_ROOK]=35; PIECE_VALUE_MIDDLEGAME[WHITE_ROOK]=350;
PIECE_VALUE_MIDDLEGAME[WHITE_KNIGHT]=30; PIECE_VALUE_MIDDLEGAME[WHITE_KNIGHT]=300;
PIECE_VALUE_MIDDLEGAME[WHITE_BISHOP]=-10; PIECE_VALUE_MIDDLEGAME[WHITE_BISHOP]=-400; //started with -100
PIECE_VALUE_MIDDLEGAME[WHITE_PAWN]=10; PIECE_VALUE_MIDDLEGAME[WHITE_PAWN]=300; //started with 100
PIECE_VALUE_MIDDLEGAME[BLACK_KING]=-PIECE_VALUE_MIDDLEGAME[WHITE_KING]; PIECE_VALUE_MIDDLEGAME[BLACK_KING]=-PIECE_VALUE_MIDDLEGAME[WHITE_KING];
PIECE_VALUE_MIDDLEGAME[BLACK_QUEEN]=-PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN]; PIECE_VALUE_MIDDLEGAME[BLACK_QUEEN]=-PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN];
PIECE_VALUE_MIDDLEGAME[BLACK_ROOK]=-PIECE_VALUE_MIDDLEGAME[WHITE_ROOK]; PIECE_VALUE_MIDDLEGAME[BLACK_ROOK]=-PIECE_VALUE_MIDDLEGAME[WHITE_ROOK];
PIECE_VALUE_MIDDLEGAME[BLACK_KNIGHT]=-PIECE_VALUE_MIDDLEGAME[WHITE_KNIGHT]; PIECE_VALUE_MIDDLEGAME[BLACK_KNIGHT]=-PIECE_VALUE_MIDDLEGAME[WHITE_KNIGHT];
PIECE_VALUE_MIDDLEGAME[BLACK_BISHOP]=-PIECE_VALUE_MIDDLEGAME[WHITE_BISHOP]; PIECE_VALUE_MIDDLEGAME[BLACK_BISHOP]=-PIECE_VALUE_MIDDLEGAME[WHITE_BISHOP];
PIECE_VALUE_MIDDLEGAME[BLACK_PAWN]=-PIECE_VALUE_MIDDLEGAME[WHITE_PAWN]; PIECE_VALUE_MIDDLEGAME[BLACK_PAWN]=-PIECE_VALUE_MIDDLEGAME[WHITE_PAWN];
PIECE_VALUE_ENDGAME[WHITE_KING]=-40; PIECE_VALUE_ENDGAME[WHITE_KING]=-400;
PIECE_VALUE_ENDGAME[WHITE_QUEEN]=-40; PIECE_VALUE_ENDGAME[WHITE_QUEEN]=-400;
PIECE_VALUE_ENDGAME[WHITE_ROOK]=-10; PIECE_VALUE_ENDGAME[WHITE_ROOK]=-100;
PIECE_VALUE_ENDGAME[WHITE_KNIGHT]=-70; PIECE_VALUE_ENDGAME[WHITE_KNIGHT]=-700;
PIECE_VALUE_ENDGAME[WHITE_BISHOP]=-40; PIECE_VALUE_ENDGAME[WHITE_BISHOP]=-400;
PIECE_VALUE_ENDGAME[WHITE_PAWN]=-90; PIECE_VALUE_ENDGAME[WHITE_PAWN]=-900;
PIECE_VALUE_ENDGAME[BLACK_KING]=-PIECE_VALUE_ENDGAME[WHITE_KING]; PIECE_VALUE_ENDGAME[BLACK_KING]=-PIECE_VALUE_ENDGAME[WHITE_KING];
PIECE_VALUE_ENDGAME[BLACK_QUEEN]=-PIECE_VALUE_ENDGAME[WHITE_QUEEN]; PIECE_VALUE_ENDGAME[BLACK_QUEEN]=-PIECE_VALUE_ENDGAME[WHITE_QUEEN];
PIECE_VALUE_ENDGAME[BLACK_ROOK]=-PIECE_VALUE_ENDGAME[WHITE_ROOK]; PIECE_VALUE_ENDGAME[BLACK_ROOK]=-PIECE_VALUE_ENDGAME[WHITE_ROOK];

View File

@ -36,17 +36,36 @@ public class SuicideChess {
/** /**
* The name to be displayed * The name to be displayed
*/ */
public static final String NAME = "djib's SuShi v0.6.9"; public static final String NAME = "djib's SuShi v0.7";
/** /**
* Displays informations in the console. * Displays informations in the console.
*/ */
public static final boolean ASCII_GAME = true; private static boolean asciiGame = false;
/**
* Should the game be played in acsii
* @return boolean
*/
public static boolean playInACSII() {
return asciiGame;
}
/** /**
* Number of Plies the computes searches to * Number of Plies the computes searches to
*/ */
public static final int PLY_DEPTH = 4; private static int plyDepth = 4;
/**
* What is the current ply depth
* @return integer
*/
public static int getPlyDepth() { return plyDepth; }
/**
* Maximum number of Plies the computer will ever go to
*/
public static final int MAX_PLY_DEPTH = 8;
/** /**
* Test and display if the board is in a winning state. * Test and display if the board is in a winning state.
@ -108,6 +127,15 @@ public class SuicideChess {
public static boolean postThinkingOutput() { public static boolean postThinkingOutput() {
return post; return post;
} }
private static void displayPlayer(Board bitboard) {
if(bitboard.getCurrentPlayer()==Piece.BLACK) {
System.out.println("Black: ");
} else {
System.out.println("White: ");
}
}
/** /**
* The main function * The main function
* @param args No parameters should be transmitted to this function. * @param args No parameters should be transmitted to this function.
@ -116,10 +144,9 @@ public class SuicideChess {
public static void main(String[] args) throws NotAValidSquare { public static void main(String[] args) throws NotAValidSquare {
System.out.println("Welcome to SuicideChess "+SuicideChess.NAME+"!"); System.out.println("Welcome to SuicideChess "+SuicideChess.NAME+"!\n");
if (!SuicideChess.ASCII_GAME) { System.out.println("Type 'asciiplay' to be able to play in a terminal.");
System.out.println("This game was not designed to be played in console. Please use it with XBoard, WinBoard or any compatible program."); System.out.println("If you want a graphical interface, you can use XBoard, WinBoard or any compatible program.");
}
System.out.println(); System.out.println();
@ -127,11 +154,6 @@ public class SuicideChess {
Board bitboard = new Board(); Board bitboard = new Board();
addPlayedPosition(bitboard); addPlayedPosition(bitboard);
if (ASCII_GAME) {
bitboard.display();
System.out.println("White: ");
}
boolean computerPlaying = true; //the computer does not play in foce mode. boolean computerPlaying = true; //the computer does not play in foce mode.
boolean playing = true; boolean playing = true;
@ -152,12 +174,20 @@ public class SuicideChess {
try { try {
int problemNb = Integer.parseInt(whatMove.substring(8)); int problemNb = Integer.parseInt(whatMove.substring(8));
bitboard=new Board(SuicideProblems.getProblemNumber(problemNb)); bitboard=new Board(SuicideProblems.getProblemNumber(problemNb));
if(ASCII_GAME) if(asciiGame)
bitboard.display(); bitboard.display();
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
System.out.println("Not a valid number: "+ whatMove.substring(8)); System.out.println("Not a valid number: "+ whatMove.substring(8));
} }
} }
} else if (whatMove.startsWith("asciiplay")) {
asciiGame=true;
bitboard.display();
displayPlayer(bitboard);
} else if (whatMove.startsWith("asciiplay")) {
asciiGame=false;
} else if ((whatMove.startsWith("board"))) {
bitboard.display();
} else { } else {
int xBoardCommand = XBoardProtocol.getCommand(whatMove); int xBoardCommand = XBoardProtocol.getCommand(whatMove);
@ -183,6 +213,10 @@ public class SuicideChess {
playing=false; playing=false;
break; break;
case XBoardProtocol.NEW: case XBoardProtocol.NEW:
bitboard=new Board();
addPlayedPosition(bitboard);
computerPlaying = true; //the computer does not play in foce mode.
bitboard.display();
//System.out.println("variant suicide"); //System.out.println("variant suicide");
break; break;
case XBoardProtocol.HINT: case XBoardProtocol.HINT:
@ -199,7 +233,7 @@ public class SuicideChess {
//no break here //no break here
case XBoardProtocol.UNDO: case XBoardProtocol.UNDO:
bitboard=new Board(removePlayedPosition()); bitboard=new Board(removePlayedPosition());
if (ASCII_GAME) { if (asciiGame) {
bitboard.display(); bitboard.display();
} }
break; break;
@ -211,9 +245,16 @@ public class SuicideChess {
break; break;
case XBoardProtocol.SETBOARD: case XBoardProtocol.SETBOARD:
bitboard=new Board(whatMove.substring(9)); bitboard=new Board(whatMove.substring(9));
if(ASCII_GAME) if(asciiGame)
bitboard.display(); bitboard.display();
break; break;
case XBoardProtocol.SETPLY:
try{
plyDepth = Integer.parseInt(whatMove.substring(3));
} catch (NumberFormatException e) {
System.out.println("Not a valid depth: "+ whatMove.substring(3));
}
break;
case XBoardProtocol.UNKNOWN: case XBoardProtocol.UNKNOWN:
if (acceptedUsermove) { if (acceptedUsermove) {
System.out.println("Error (unknown command): "+whatMove); System.out.println("Error (unknown command): "+whatMove);
@ -258,22 +299,22 @@ public class SuicideChess {
} }
if (foundMoveIndex == -1) { if (foundMoveIndex == -1) {
if (needToCapture) { if (needToCapture) {
if (ASCII_GAME) if (asciiGame)
System.out.println("Capturing is mandatory."); System.out.println("Capturing is mandatory.");
} }
System.out.println("Illegal move: "+theMove.toString()); System.out.println("Illegal move: "+theMove.toString());
} else { } else {
bitboard.doMove(allLegalMoves.get(foundMoveIndex)); bitboard.doMove(allLegalMoves.get(foundMoveIndex));
addPlayedPosition(bitboard); addPlayedPosition(bitboard);
if (ASCII_GAME) { if (asciiGame) {
allLegalMoves.get(foundMoveIndex).display(); //allLegalMoves.get(foundMoveIndex).display();
System.out.println("Board value: "+bitboard.getBoardValue()); //System.out.println("Board value: "+bitboard.getBoardValue());
bitboard.display(); bitboard.display();
} }
playedALegalMove=true; playedALegalMove=true;
} }
} else { } else {
if (ASCII_GAME) if (asciiGame)
System.out.println("Please play a piece of the right color."); System.out.println("Please play a piece of the right color.");
System.out.println("Illegal move: "+theMove.toString()); System.out.println("Illegal move: "+theMove.toString());
} }
@ -304,10 +345,11 @@ public class SuicideChess {
bitboard.doMove(computerMove); bitboard.doMove(computerMove);
addPlayedPosition(bitboard); addPlayedPosition(bitboard);
XBoardProtocol.doMove(computerMove); XBoardProtocol.doMove(computerMove);
if (ASCII_GAME) { if (asciiGame) {
computerMove.display(); //computerMove.display();
System.out.println("Board value: "+bitboard.getBoardValue()); //System.out.println("Board value: "+bitboard.getBoardValue());
bitboard.display(); bitboard.display();
displayPlayer(bitboard);
} }
} }
@ -370,7 +412,7 @@ public class SuicideChess {
//in the end it says what games where lost by white. //in the end it says what games where lost by white.
private static void autoProblem() throws NotAValidSquare, UnableToParseFENStringException, NoPieceOnSquare, NoSuchSuicideProblem { private static void autoProblem() throws NotAValidSquare, UnableToParseFENStringException, NoPieceOnSquare, NoSuchSuicideProblem {
Board bitboard; Board bitboard;
boolean[] result=new boolean[SuicideProblems.numberOfProblems()]; int[] result=new int[SuicideProblems.numberOfProblems()];
for(int i=1; i<=SuicideProblems.numberOfProblems(); i++) { for(int i=1; i<=SuicideProblems.numberOfProblems(); i++) {
System.out.println("\n\nProblem "+i); System.out.println("\n\nProblem "+i);
bitboard=new Board(SuicideProblems.getProblemNumber(i)); bitboard=new Board(SuicideProblems.getProblemNumber(i));
@ -379,16 +421,26 @@ public class SuicideChess {
bitboard.doMove(computerMove); bitboard.doMove(computerMove);
} }
if (bitboard.getCurrentPlayer()==Piece.BLACK) { if (bitboard.getCurrentPlayer()==Piece.BLACK) {
result[i-1]=false; result[i-1]=Piece.BLACK;
} else if(bitboard.isADraw()){
result[i-1]=Piece.NONE;
} else { } else {
result[i-1]=true; result[i-1]=Piece.WHITE;
} }
} }
System.out.println("\n\nLost following games:\n========begin========"); System.out.println("\n\nLost following games:\n========begin========");
int stats=SuicideProblems.numberOfProblems();
for(int i=1; i<=SuicideProblems.numberOfProblems(); i++) { for(int i=1; i<=SuicideProblems.numberOfProblems(); i++) {
if (!result[i-1]) if (result[i-1]==Piece.BLACK) {
System.out.println("Problem "+i+" lost !"); System.out.println("Problem "+i+" lost !");
stats--;
} else if (result[i-1]==Piece.NONE) {
System.out.println("Problem "+i+" drawn !");
stats--;
} }
}
System.out.println("---------------------\n"+stats+" problems solved out of "+SuicideProblems.numberOfProblems());
System.out.println("=========end========="); System.out.println("=========end=========");
} }
} }

View File

@ -86,6 +86,10 @@ public class XBoardProtocol {
* XBoard changes the board position * XBoard changes the board position
*/ */
public static final int SETBOARD = 17; public static final int SETBOARD = 17;
/**
* XBoard send a signal to limit ply depth
*/
public static final int SETPLY = 18;
/** /**
* Unknown command * Unknown command
*/ */
@ -105,7 +109,7 @@ public class XBoardProtocol {
System.out.println("feature ping=1 setboard=1"); System.out.println("feature ping=1 setboard=1");
System.out.println("feature time=0 draw=0 reuse=0 analyze=0 colors=0"); System.out.println("feature time=0 draw=0 reuse=0 analyze=0 colors=0");
System.out.println("feature done=1"); System.out.println("feature done=1");
if (SuicideChess.ASCII_GAME) if (SuicideChess.playInACSII())
System.out.println(); System.out.println();
} }
@ -160,6 +164,8 @@ public class XBoardProtocol {
return NOPOST; return NOPOST;
} else if (command.startsWith("setboard")) { } else if (command.startsWith("setboard")) {
return SETBOARD; return SETBOARD;
} else if (command.startsWith("sd")) {
return SETPLY;
} }
return UNKNOWN; return UNKNOWN;