📄 jcboard.java
字号:
/***************************************************************************** * jcBoard.java - Encapsulation of a chess board * by Fran鏾is Dominic Laram閑 * * Purpose: This object contains all of the data and methods required to * process a chess board in the game. It uses the ubiquitous "bitboard" * representation. * * History: * 08.06.00 Created * 14.08.00 Made "HashLock" a relative clone of "HashKey"; the java * Object.hashCode method is unsuitable to our purposes after all, * probably because it includes memory addresses in the calculation. ***************************************************************************/package javachess;import java.util.Random;import java.io.*;/**************************************************************************** * public class jcBoard * * Notes: * 1. The squares are numbered line by line, starting in the corner occupied by * Black's Queen's Rook at the beginning of the game. There are no constants * to represent squares, as they are usually manipulated algorithmically, in * sequences, instead of being explicitly identified in the code. ***************************************************************************/public class jcBoard{/*************************************************************************** * CONSTANTS **************************************************************************/ // Codes representing pieces public static final int PAWN = 0; public static final int KNIGHT = 2; public static final int BISHOP = 4; public static final int ROOK = 6; public static final int QUEEN = 8; public static final int KING = 10; public static final int WHITE_PAWN = PAWN + jcPlayer.SIDE_WHITE; public static final int WHITE_KNIGHT = KNIGHT + jcPlayer.SIDE_WHITE; public static final int WHITE_BISHOP = BISHOP + jcPlayer.SIDE_WHITE; public static final int WHITE_ROOK = ROOK + jcPlayer.SIDE_WHITE; public static final int WHITE_QUEEN = QUEEN + jcPlayer.SIDE_WHITE; public static final int WHITE_KING = KING + jcPlayer.SIDE_WHITE; public static final int BLACK_PAWN = PAWN + jcPlayer.SIDE_BLACK; public static final int BLACK_KNIGHT = KNIGHT + jcPlayer.SIDE_BLACK; public static final int BLACK_BISHOP = BISHOP + jcPlayer.SIDE_BLACK; public static final int BLACK_ROOK = ROOK + jcPlayer.SIDE_BLACK; public static final int BLACK_QUEEN = QUEEN + jcPlayer.SIDE_BLACK; public static final int BLACK_KING = KING + jcPlayer.SIDE_BLACK; public static final int EMPTY_SQUARE = 12; // Useful loop boundary constants, to allow looping on all bitboards and // on all squares of a chessboard public static final int ALL_PIECES = 12; public static final int ALL_SQUARES = 64; // Indices of the "shortcut" bitboards containing information on "all black // pieces" and "all white pieces" public static final int ALL_WHITE_PIECES = ALL_PIECES + jcPlayer.SIDE_WHITE; public static final int ALL_BLACK_PIECES = ALL_PIECES + jcPlayer.SIDE_BLACK; public static final int ALL_BITBOARDS = 14; // The possible types of castling moves; add the "side" constant to // pick a specific move for a specific player public static final int CASTLE_KINGSIDE = 0; public static final int CASTLE_QUEENSIDE = 2;/*************************************************************************** * DATA MEMBERS **************************************************************************/ // An array of bitfields, each of which contains the single bit associated // with a square in a bitboard public static long SquareBits[]; // Private table of random numbers used to compute Zobrist hash values // Contains a signature for any kind of piece on any square of the board private static int HashKeyComponents[][]; private static int HashLockComponents[][]; // Private table of tokens (string representations) for all pieces public static String PieceStrings[]; // Data needed to compute the evaluation function private int MaterialValue[ ]; private int NumPawns[ ]; private static int PieceValues[ ]; // And a few flags for special conditions. The ExtraKings are a device // used to detect illegal castling moves: the rules of chess forbid castling // when the king is in check or when the square it flies over is under // attack; therefore, we add "phantom kings" to the board for one move only, // and if the opponent can capture one of them with its next move, then // castling was illegal and search can be cancelled private long ExtraKings[]; public static long EXTRAKINGS_WHITE_KINGSIDE; public static long EXTRAKINGS_WHITE_QUEENSIDE; public static long EXTRAKINGS_BLACK_KINGSIDE; public static long EXTRAKINGS_BLACK_QUEENSIDE; public static long EMPTYSQUARES_WHITE_KINGSIDE; public static long EMPTYSQUARES_WHITE_QUEENSIDE; public static long EMPTYSQUARES_BLACK_KINGSIDE; public static long EMPTYSQUARES_BLACK_QUEENSIDE; // static member initialization static { // Build the SquareBits constants SquareBits = new long[ ALL_SQUARES ]; for( int i = 0; i < ALL_SQUARES; i++ ) { // Note: the 1L specifies that the 1 we are shifting is a long int // Java would, by default, make it a 4-byte int and be unable to // shift the 1 to bits 32 to 63 SquareBits[ i ] = ( 1L << i ); } // Build the extrakings constants EXTRAKINGS_WHITE_KINGSIDE = SquareBits[ 60 ] | SquareBits[ 61 ]; EXTRAKINGS_WHITE_QUEENSIDE = SquareBits[ 60 ] | SquareBits[ 59 ]; EXTRAKINGS_BLACK_KINGSIDE = SquareBits[ 4 ] | SquareBits[ 5 ]; EXTRAKINGS_BLACK_QUEENSIDE = SquareBits[ 4 ] | SquareBits[ 3 ]; EMPTYSQUARES_WHITE_KINGSIDE = SquareBits[ 61 ] | SquareBits[ 62 ]; EMPTYSQUARES_WHITE_QUEENSIDE = SquareBits[ 59 ] | SquareBits[ 58 ] | SquareBits[ 57 ]; EMPTYSQUARES_BLACK_KINGSIDE = SquareBits[ 5 ] | SquareBits[ 6 ]; EMPTYSQUARES_BLACK_QUEENSIDE = SquareBits[ 3 ] | SquareBits[ 2 ] | SquareBits[ 1 ]; // Build the hashing database HashKeyComponents = new int[ ALL_PIECES ][ ALL_SQUARES ]; HashLockComponents = new int[ ALL_PIECES ][ ALL_SQUARES ]; Random rnd = new Random(); for( int i = 0; i < ALL_PIECES; i++ ) { for( int j = 0; j < ALL_SQUARES; j++ ) { HashKeyComponents[ i ][ j ] = rnd.nextInt(); HashLockComponents[ i ][ j ] = rnd.nextInt(); } } // Tokens representing the various concepts in the game, for printint // and file i/o purposes // PieceStrings contains an extra string representing empty squares PieceStrings = new String[ ALL_PIECES + 1 ]; PieceStrings[ WHITE_PAWN ] = "WP"; PieceStrings[ WHITE_ROOK ] = "WR"; PieceStrings[ WHITE_KNIGHT ] = "WN"; PieceStrings[ WHITE_BISHOP ] = "WB"; PieceStrings[ WHITE_QUEEN ] = "WQ"; PieceStrings[ WHITE_KING ] = "WK"; PieceStrings[ BLACK_PAWN ] = "BP"; PieceStrings[ BLACK_ROOK ] = "BR"; PieceStrings[ BLACK_KNIGHT ] = "BN"; PieceStrings[ BLACK_BISHOP ] = "BB"; PieceStrings[ BLACK_QUEEN ] = "BQ"; PieceStrings[ BLACK_KING ] = "BK"; PieceStrings[ ALL_PIECES ] = " "; // Numerical evaluation of piece material values PieceValues = new int[ ALL_PIECES ]; PieceValues[ WHITE_PAWN ] = 100; PieceValues[ BLACK_PAWN ] = 100; PieceValues[ WHITE_KNIGHT ] = 300; PieceValues[ BLACK_KNIGHT ] = 300; PieceValues[ WHITE_BISHOP ] = 350; PieceValues[ BLACK_BISHOP ] = 350; PieceValues[ WHITE_ROOK ] = 500; PieceValues[ BLACK_ROOK ] = 500; PieceValues[ BLACK_QUEEN ] = 900; PieceValues[ WHITE_QUEEN ] = 900; PieceValues[ WHITE_KING ] = 2000; PieceValues[ BLACK_KING ] = 2000; } // The actual data representation of a chess board. First, an array of // bitboards, each of which contains flags for the squares where you can // find a specific type of piece private long BitBoards[]; // And a few other flags private boolean CastlingStatus[]; private boolean HasCastled[]; private long EnPassantPawn; // Whose turn is it? int CurrentPlayer;/************************************************************************** * METHODS **************************************************************************/ // Accessors public boolean GetCastlingStatus( int which ) { return CastlingStatus[ which ]; } public boolean GetHasCastled( int which ) { return HasCastled[ which ]; } public long GetEnPassantPawn() { return EnPassantPawn; } public long GetExtraKings( int side ) { return ExtraKings[ side ]; } public void SetExtraKings( int side, long val ) { // Mark a few squares as containing "phantom kings" to detect illegal // castling ExtraKings[ side ] = val; BitBoards[ KING + side ] |= ExtraKings[ side ]; BitBoards[ ALL_PIECES + side ] |= ExtraKings[ side ]; } public void ClearExtraKings( int side ) { BitBoards[ KING + side ] ^= ExtraKings[ side ]; BitBoards[ ALL_PIECES + side ] ^= ExtraKings[ side ]; // Note: one of the Extra Kings is superimposed on the rook involved in // the castling, so the next step is required to prevent ALL_PIECES from // forgetting about the rook at the same time as the phantom king BitBoards[ ALL_PIECES + side ] |= BitBoards[ ROOK + side ]; ExtraKings[ side ] = 0; } public int GetCurrentPlayer() { return CurrentPlayer; } public long GetBitBoard( int which ) { return BitBoards[ which ]; } // Look for the piece located on a specific square public int FindBlackPiece( int square ) { // Note: we look for kings first for two reasons: because it helps // detect check, and because there may be a phantom king (marking an // illegal castling move) and a rook on the same square! if ( ( BitBoards[ BLACK_KING ] & SquareBits[ square ] ) != 0 ) return BLACK_KING; if ( ( BitBoards[ BLACK_QUEEN ] & SquareBits[ square ] ) != 0 ) return BLACK_QUEEN; if ( ( BitBoards[ BLACK_ROOK ] & SquareBits[ square ] ) != 0 ) return BLACK_ROOK; if ( ( BitBoards[ BLACK_KNIGHT ] & SquareBits[ square ] ) != 0 ) return BLACK_KNIGHT; if ( ( BitBoards[ BLACK_BISHOP ] & SquareBits[ square ] ) != 0 ) return BLACK_BISHOP; if ( ( BitBoards[ BLACK_PAWN ] & SquareBits[ square ] ) != 0 ) return BLACK_PAWN; return EMPTY_SQUARE; } public int FindWhitePiece( int square ) { if ( ( BitBoards[ WHITE_KING ] & SquareBits[ square ] ) != 0 ) return WHITE_KING; if ( ( BitBoards[ WHITE_QUEEN ] & SquareBits[ square ] ) != 0 ) return WHITE_QUEEN; if ( ( BitBoards[ WHITE_ROOK ] & SquareBits[ square ] ) != 0 ) return WHITE_ROOK; if ( ( BitBoards[ WHITE_KNIGHT ] & SquareBits[ square ] ) != 0 ) return WHITE_KNIGHT; if ( ( BitBoards[ WHITE_BISHOP ] & SquareBits[ square ] ) != 0 ) return WHITE_BISHOP; if ( ( BitBoards[ WHITE_PAWN ] & SquareBits[ square ] ) != 0 ) return WHITE_PAWN; return EMPTY_SQUARE; } // Constructor public jcBoard() { BitBoards = new long[ ALL_BITBOARDS ]; CastlingStatus = new boolean[ 4 ]; HasCastled = new boolean[ 2 ]; ExtraKings = new long[ 2 ]; NumPawns = new int[ 2 ]; MaterialValue = new int[ 2 ]; StartingBoard(); } // public boolean Clone // Make a deep copy of a jcBoard object; assumes that memory has already // been allocated for the new object, which is always true since we // "allocate" jcBoards from a permanent array public boolean Clone( jcBoard target ) { EnPassantPawn = target.EnPassantPawn; for( int i = 0; i < 4; i++ ) { CastlingStatus[ i ] = target.CastlingStatus[ i ]; } for( int i = 0; i < ALL_BITBOARDS; i++ ) { BitBoards[ i ] = target.BitBoards[ i ]; } MaterialValue[ 0 ] = target.MaterialValue[ 0 ]; MaterialValue[ 1 ] = target.MaterialValue[ 1 ]; NumPawns[ 0 ] = target.NumPawns[ 0 ]; NumPawns[ 1 ] = target.NumPawns[ 1 ]; ExtraKings[ 0 ] = target.ExtraKings[ 0 ]; ExtraKings[ 1 ] = target.ExtraKings[ 1 ];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -