Version 0.5.6
============= Now has weights for each piece. Now detects endgame (uses different evaluation function)
This commit is contained in:
@ -31,6 +31,9 @@ public class Board {
|
|||||||
|
|
||||||
private static final int NB_OF_BITBOARDS = 14;
|
private static final int NB_OF_BITBOARDS = 14;
|
||||||
|
|
||||||
|
//with less than that many pawns on one side, the computer will enter endgame mode
|
||||||
|
public static final int ENDGAME = 3;
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class NoPieceOnSquare extends Exception {
|
public class NoPieceOnSquare extends Exception {
|
||||||
NoPieceOnSquare(String s) { super(s); };
|
NoPieceOnSquare(String s) { super(s); };
|
||||||
@ -83,11 +86,11 @@ public class Board {
|
|||||||
private boolean enPassant=false; //is there an 'en passant pawn' on the board
|
private boolean enPassant=false; //is there an 'en passant pawn' on the board
|
||||||
private Square enPassantSquare;
|
private Square enPassantSquare;
|
||||||
|
|
||||||
private int numberOfBlackPieces = NB_OF_FILES*2;
|
//the number of each piece type will be accessed
|
||||||
private int numberOfWhitePieces = NB_OF_FILES*2;
|
//using the index and the piece value defined in Piece class
|
||||||
private int[] numberOfPieces = new int[Piece.MAX_PIECE_NUMBER];
|
private int[] numberOfPieces;
|
||||||
{ numberOfPieces[Piece.BLACK_BISHOP]=2;
|
//the value of each piece (used for the evaluation function)
|
||||||
}
|
|
||||||
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.
|
private int currentPlayer; //color of the current player.
|
||||||
@ -105,6 +108,11 @@ public class Board {
|
|||||||
//the following line makes sure that enPassantSquare is defined at some point.
|
//the following line makes sure that enPassantSquare is defined at some point.
|
||||||
enPassantSquare = new Square("a1");
|
enPassantSquare = new Square("a1");
|
||||||
|
|
||||||
|
numberOfPieces = new int[Piece.MAX_PIECE_NUMBER+1];
|
||||||
|
for (int i=0; i<=Piece.MAX_PIECE_NUMBER; i++) {
|
||||||
|
numberOfPieces[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
bitBoards = new long[NB_OF_BITBOARDS];
|
bitBoards = new long[NB_OF_BITBOARDS];
|
||||||
addPiece(new Square("a1"),new Piece(Piece.WHITE_ROOK));
|
addPiece(new Square("a1"),new Piece(Piece.WHITE_ROOK));
|
||||||
addPiece(new Square("b1"),new Piece(Piece.WHITE_KNIGHT));
|
addPiece(new Square("b1"),new Piece(Piece.WHITE_KNIGHT));
|
||||||
@ -150,8 +158,11 @@ public class Board {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
public Board(Board bitboard) {
|
public Board(Board bitboard) {
|
||||||
this.numberOfBlackPieces = bitboard.numberOfBlackPieces;
|
numberOfPieces = new int[Piece.MAX_PIECE_NUMBER+1];
|
||||||
this.numberOfWhitePieces = bitboard.numberOfWhitePieces;
|
for (int i=0; i<=Piece.MAX_PIECE_NUMBER; i++) {
|
||||||
|
this.numberOfPieces[i] = bitboard.numberOfPieces[i];
|
||||||
|
}
|
||||||
|
|
||||||
this.boardValue = bitboard.boardValue;
|
this.boardValue = bitboard.boardValue;
|
||||||
this.bitBoards = new long[NB_OF_BITBOARDS];
|
this.bitBoards = new long[NB_OF_BITBOARDS];
|
||||||
for (int i=0; i<NB_OF_BITBOARDS; i++) {
|
for (int i=0; i<NB_OF_BITBOARDS; i++) {
|
||||||
@ -204,8 +215,8 @@ public class Board {
|
|||||||
enPassantSquare = new Square("a1"); //otherwise it is null
|
enPassantSquare = new Square("a1"); //otherwise it is null
|
||||||
}
|
}
|
||||||
|
|
||||||
numberOfBlackPieces = 0;
|
|
||||||
numberOfWhitePieces = 0;
|
numberOfPieces = new int[Piece.MAX_PIECE_NUMBER];
|
||||||
|
|
||||||
for(int split=0; split < 8; split++) {
|
for(int split=0; split < 8; split++) {
|
||||||
int offset=0;
|
int offset=0;
|
||||||
@ -216,19 +227,14 @@ public class Board {
|
|||||||
} else {
|
} else {
|
||||||
Piece pieceToAdd = new Piece(rowToParse[character]);
|
Piece pieceToAdd = new Piece(rowToParse[character]);
|
||||||
addPiece(new Square(character+offset+1,NB_OF_RANKS-split),pieceToAdd);
|
addPiece(new Square(character+offset+1,NB_OF_RANKS-split),pieceToAdd);
|
||||||
if (pieceToAdd.getColor()==Piece.BLACK) {
|
|
||||||
numberOfBlackPieces++;
|
|
||||||
} else {
|
|
||||||
numberOfWhitePieces++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (numberOfBlackPieces == 0) {
|
if (numberOfPieces[Piece.BLACK] == 0) {
|
||||||
boardValue = BLACK_WINS;
|
boardValue = BLACK_WINS;
|
||||||
} else if (numberOfWhitePieces == 0){
|
} else if (numberOfPieces[Piece.WHITE] == 0){
|
||||||
boardValue = WHITE_WINS;
|
boardValue = WHITE_WINS;
|
||||||
} else if (!Rules.isThereALegalMovesForPlayer(this)) {
|
} else if (!Rules.isThereALegalMovesForPlayer(this)) {
|
||||||
if (currentPlayer==Piece.WHITE) {
|
if (currentPlayer==Piece.WHITE) {
|
||||||
@ -466,6 +472,7 @@ public class Board {
|
|||||||
System.out.println(" +---+---+---+---+---+---+---+---+");
|
System.out.println(" +---+---+---+---+---+---+---+---+");
|
||||||
System.out.println(" a b c d e f g h");
|
System.out.println(" a b c d e f g h");
|
||||||
System.out.println();
|
System.out.println();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -488,6 +495,9 @@ public class Board {
|
|||||||
bitBoards[piece.getPieceNumber()] |= mapSquaresToBits[squareToBitBoardSquare(square)];
|
bitBoards[piece.getPieceNumber()] |= mapSquaresToBits[squareToBitBoardSquare(square)];
|
||||||
//update the bitboard of all pieces of that color
|
//update the bitboard of all pieces of that color
|
||||||
bitBoards[piece.getColor()] |= mapSquaresToBits[squareToBitBoardSquare(square)];
|
bitBoards[piece.getColor()] |= mapSquaresToBits[squareToBitBoardSquare(square)];
|
||||||
|
|
||||||
|
numberOfPieces[piece.getPieceNumber()] += 1;
|
||||||
|
numberOfPieces[piece.getColor()] += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void removePiece(Square square, Piece piece) throws NoPieceOnSquare {
|
protected void removePiece(Square square, Piece piece) throws NoPieceOnSquare {
|
||||||
@ -508,6 +518,9 @@ public class Board {
|
|||||||
}
|
}
|
||||||
//update the bitboard of all pieces of that color
|
//update the bitboard of all pieces of that color
|
||||||
bitBoards[piece.getColor()] ^= mapSquaresToBits[squareToBitBoardSquare(square)];;
|
bitBoards[piece.getColor()] ^= mapSquaresToBits[squareToBitBoardSquare(square)];;
|
||||||
|
|
||||||
|
numberOfPieces[piece.getPieceNumber()] -= 1;
|
||||||
|
numberOfPieces[piece.getColor()] -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//used by function display()
|
//used by function display()
|
||||||
@ -522,18 +535,25 @@ public class Board {
|
|||||||
private void evaluateNewBoardValue (Move move) throws NotAValidSquare {
|
private void evaluateNewBoardValue (Move move) throws NotAValidSquare {
|
||||||
|
|
||||||
if (move.isCaptureMove()) {
|
if (move.isCaptureMove()) {
|
||||||
if (move.getCapturedPiece().getColor()==Piece.BLACK) {
|
if (numberOfPieces[Piece.BLACK] == 0) {
|
||||||
numberOfBlackPieces--;
|
|
||||||
} else {
|
|
||||||
numberOfWhitePieces--;
|
|
||||||
}
|
|
||||||
if (numberOfBlackPieces == 0) {
|
|
||||||
boardValue = BLACK_WINS;
|
boardValue = BLACK_WINS;
|
||||||
} else if (numberOfWhitePieces == 0){
|
} else if (numberOfPieces[Piece.WHITE] == 0){
|
||||||
boardValue = WHITE_WINS;
|
boardValue = WHITE_WINS;
|
||||||
} else {
|
} else {
|
||||||
//this is a very very basic evaluation function that will be changed.
|
//this is a very very basic evaluation function that will be changed.
|
||||||
boardValue = numberOfBlackPieces - numberOfWhitePieces;
|
//boardValue = numberOfBlackPieces - numberOfWhitePieces;
|
||||||
|
boardValue = 0;
|
||||||
|
if((numberOfPieces[Piece.BLACK_PAWN] <= ENDGAME) || (numberOfPieces[Piece.WHITE_PAWN] <= ENDGAME)) {
|
||||||
|
System.out.println("Playing endgame");
|
||||||
|
for (int i = Piece.OFFSET; i<=Piece.MAX_PIECE_NUMBER; i++) {
|
||||||
|
boardValue += numberOfPieces[i]*Piece.PIECE_VALUE_ENDGAME[i];
|
||||||
|
}
|
||||||
|
} 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];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Rules.isThereALegalMovesForPlayer(this)) {
|
if (!Rules.isThereALegalMovesForPlayer(this)) {
|
||||||
|
@ -48,6 +48,9 @@ public class Piece {
|
|||||||
public static final int BLACK_ROOK = 2*(ROOK+1) + BLACK;
|
public static final int BLACK_ROOK = 2*(ROOK+1) + BLACK;
|
||||||
|
|
||||||
public static final int MAX_PIECE_NUMBER = BLACK_ROOK;
|
public static final int MAX_PIECE_NUMBER = BLACK_ROOK;
|
||||||
|
//offset used for table indexing
|
||||||
|
public static final int OFFSET = WHITE_PAWN;
|
||||||
|
|
||||||
public static final int NB_OF_PIECES = ROOK + 1;
|
public static final int NB_OF_PIECES = ROOK + 1;
|
||||||
|
|
||||||
//Constants used for promotion (as used in the xboard protocol)
|
//Constants used for promotion (as used in the xboard protocol)
|
||||||
@ -71,6 +74,36 @@ public class Piece {
|
|||||||
public static final char BLACK_ROOK_CHAR='r';
|
public static final char BLACK_ROOK_CHAR='r';
|
||||||
public static final char BLACK_PAWN_CHAR='p';
|
public static final char BLACK_PAWN_CHAR='p';
|
||||||
|
|
||||||
|
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[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[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];
|
||||||
|
PIECE_VALUE_ENDGAME[BLACK_KNIGHT]=-PIECE_VALUE_ENDGAME[WHITE_KNIGHT];
|
||||||
|
PIECE_VALUE_ENDGAME[BLACK_BISHOP]=-PIECE_VALUE_ENDGAME[WHITE_BISHOP];
|
||||||
|
PIECE_VALUE_ENDGAME[BLACK_PAWN]=-PIECE_VALUE_ENDGAME[WHITE_PAWN];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*==============*
|
/*==============*
|
||||||
* PRIVATE DATA *
|
* PRIVATE DATA *
|
||||||
|
@ -33,7 +33,7 @@ public class SuicideChess {
|
|||||||
/**
|
/**
|
||||||
* The name to be displayed
|
* The name to be displayed
|
||||||
*/
|
*/
|
||||||
public static final String NAME = "djib's SuShi v0.5.2";
|
public static final String NAME = "djib's SuShi v0.5.5";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Displays informations in the console.
|
* Displays informations in the console.
|
||||||
|
Reference in New Issue
Block a user