Version 7.0
=========== Corrected a few bugs from 6.9, like the principal variation. About to add opening book.
This commit is contained in:
@ -70,6 +70,15 @@ public class Board {
|
||||
* Value representing the value of a draw position
|
||||
*/
|
||||
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 *
|
||||
@ -314,13 +323,9 @@ public class Board {
|
||||
|
||||
if(currentPlayer==Piece.WHITE) {
|
||||
currentPlayer=Piece.BLACK;
|
||||
//if (SuicideChess.ASCII_GAME)
|
||||
// System.out.println("Black: ");
|
||||
} else {
|
||||
fullmoveNumber++; //black has just played
|
||||
currentPlayer=Piece.WHITE;
|
||||
//if (SuicideChess.ASCII_GAME)
|
||||
// System.out.println("White: ");
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
if (move.isCaptureMove()) {
|
||||
@ -602,7 +620,8 @@ public class Board {
|
||||
//System.out.println("Playing midgame");
|
||||
for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
|
||||
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_MIDDLEGAME[i];
|
||||
}
|
||||
}
|
||||
boardValue += ((mobility(Piece.WHITE)-mobility(Piece.BLACK)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ public class ComputerPlayer {
|
||||
|
||||
int bestScore = MinMax(bitboard, 0);
|
||||
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;
|
||||
}
|
||||
@ -69,7 +69,7 @@ public class ComputerPlayer {
|
||||
private static int MinMax(Board bitboard, int currentDepth) throws NotAValidSquare, NoPieceOnSquare {
|
||||
nodesSearched++;
|
||||
|
||||
if (currentDepth >= SuicideChess.PLY_DEPTH) {
|
||||
if (currentDepth >= SuicideChess.getPlyDepth()) {
|
||||
return bitboard.getBoardValue();
|
||||
}
|
||||
|
||||
@ -140,50 +140,63 @@ public class ComputerPlayer {
|
||||
bestMove = null;
|
||||
nodesSearched = 0;
|
||||
|
||||
Date thinkingBeginingTime = new Date();
|
||||
ReturnWrapper bestScore = AlphaBeta(bitboard, 0, Board.BLACK_WINS-1, Board.WHITE_WINS+1);
|
||||
Date thinkingEndTime = new Date();
|
||||
thinkingBeginingTime = new Date();
|
||||
|
||||
//iterative deepening
|
||||
for(maxDepth=2; maxDepth<=SuicideChess.getPlyDepth(); maxDepth++) {
|
||||
ReturnWrapper bestScore = AlphaBeta(bitboard, 0, Board.MIN_VALUE, Board.MAX_VALUE);
|
||||
Date thinkingEndTime = new Date();
|
||||
|
||||
//select one of the best moves randomly
|
||||
Random generator = new Random();
|
||||
//if (currentDepth == 0) { System.out.println(bestMoveIndex.size()); }
|
||||
bestMove = bestMoves.get(generator.nextInt(bestMoves.size()));
|
||||
|
||||
if (SuicideChess.postThinkingOutput()) {
|
||||
System.out.println(maxDepth+"\t"+bestScore.getBranchValue()*100+
|
||||
"\t"+((int)(thinkingEndTime.getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
|
||||
"\t"+nodesSearched+"\t"+bestScore.getPrincipalVariation());
|
||||
}
|
||||
|
||||
//select one of the best moves randomly
|
||||
Random generator = new Random();
|
||||
//if (currentDepth == 0) { System.out.println(bestMoveIndex.size()); }
|
||||
bestMove = bestMoves.get(generator.nextInt(bestMoves.size()));
|
||||
}
|
||||
if(SuicideChess.playInACSII()) {
|
||||
System.out.println("Found "+bestMoves.size()+" good moves.");
|
||||
}
|
||||
|
||||
System.out.println("Found "+bestMoves.size()+" good moves.");
|
||||
|
||||
if (SuicideChess.postThinkingOutput()) {
|
||||
System.out.println(SuicideChess.PLY_DEPTH+" "+bestScore.getAlphaBeta()*100+
|
||||
" "+((int)(thinkingEndTime.getTime()-thinkingBeginingTime.getTime())/10)+ //search time in centiseconds
|
||||
" "+nodesSearched+" "+bestMove);
|
||||
}
|
||||
System.out.println(((bitboard.mobility(Piece.WHITE))));
|
||||
System.out.println(((-bitboard.mobility(Piece.BLACK))));
|
||||
|
||||
return bestMove;
|
||||
}
|
||||
|
||||
|
||||
private static ArrayList<Move> bestMoves=new ArrayList<Move>();
|
||||
private static Date thinkingBeginingTime;
|
||||
private static int maxDepth;
|
||||
private static ArrayList<Move> bestMoves=new ArrayList<Move>();
|
||||
//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)
|
||||
private static class ReturnWrapper {
|
||||
private int alphaBeta;
|
||||
private int branchValue;
|
||||
public ReturnWrapper(int alphaBeta, int branchValue) {
|
||||
private String principalVariation;
|
||||
public ReturnWrapper(int alphaBeta, int branchValue, String principalVariation) {
|
||||
this.alphaBeta = alphaBeta;
|
||||
this.branchValue = branchValue;
|
||||
this.principalVariation = principalVariation;
|
||||
}
|
||||
public int getAlphaBeta() {return this.alphaBeta;}
|
||||
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 {
|
||||
nodesSearched++;
|
||||
|
||||
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());
|
||||
return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue());
|
||||
return new ReturnWrapper(bitboard.getBoardValue(),bitboard.getBoardValue(),"");
|
||||
}
|
||||
|
||||
Rules.legalMovesForPlayer(bitboard);
|
||||
@ -194,15 +207,16 @@ public class ComputerPlayer {
|
||||
if (allLegalMoves.size()==0) {
|
||||
if (bitboard.getCurrentPlayer()==Piece.BLACK) {
|
||||
//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 {
|
||||
//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 {
|
||||
int currentScore;
|
||||
int bestScoreSoFar;
|
||||
int currentAlphaBeta;
|
||||
String bestVariationSoFar="";
|
||||
if (bitboard.getCurrentPlayer()==Piece.BLACK) {
|
||||
bestScoreSoFar=Board.MAX_VALUE; //black tries to minimise
|
||||
for (int i=0; i<allLegalMoves.size(); i++) {
|
||||
@ -226,8 +240,14 @@ public class ComputerPlayer {
|
||||
if (currentScore <= bestScoreSoFar) {
|
||||
if (currentScore < bestScoreSoFar) {
|
||||
bestScoreSoFar=currentScore;
|
||||
bestVariationSoFar = allLegalMoves.get(i).toString()+" "+returnValue.getPrincipalVariation();
|
||||
if (currentDepth==0) {
|
||||
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 ");
|
||||
}
|
||||
}
|
||||
@ -236,19 +256,19 @@ public class ComputerPlayer {
|
||||
//System.out.println("*** Adding "+allLegalMoves.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(beta<alpha) {
|
||||
//if(currentDepth!=SuicideChess.PLY_DEPTH-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
|
||||
return new ReturnWrapper(alpha,bestScoreSoFar); //pruning
|
||||
//if(currentDepth!=SuicideChess.getPlyDepth()-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
|
||||
return new ReturnWrapper(alpha,bestScoreSoFar,bestVariationSoFar); //pruning
|
||||
}
|
||||
}
|
||||
return new ReturnWrapper(beta,bestScoreSoFar);
|
||||
return new ReturnWrapper(beta,bestScoreSoFar,bestVariationSoFar);
|
||||
} else { //white piece
|
||||
bestScoreSoFar=Board.MIN_VALUE; //white tries to maximise
|
||||
for (int i=0; i<allLegalMoves.size(); i++) {
|
||||
Board boardCopy = new Board(bitboard);
|
||||
boardCopy.doMove(allLegalMoves.get(i));
|
||||
|
||||
|
||||
//System.out.println("Analysing "+currentDepth+":"+allLegalMoves.get(i));
|
||||
|
||||
ReturnWrapper returnValue = AlphaBeta(boardCopy,currentDepth+1,alpha,Board.MAX_VALUE);
|
||||
@ -265,9 +285,15 @@ public class ComputerPlayer {
|
||||
//calculating branch value
|
||||
if (currentScore >= bestScoreSoFar) {
|
||||
if (currentScore > bestScoreSoFar) {
|
||||
bestVariationSoFar = allLegalMoves.get(i).toString()+" "+returnValue.getPrincipalVariation();
|
||||
bestScoreSoFar=currentScore;
|
||||
if (currentDepth==0) {
|
||||
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 ");
|
||||
}
|
||||
}
|
||||
@ -278,11 +304,11 @@ public class ComputerPlayer {
|
||||
}
|
||||
|
||||
if(alpha>beta) {
|
||||
//if(currentDepth!=SuicideChess.PLY_DEPTH-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
|
||||
return new ReturnWrapper(beta,bestScoreSoFar); //pruning
|
||||
//if(currentDepth!=SuicideChess.getPlyDepth()-1) System.out.println("Pruning "+Integer.toString(allLegalMoves.size()-i)+" alternatives at depth "+ currentDepth);
|
||||
return new ReturnWrapper(beta,bestScoreSoFar,bestVariationSoFar); //pruning
|
||||
}
|
||||
}
|
||||
return new ReturnWrapper(alpha,bestScoreSoFar);
|
||||
return new ReturnWrapper(alpha,bestScoreSoFar,bestVariationSoFar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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_ENDGAME = new int[Piece.MAX_PIECE_NUMBER+1];
|
||||
static {
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_KING]=50;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN]=90;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_ROOK]=35;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_KNIGHT]=30;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_BISHOP]=-10;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_PAWN]=10;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_KING]=500;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN]=900;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_ROOK]=350;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_KNIGHT]=300;
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_BISHOP]=-400; //started with -100
|
||||
PIECE_VALUE_MIDDLEGAME[WHITE_PAWN]=300; //started with 100
|
||||
PIECE_VALUE_MIDDLEGAME[BLACK_KING]=-PIECE_VALUE_MIDDLEGAME[WHITE_KING];
|
||||
PIECE_VALUE_MIDDLEGAME[BLACK_QUEEN]=-PIECE_VALUE_MIDDLEGAME[WHITE_QUEEN];
|
||||
PIECE_VALUE_MIDDLEGAME[BLACK_ROOK]=-PIECE_VALUE_MIDDLEGAME[WHITE_ROOK];
|
||||
PIECE_VALUE_MIDDLEGAME[BLACK_KNIGHT]=-PIECE_VALUE_MIDDLEGAME[WHITE_KNIGHT];
|
||||
PIECE_VALUE_MIDDLEGAME[BLACK_BISHOP]=-PIECE_VALUE_MIDDLEGAME[WHITE_BISHOP];
|
||||
PIECE_VALUE_MIDDLEGAME[BLACK_PAWN]=-PIECE_VALUE_MIDDLEGAME[WHITE_PAWN];
|
||||
PIECE_VALUE_ENDGAME[WHITE_KING]=-40;
|
||||
PIECE_VALUE_ENDGAME[WHITE_QUEEN]=-40;
|
||||
PIECE_VALUE_ENDGAME[WHITE_ROOK]=-10;
|
||||
PIECE_VALUE_ENDGAME[WHITE_KNIGHT]=-70;
|
||||
PIECE_VALUE_ENDGAME[WHITE_BISHOP]=-40;
|
||||
PIECE_VALUE_ENDGAME[WHITE_PAWN]=-90;
|
||||
PIECE_VALUE_ENDGAME[WHITE_KING]=-400;
|
||||
PIECE_VALUE_ENDGAME[WHITE_QUEEN]=-400;
|
||||
PIECE_VALUE_ENDGAME[WHITE_ROOK]=-100;
|
||||
PIECE_VALUE_ENDGAME[WHITE_KNIGHT]=-700;
|
||||
PIECE_VALUE_ENDGAME[WHITE_BISHOP]=-400;
|
||||
PIECE_VALUE_ENDGAME[WHITE_PAWN]=-900;
|
||||
PIECE_VALUE_ENDGAME[BLACK_KING]=-PIECE_VALUE_ENDGAME[WHITE_KING];
|
||||
PIECE_VALUE_ENDGAME[BLACK_QUEEN]=-PIECE_VALUE_ENDGAME[WHITE_QUEEN];
|
||||
PIECE_VALUE_ENDGAME[BLACK_ROOK]=-PIECE_VALUE_ENDGAME[WHITE_ROOK];
|
||||
|
@ -57,8 +57,8 @@ public class Rules {
|
||||
}
|
||||
legalMovesFromSquare(square,board);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for one legal move according to the current status of the {@link Board} and the
|
||||
* color of the current player.
|
||||
|
@ -36,17 +36,36 @@ public class SuicideChess {
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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.
|
||||
@ -108,6 +127,15 @@ public class SuicideChess {
|
||||
public static boolean postThinkingOutput() {
|
||||
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
|
||||
* @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 {
|
||||
|
||||
|
||||
System.out.println("Welcome to SuicideChess "+SuicideChess.NAME+"!");
|
||||
if (!SuicideChess.ASCII_GAME) {
|
||||
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("Welcome to SuicideChess "+SuicideChess.NAME+"!\n");
|
||||
System.out.println("Type 'asciiplay' to be able to play in a terminal.");
|
||||
System.out.println("If you want a graphical interface, you can use XBoard, WinBoard or any compatible program.");
|
||||
System.out.println();
|
||||
|
||||
|
||||
@ -127,11 +154,6 @@ public class SuicideChess {
|
||||
Board bitboard = new Board();
|
||||
addPlayedPosition(bitboard);
|
||||
|
||||
if (ASCII_GAME) {
|
||||
bitboard.display();
|
||||
System.out.println("White: ");
|
||||
}
|
||||
|
||||
boolean computerPlaying = true; //the computer does not play in foce mode.
|
||||
|
||||
boolean playing = true;
|
||||
@ -152,12 +174,20 @@ public class SuicideChess {
|
||||
try {
|
||||
int problemNb = Integer.parseInt(whatMove.substring(8));
|
||||
bitboard=new Board(SuicideProblems.getProblemNumber(problemNb));
|
||||
if(ASCII_GAME)
|
||||
if(asciiGame)
|
||||
bitboard.display();
|
||||
} catch (NumberFormatException e) {
|
||||
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 {
|
||||
int xBoardCommand = XBoardProtocol.getCommand(whatMove);
|
||||
|
||||
@ -183,6 +213,10 @@ public class SuicideChess {
|
||||
playing=false;
|
||||
break;
|
||||
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");
|
||||
break;
|
||||
case XBoardProtocol.HINT:
|
||||
@ -199,7 +233,7 @@ public class SuicideChess {
|
||||
//no break here
|
||||
case XBoardProtocol.UNDO:
|
||||
bitboard=new Board(removePlayedPosition());
|
||||
if (ASCII_GAME) {
|
||||
if (asciiGame) {
|
||||
bitboard.display();
|
||||
}
|
||||
break;
|
||||
@ -211,9 +245,16 @@ public class SuicideChess {
|
||||
break;
|
||||
case XBoardProtocol.SETBOARD:
|
||||
bitboard=new Board(whatMove.substring(9));
|
||||
if(ASCII_GAME)
|
||||
if(asciiGame)
|
||||
bitboard.display();
|
||||
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:
|
||||
if (acceptedUsermove) {
|
||||
System.out.println("Error (unknown command): "+whatMove);
|
||||
@ -258,22 +299,22 @@ public class SuicideChess {
|
||||
}
|
||||
if (foundMoveIndex == -1) {
|
||||
if (needToCapture) {
|
||||
if (ASCII_GAME)
|
||||
if (asciiGame)
|
||||
System.out.println("Capturing is mandatory.");
|
||||
}
|
||||
System.out.println("Illegal move: "+theMove.toString());
|
||||
} else {
|
||||
bitboard.doMove(allLegalMoves.get(foundMoveIndex));
|
||||
addPlayedPosition(bitboard);
|
||||
if (ASCII_GAME) {
|
||||
allLegalMoves.get(foundMoveIndex).display();
|
||||
System.out.println("Board value: "+bitboard.getBoardValue());
|
||||
if (asciiGame) {
|
||||
//allLegalMoves.get(foundMoveIndex).display();
|
||||
//System.out.println("Board value: "+bitboard.getBoardValue());
|
||||
bitboard.display();
|
||||
}
|
||||
playedALegalMove=true;
|
||||
}
|
||||
} else {
|
||||
if (ASCII_GAME)
|
||||
if (asciiGame)
|
||||
System.out.println("Please play a piece of the right color.");
|
||||
System.out.println("Illegal move: "+theMove.toString());
|
||||
}
|
||||
@ -304,13 +345,14 @@ public class SuicideChess {
|
||||
bitboard.doMove(computerMove);
|
||||
addPlayedPosition(bitboard);
|
||||
XBoardProtocol.doMove(computerMove);
|
||||
if (ASCII_GAME) {
|
||||
computerMove.display();
|
||||
System.out.println("Board value: "+bitboard.getBoardValue());
|
||||
if (asciiGame) {
|
||||
//computerMove.display();
|
||||
//System.out.println("Board value: "+bitboard.getBoardValue());
|
||||
bitboard.display();
|
||||
displayPlayer(bitboard);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (testAndDisplayIfWinningOrDrawPosition(bitboard)) {
|
||||
computerPlaying=false;
|
||||
}
|
||||
@ -370,7 +412,7 @@ public class SuicideChess {
|
||||
//in the end it says what games where lost by white.
|
||||
private static void autoProblem() throws NotAValidSquare, UnableToParseFENStringException, NoPieceOnSquare, NoSuchSuicideProblem {
|
||||
Board bitboard;
|
||||
boolean[] result=new boolean[SuicideProblems.numberOfProblems()];
|
||||
int[] result=new int[SuicideProblems.numberOfProblems()];
|
||||
for(int i=1; i<=SuicideProblems.numberOfProblems(); i++) {
|
||||
System.out.println("\n\nProblem "+i);
|
||||
bitboard=new Board(SuicideProblems.getProblemNumber(i));
|
||||
@ -379,16 +421,26 @@ public class SuicideChess {
|
||||
bitboard.doMove(computerMove);
|
||||
}
|
||||
if (bitboard.getCurrentPlayer()==Piece.BLACK) {
|
||||
result[i-1]=false;
|
||||
result[i-1]=Piece.BLACK;
|
||||
} else if(bitboard.isADraw()){
|
||||
result[i-1]=Piece.NONE;
|
||||
} else {
|
||||
result[i-1]=true;
|
||||
result[i-1]=Piece.WHITE;
|
||||
}
|
||||
|
||||
}
|
||||
System.out.println("\n\nLost following games:\n========begin========");
|
||||
int stats=SuicideProblems.numberOfProblems();
|
||||
for(int i=1; i<=SuicideProblems.numberOfProblems(); i++) {
|
||||
if (!result[i-1])
|
||||
if (result[i-1]==Piece.BLACK) {
|
||||
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=========");
|
||||
}
|
||||
}
|
@ -86,6 +86,10 @@ public class XBoardProtocol {
|
||||
* XBoard changes the board position
|
||||
*/
|
||||
public static final int SETBOARD = 17;
|
||||
/**
|
||||
* XBoard send a signal to limit ply depth
|
||||
*/
|
||||
public static final int SETPLY = 18;
|
||||
/**
|
||||
* Unknown command
|
||||
*/
|
||||
@ -105,7 +109,7 @@ public class XBoardProtocol {
|
||||
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 done=1");
|
||||
if (SuicideChess.ASCII_GAME)
|
||||
if (SuicideChess.playInACSII())
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@ -160,6 +164,8 @@ public class XBoardProtocol {
|
||||
return NOPOST;
|
||||
} else if (command.startsWith("setboard")) {
|
||||
return SETBOARD;
|
||||
} else if (command.startsWith("sd")) {
|
||||
return SETPLY;
|
||||
}
|
||||
|
||||
return UNKNOWN;
|
||||
|
Reference in New Issue
Block a user