📄 jcboard.java
字号:
// First, look for the number of pieces on the board tok.nextToken(); int numPieces = (int) tok.nval; // Now, loop on the pieces in question for( int i = 0; i < numPieces; i++ ) { // What kind of piece is this, and where does it go? tok.nextToken(); String whichPieceStr = tok.sval; int whichPiece = 0; while ( !whichPieceStr.equalsIgnoreCase( PieceStrings[ whichPiece ] ) ) whichPiece++; tok.nextToken(); int whichSquare = (int) tok.nval; // Add the piece to the board AddPiece( whichSquare, whichPiece ); } // Now, read the castling status flags for( int i = 0; i < 4; i++ ) { tok.nextToken(); if ( "TRUE".equalsIgnoreCase( tok.sval ) ) SetCastlingStatus( i, true ); else SetCastlingStatus( i, false ); } // And finally, read the bitboard representing the position of the en // passant pawn, if any tok.nextToken(); SetEnPassantPawn( (long) tok.nval ); fr.close(); return true; } // public boolean Save // Save the state of the game to a file public boolean Save( String fileName ) throws Exception { // Open the file for business FileWriter fr = new FileWriter( fileName ); BufferedWriter bw = new BufferedWriter( fr ); // Whose turn is it? bw.write( jcPlayer.PlayerStrings[ CurrentPlayer ] ); bw.newLine(); // Count the pieces on the board int numPieces = 0; for( int i = 0; i < ALL_SQUARES; i++ ) { if ( ( SquareBits[ i ] & BitBoards[ ALL_WHITE_PIECES ] ) != 0 ) numPieces++; if ( ( SquareBits[ i ] & BitBoards[ ALL_BLACK_PIECES ] ) != 0 ) numPieces++; } bw.write( String.valueOf( numPieces ) ); bw.newLine(); // Dump the pieces, one by one for( int piece = 0; piece < ALL_PIECES; piece++ ) { for( int square = 0; square < ALL_SQUARES; square++ ) { if ( ( BitBoards[ piece ] & SquareBits[ square ] ) != 0 ) { bw.write( PieceStrings[ piece ] + " " + String.valueOf( square ) ); bw.newLine(); } } } // And finally, dump the castling status and the en passant pawn for( int i = 0; i < 4; i++ ) { if ( CastlingStatus[ i ] ) bw.write( "TRUE" ); else bw.write( "FALSE" ); bw.newLine(); } bw.write( String.valueOf( EnPassantPawn ) ); bw.close(); return true; } // public int EvalMaterial // Compute the board's material balance, from the point of view of the "side" // player. This is an exact clone of the eval function in CHESS 4.5 public int EvalMaterial( int side ) { // If both sides are equal, no need to compute anything! if ( MaterialValue[ jcPlayer.SIDE_BLACK ] == MaterialValue[ jcPlayer.SIDE_WHITE ] ) return 0; int otherSide = ( side + 1 ) % 2; int matTotal = MaterialValue[ side ] + MaterialValue[ otherSide ]; // Who is leading the game, material-wise? if ( MaterialValue[ jcPlayer.SIDE_BLACK ] > MaterialValue[ jcPlayer.SIDE_WHITE ] ) { // Black leading int matDiff = MaterialValue[ jcPlayer.SIDE_BLACK ] - MaterialValue[ jcPlayer.SIDE_WHITE ]; int val = Math.min( 2400, matDiff ) + ( matDiff * ( 12000 - matTotal ) * NumPawns[ jcPlayer.SIDE_BLACK ] ) / ( 6400 * ( NumPawns[ jcPlayer.SIDE_BLACK ] + 1 ) ); if ( side == jcPlayer.SIDE_BLACK ) return val; else return -val; } else { // White leading int matDiff = MaterialValue[ jcPlayer.SIDE_WHITE ] - MaterialValue[ jcPlayer.SIDE_BLACK ]; int val = Math.min( 2400, matDiff ) + ( matDiff * ( 12000 - matTotal ) * NumPawns[ jcPlayer.SIDE_WHITE ] ) / ( 6400 * ( NumPawns[ jcPlayer.SIDE_WHITE ] + 1 ) ); if ( side == jcPlayer.SIDE_WHITE ) return val; else return -val; } } // public boolean StartingBoard // Restore the board to a game-start position public boolean StartingBoard() { // Put the pieces on the board EmptyBoard(); AddPiece( 0, BLACK_ROOK ); AddPiece( 1, BLACK_KNIGHT ); AddPiece( 2, BLACK_BISHOP ); AddPiece( 3, BLACK_QUEEN ); AddPiece( 4, BLACK_KING ); AddPiece( 5, BLACK_BISHOP ); AddPiece( 6, BLACK_KNIGHT ); AddPiece( 7, BLACK_ROOK ); for( int i = 8; i < 16; i++ ) { AddPiece( i, BLACK_PAWN ); } for( int i = 48; i < 56; i++ ) { AddPiece( i, WHITE_PAWN ); } AddPiece( 56, WHITE_ROOK ); AddPiece( 57, WHITE_KNIGHT ); AddPiece( 58, WHITE_BISHOP ); AddPiece( 59, WHITE_QUEEN ); AddPiece( 60, WHITE_KING ); AddPiece( 61, WHITE_BISHOP ); AddPiece( 62, WHITE_KNIGHT ); AddPiece( 63, WHITE_ROOK ); // And allow all castling moves for( int i = 0; i < 4; i++ ) { CastlingStatus[ i ] = true; } HasCastled[ 0 ] = false; HasCastled[ 1 ] = false; ClearEnPassantPawn(); // And ask White to play the first move SetCurrentPlayer( jcPlayer.SIDE_WHITE ); return true; }/****************************************************************************** * PRIVATE METHODS *****************************************************************************/ // private boolean AddPiece // Place a specific piece on a specific board square private boolean AddPiece( int whichSquare, int whichPiece ) { // Add the piece itself BitBoards[ whichPiece ] |= SquareBits[ whichSquare ]; // And note the new piece position in the bitboard containing all // pieces of its color. Here, we take advantage of the fact that // all pieces of a given color are represented by numbers of the same // parity BitBoards[ ALL_PIECES + ( whichPiece % 2 ) ] |= SquareBits[ whichSquare ]; // And adjust material balance accordingly MaterialValue[ whichPiece % 2 ] += PieceValues[ whichPiece ]; if ( whichPiece == WHITE_PAWN ) NumPawns[ jcPlayer.SIDE_WHITE ]++; else if ( whichPiece == BLACK_PAWN ) NumPawns[ jcPlayer.SIDE_BLACK ]++; return true; } // private boolean RemovePiece // Eliminate a specific piece from a specific square on the board // Note that you MUST know that the piece is there before calling this, // or the results will not be what you expect! private boolean RemovePiece( int whichSquare, int whichPiece ) { // Remove the piece itself BitBoards[ whichPiece ] ^= SquareBits[ whichSquare ]; BitBoards[ ALL_PIECES + ( whichPiece % 2 ) ] ^= SquareBits[ whichSquare ]; // And adjust material balance accordingly MaterialValue[ whichPiece % 2 ] -= PieceValues[ whichPiece ]; if ( whichPiece == WHITE_PAWN ) NumPawns[ jcPlayer.SIDE_WHITE ]--; else if ( whichPiece == BLACK_PAWN ) NumPawns[ jcPlayer.SIDE_BLACK ]--; return true; } // private boolean EmptyBoard // Remove every piece from the board private boolean EmptyBoard() { for( int i = 0; i < ALL_BITBOARDS; i++ ) { BitBoards[ i ] = 0; } ExtraKings[ 0 ] = 0; ExtraKings[ 1 ] = 0; EnPassantPawn = 0; MaterialValue[ 0 ] = 0; MaterialValue[ 1 ] = 0; NumPawns[ 0 ] = 0; NumPawns[ 1 ] = 0; return true; } // private boolean SetCastlingStatus // Change one of the "castling status" flags // parameter whichFlag should be a sum of a side marker and a castling // move identifier, for example, jcPlayer.SIDE_WHITE + CASTLE_QUEENSIDE private boolean SetCastlingStatus( int whichFlag, boolean newValue ) { CastlingStatus[ whichFlag ] = newValue; return true; } // private boolean SetEnPassantPawn // If a pawn move has just made en passant capture possible, mark it as // such in a bitboard (containing the en passant square only) private boolean SetEnPassantPawn( int square ) { ClearEnPassantPawn(); EnPassantPawn |= SquareBits[ square ]; return true; } private boolean SetEnPassantPawn( long bitboard ) { EnPassantPawn = bitboard; return true; } // private boolean ClearEnPassantPawn // Indicates that there is no en passant square at all. Technically, this // job could have been handled by SetEnPassaantPawn( long ) with a null // parameter, but I have chosen to add a method to avoid problems if I ever // forgot to specify 0L: using 0 would call the first form of the Set method // and indicate an en passant pawn in a corner of the board, with possibly // disastrous consequences! private boolean ClearEnPassantPawn() { EnPassantPawn = 0; return true; } // private boolean SetCurrentPlayer // Whose turn is it? private boolean SetCurrentPlayer( int which ) { CurrentPlayer = which; return true; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -