End of game detection now works fine but has made the game a lot slower.
I will imporve this with a : istherevalidmove function.
This commit is contained in:
@ -73,6 +73,7 @@ public class Board {
|
|||||||
private int numberOfWhitePieces = NB_OF_FILES*2;
|
private int numberOfWhitePieces = NB_OF_FILES*2;
|
||||||
private int boardValue = 0; //evaluation of the board value
|
private int boardValue = 0; //evaluation of the board value
|
||||||
|
|
||||||
|
private int currentPlayer; //color of the current player.
|
||||||
|
|
||||||
/*=============*
|
/*=============*
|
||||||
* CONSTRUCTOR *
|
* CONSTRUCTOR *
|
||||||
@ -141,6 +142,7 @@ public class Board {
|
|||||||
}
|
}
|
||||||
this.enPassant = bitboard.enPassant;
|
this.enPassant = bitboard.enPassant;
|
||||||
this.enPassantSquare = new Square(bitboard.enPassantSquare);
|
this.enPassantSquare = new Square(bitboard.enPassantSquare);
|
||||||
|
this.currentPlayer = bitboard.currentPlayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*================*
|
/*================*
|
||||||
@ -152,10 +154,11 @@ public class Board {
|
|||||||
* This methods takes a {@link Move} and applies it (updating the bitboard)
|
* This methods takes a {@link Move} and applies it (updating the bitboard)
|
||||||
* @param move The move that is to be done
|
* @param move The move that is to be done
|
||||||
* @throws NoPieceOnSquare If a piece is trying to be moved from a square that does not exist.
|
* @throws NoPieceOnSquare If a piece is trying to be moved from a square that does not exist.
|
||||||
|
* @throws NotAValidSquare
|
||||||
* @see Move
|
* @see Move
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public void doMove(Move move) throws NoPieceOnSquare {
|
public void doMove(Move move) throws NoPieceOnSquare, NotAValidSquare {
|
||||||
if (move.isCaptureMove()) {
|
if (move.isCaptureMove()) {
|
||||||
if (move.isEnPassant()) {
|
if (move.isEnPassant()) {
|
||||||
removePiece(move.getEnPassantSquare(), move.getCapturedPiece());
|
removePiece(move.getEnPassantSquare(), move.getCapturedPiece());
|
||||||
@ -176,6 +179,16 @@ public class Board {
|
|||||||
enPassantSquare=move.getEnPassantSquare();
|
enPassantSquare=move.getEnPassantSquare();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(currentPlayer==Piece.WHITE) {
|
||||||
|
currentPlayer=Piece.BLACK;
|
||||||
|
if (SuicideChess.ASCII_GAME)
|
||||||
|
System.out.println("Black: ");
|
||||||
|
} else {
|
||||||
|
currentPlayer=Piece.WHITE;
|
||||||
|
if (SuicideChess.ASCII_GAME)
|
||||||
|
System.out.println("White: ");
|
||||||
|
}
|
||||||
|
|
||||||
evaluateNewBoardValue(move);
|
evaluateNewBoardValue(move);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,12 +287,19 @@ public class Board {
|
|||||||
/**
|
/**
|
||||||
* This function returns an integer representing the result of the static evaluation function
|
* This function returns an integer representing the result of the static evaluation function
|
||||||
* for the current board
|
* for the current board
|
||||||
* @return
|
* @return Integer
|
||||||
*/
|
*/
|
||||||
public int getBoardValue() {
|
public int getBoardValue() {
|
||||||
return boardValue;
|
return boardValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function returns the current player color
|
||||||
|
* @return Integer
|
||||||
|
*/
|
||||||
|
public int getCurrentPlayer() {
|
||||||
|
return currentPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function can be used to display the board
|
* This function can be used to display the board
|
||||||
@ -402,7 +422,7 @@ public class Board {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void evaluateNewBoardValue (Move move) {
|
private void evaluateNewBoardValue (Move move) throws NotAValidSquare {
|
||||||
if (move.isCaptureMove()) {
|
if (move.isCaptureMove()) {
|
||||||
if (move.getCapturedPiece().getColor()==Piece.BLACK) {
|
if (move.getCapturedPiece().getColor()==Piece.BLACK) {
|
||||||
numberOfBlackPieces--;
|
numberOfBlackPieces--;
|
||||||
@ -418,6 +438,7 @@ public class Board {
|
|||||||
boardValue = numberOfBlackPieces - numberOfWhitePieces;
|
boardValue = numberOfBlackPieces - numberOfWhitePieces;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Rules.legalMovesForPlayer(this);
|
||||||
if ((Rules.getLegalMovesCapture().size()==0)&&(Rules.getLegalMovesNonCapture().size()==0)) {
|
if ((Rules.getLegalMovesCapture().size()==0)&&(Rules.getLegalMovesNonCapture().size()==0)) {
|
||||||
// The following line is NOT an error !!!
|
// The following line is NOT an error !!!
|
||||||
// After move from WHITE, if there is no moves for BLACK, BLACK won.
|
// After move from WHITE, if there is no moves for BLACK, BLACK won.
|
||||||
|
@ -25,9 +25,9 @@ public class ComputerPlayer {
|
|||||||
* @see Board
|
* @see Board
|
||||||
* @see Move
|
* @see Move
|
||||||
*/
|
*/
|
||||||
public static Move doRandomMove(Board bitboard, int color) throws NotAValidSquare {
|
public static Move doRandomMove(Board bitboard) throws NotAValidSquare {
|
||||||
Random generator = new Random();
|
Random generator = new Random();
|
||||||
Rules.legalMovesForPlayer(bitboard,color);
|
Rules.legalMovesForPlayer(bitboard);
|
||||||
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
|
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
|
||||||
if (allLegalMoves.size()==0) {
|
if (allLegalMoves.size()==0) {
|
||||||
allLegalMoves = Rules.getLegalMovesNonCapture();
|
allLegalMoves = Rules.getLegalMovesNonCapture();
|
||||||
@ -50,10 +50,10 @@ public class ComputerPlayer {
|
|||||||
* @see Board
|
* @see Board
|
||||||
* @see Move
|
* @see Move
|
||||||
*/
|
*/
|
||||||
public static Move doMinMaxMove(Board bitboard, int color) throws NotAValidSquare, NoPieceOnSquare {
|
public static Move doMinMaxMove(Board bitboard) throws NotAValidSquare, NoPieceOnSquare {
|
||||||
bestMove = null;
|
bestMove = null;
|
||||||
nodesSearched = 0;
|
nodesSearched = 0;
|
||||||
int bestScore = MinMax(bitboard, color, 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.PLY_DEPTH+" "+bestScore*100+" 0 "+nodesSearched+" "+bestMove);
|
||||||
}
|
}
|
||||||
@ -61,20 +61,20 @@ public class ComputerPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static int MinMax(Board bitboard, int color, int currentDepth) throws NotAValidSquare, NoPieceOnSquare {
|
private static int MinMax(Board bitboard, int currentDepth) throws NotAValidSquare, NoPieceOnSquare {
|
||||||
if (currentDepth >= SuicideChess.PLY_DEPTH) {
|
if (currentDepth >= SuicideChess.PLY_DEPTH) {
|
||||||
return bitboard.getBoardValue();
|
return bitboard.getBoardValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
nodesSearched++;
|
nodesSearched++;
|
||||||
|
|
||||||
Rules.legalMovesForPlayer(bitboard,color);
|
Rules.legalMovesForPlayer(bitboard);
|
||||||
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
|
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
|
||||||
if (allLegalMoves.size()==0) {
|
if (allLegalMoves.size()==0) {
|
||||||
allLegalMoves = Rules.getLegalMovesNonCapture();
|
allLegalMoves = Rules.getLegalMovesNonCapture();
|
||||||
}
|
}
|
||||||
if (allLegalMoves.size()==0) {
|
if (allLegalMoves.size()==0) {
|
||||||
if (color==Piece.BLACK) {
|
if (bitboard.getCurrentPlayer()==Piece.BLACK) {
|
||||||
return Board.BLACK_WINS;
|
return Board.BLACK_WINS;
|
||||||
} else {
|
} else {
|
||||||
return Board.WHITE_WINS;
|
return Board.WHITE_WINS;
|
||||||
@ -83,12 +83,12 @@ public class ComputerPlayer {
|
|||||||
int bestMoveIndex=0;
|
int bestMoveIndex=0;
|
||||||
int currentScore;
|
int currentScore;
|
||||||
int bestScoreSoFar;
|
int bestScoreSoFar;
|
||||||
if (color==Piece.BLACK) {
|
if (bitboard.getCurrentPlayer()==Piece.BLACK) {
|
||||||
bestScoreSoFar=Board.WHITE_WINS+1; //any move even a WHITE_WINS will be better than that
|
bestScoreSoFar=Board.WHITE_WINS+1; //any move even a WHITE_WINS will be better than that
|
||||||
for (int i=0; i<allLegalMoves.size(); i++) {
|
for (int i=0; i<allLegalMoves.size(); i++) {
|
||||||
Board boardCopy = new Board(bitboard);
|
Board boardCopy = new Board(bitboard);
|
||||||
boardCopy.doMove(allLegalMoves.get(i));
|
boardCopy.doMove(allLegalMoves.get(i));
|
||||||
currentScore=MinMax(boardCopy,Piece.WHITE,currentDepth+1);
|
currentScore=MinMax(boardCopy,currentDepth+1);
|
||||||
if (currentScore < bestScoreSoFar) { //black tries to minimise his score
|
if (currentScore < bestScoreSoFar) { //black tries to minimise his score
|
||||||
bestScoreSoFar = currentScore;
|
bestScoreSoFar = currentScore;
|
||||||
bestMoveIndex = i;
|
bestMoveIndex = i;
|
||||||
@ -99,7 +99,7 @@ public class ComputerPlayer {
|
|||||||
for (int i=0; i<allLegalMoves.size(); i++) {
|
for (int i=0; i<allLegalMoves.size(); i++) {
|
||||||
Board boardCopy = new Board(bitboard);
|
Board boardCopy = new Board(bitboard);
|
||||||
boardCopy.doMove(allLegalMoves.get(i));
|
boardCopy.doMove(allLegalMoves.get(i));
|
||||||
currentScore=MinMax(boardCopy,Piece.BLACK,currentDepth+1);
|
currentScore=MinMax(boardCopy,currentDepth+1);
|
||||||
if (currentScore > bestScoreSoFar) { //white tries to maximise his score
|
if (currentScore > bestScoreSoFar) { //white tries to maximise his score
|
||||||
bestScoreSoFar = currentScore;
|
bestScoreSoFar = currentScore;
|
||||||
bestMoveIndex = i;
|
bestMoveIndex = i;
|
||||||
|
@ -41,14 +41,14 @@ public class Rules {
|
|||||||
* @see Square
|
* @see Square
|
||||||
* @see Board
|
* @see Board
|
||||||
*/
|
*/
|
||||||
public static void legalMovesForPlayer(Board board, int color) throws NotAValidSquare {
|
public static void legalMovesForPlayer(Board board) throws NotAValidSquare {
|
||||||
legalMovesNonCapture = new ArrayList<Move>();
|
legalMovesNonCapture = new ArrayList<Move>();
|
||||||
legalMovesCapture = new ArrayList<Move>();
|
legalMovesCapture = new ArrayList<Move>();
|
||||||
|
|
||||||
Square square;
|
Square square;
|
||||||
for(int squareNb = 0; squareNb < Board.NB_OF_SQUARES; squareNb++) {
|
for(int squareNb = 0; squareNb < Board.NB_OF_SQUARES; squareNb++) {
|
||||||
square = new Square(squareNb);
|
square = new Square(squareNb);
|
||||||
if (board.isEmpty(square, new Piece(color))) {
|
if (board.isEmpty(square, new Piece(board.getCurrentPlayer()))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
legalMovesFromSquare(square,board);
|
legalMovesFromSquare(square,board);
|
||||||
|
@ -43,27 +43,7 @@ public class SuicideChess {
|
|||||||
/**
|
/**
|
||||||
* Number of Plies the computes searches to
|
* Number of Plies the computes searches to
|
||||||
*/
|
*/
|
||||||
public static final int PLY_DEPTH = 5;
|
public static final int PLY_DEPTH = 4;
|
||||||
|
|
||||||
/**
|
|
||||||
* The color of the current player
|
|
||||||
*/
|
|
||||||
private static int currentPlayerColor = Piece.WHITE;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the color of the current player
|
|
||||||
*/
|
|
||||||
public static void changeCurrentPlayerColor() {
|
|
||||||
if(currentPlayerColor==Piece.WHITE) {
|
|
||||||
currentPlayerColor=Piece.BLACK;
|
|
||||||
if (ASCII_GAME)
|
|
||||||
System.out.println("Black: ");
|
|
||||||
} else {
|
|
||||||
currentPlayerColor=Piece.WHITE;
|
|
||||||
if (ASCII_GAME)
|
|
||||||
System.out.println("White: ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test and display if the board is in a winning state.
|
* Test and display if the board is in a winning state.
|
||||||
@ -106,7 +86,6 @@ public class SuicideChess {
|
|||||||
* This function is used to undo the last position played
|
* This function is used to undo the last position played
|
||||||
*/
|
*/
|
||||||
private static Board removePlayedPosition () {
|
private static Board removePlayedPosition () {
|
||||||
changeCurrentPlayerColor();
|
|
||||||
allPlayedPositions.remove(0);
|
allPlayedPositions.remove(0);
|
||||||
return allPlayedPositions.get(0);
|
return allPlayedPositions.get(0);
|
||||||
}
|
}
|
||||||
@ -183,7 +162,7 @@ public class SuicideChess {
|
|||||||
//System.out.println("variant suicide");
|
//System.out.println("variant suicide");
|
||||||
break;
|
break;
|
||||||
case XBoardProtocol.HINT:
|
case XBoardProtocol.HINT:
|
||||||
System.out.println("Hint: "+ComputerPlayer.doRandomMove(bitboard,currentPlayerColor));
|
System.out.println("Hint: "+ComputerPlayer.doRandomMove(bitboard));
|
||||||
break;
|
break;
|
||||||
case XBoardProtocol.FORCE:
|
case XBoardProtocol.FORCE:
|
||||||
computerPlaying = false;
|
computerPlaying = false;
|
||||||
@ -223,8 +202,8 @@ public class SuicideChess {
|
|||||||
|
|
||||||
boolean needToCapture = false;
|
boolean needToCapture = false;
|
||||||
int foundMoveIndex = -1;
|
int foundMoveIndex = -1;
|
||||||
if(theMove.getMovingPiece().getColor() == currentPlayerColor) {
|
if(theMove.getMovingPiece().getColor() == bitboard.getCurrentPlayer()) {
|
||||||
Rules.legalMovesForPlayer(bitboard,currentPlayerColor);
|
Rules.legalMovesForPlayer(bitboard);
|
||||||
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
|
ArrayList<Move> allLegalMoves = Rules.getLegalMovesCapture();
|
||||||
if (allLegalMoves.size()==0) {
|
if (allLegalMoves.size()==0) {
|
||||||
allLegalMoves = Rules.getLegalMovesNonCapture();
|
allLegalMoves = Rules.getLegalMovesNonCapture();
|
||||||
@ -249,7 +228,6 @@ public class SuicideChess {
|
|||||||
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));
|
||||||
changeCurrentPlayerColor();
|
|
||||||
addPlayedPosition(bitboard);
|
addPlayedPosition(bitboard);
|
||||||
if (ASCII_GAME) {
|
if (ASCII_GAME) {
|
||||||
allLegalMoves.get(foundMoveIndex).display();
|
allLegalMoves.get(foundMoveIndex).display();
|
||||||
@ -279,11 +257,10 @@ public class SuicideChess {
|
|||||||
if (xBoardCommand==XBoardProtocol.GO)
|
if (xBoardCommand==XBoardProtocol.GO)
|
||||||
computerPlaying = true;
|
computerPlaying = true;
|
||||||
if (computerPlaying) {
|
if (computerPlaying) {
|
||||||
Move computerMove = ComputerPlayer.doMinMaxMove(bitboard,currentPlayerColor);
|
Move computerMove = ComputerPlayer.doMinMaxMove(bitboard);
|
||||||
bitboard.doMove(computerMove);
|
bitboard.doMove(computerMove);
|
||||||
addPlayedPosition(bitboard);
|
addPlayedPosition(bitboard);
|
||||||
XBoardProtocol.doMove(computerMove);
|
XBoardProtocol.doMove(computerMove);
|
||||||
changeCurrentPlayerColor();
|
|
||||||
if (ASCII_GAME) {
|
if (ASCII_GAME) {
|
||||||
computerMove.display();
|
computerMove.display();
|
||||||
System.out.println("Board value: "+bitboard.getBoardValue());
|
System.out.println("Board value: "+bitboard.getBoardValue());
|
||||||
|
Reference in New Issue
Block a user