bitboardanalyzerimpl.java
来自「chess 一个beguanyu国际象棋的一个Java源码」· Java 代码 · 共 549 行 · 第 1/2 页
JAVA
549 行
// It's important to start the test with the color that moves next! if( whiteHasMoveRight()) { if( isInCheck( true)) { // If the king of the moving player is in check, checkValue += BitBoardAnalyzer.BLACK_WIN; // the player seems to win. } if( isInCheck( false)) { // If the opponent's king is in check, checkValue += BitBoardAnalyzer.WHITE_WIN; // the opponent seems to win. } } else { if( isInCheck( false)) { // If the opponent's king is in check, checkValue += BitBoardAnalyzer.WHITE_WIN; // the opponent seems to win. } if( isInCheck( true)) { // If the king of the moving player is in check, checkValue += BitBoardAnalyzer.BLACK_WIN; // the player seems to win. } } // Early checks hinder the position building are punished therefore. if( getGame().getNumberOfPlies() < 12) { checkValue = (short)( checkValue / 4); } // Now compute the position and material value of all pieces. short materialValue = 0; // Count the figures and their material value. short positionalValue = 0; // Score the position value. // Check the entire board. // Use a bitmask to speedup the test for a piece on the square long emptySquareMask = getBoard().getEmptySquares(); // Get the positions of the white and black pawns. long [] pawnPos = new long[2]; pawnPos[0] = getBoard().getPositionOfPieces( Piece.PAWN << 1); pawnPos[1] = getBoard().getPositionOfPieces( Piece.PAWN << 1 | 1); // I reuse the same PositionImpl object to avoid the overhead of // object instancing for each square. Position pos = new PositionImpl(0); for( int i = 0; i < 64; i++) { if( ( emptySquareMask & 1) == 0) { // If there's a piece on the square pos.setSquareIndex( i); Piece p = getBoard().getPiece( pos); if( p != null) { short mValue = 0; short pValue = 0; // Add the value of the piece switch( p.getType()) { case Piece.PAWN: mValue = 10; pValue = _pawnPositionalValue[getGame().getNumberOfPlies() <= 12 ? 0 : 1][ p.isWhite() ? i : ( ( 7 - (i >>> 3)) << 3) + ( i & 7)]; // Check, if this pawn could be promoted if( p.isWhite()) { int j = i + 8; Position pos2 = new PositionImpl( 0); while( j < 64) { pos2.setSquareIndex( j); Piece p2 = getBoard().getPiece( pos2); if( p2 != null && p2.getType() == Piece.PAWN) { pValue -= 2; break; } j += 8; } } else { int j = i - 8; Position pos2 = new PositionImpl( 0); while( j >= 0) { pos2.setSquareIndex( j); Piece p2 = getBoard().getPiece( pos2); if( p2 != null && p2.getType() == Piece.PAWN) { pValue -= 2; break; } j += 8; } } break; case Piece.KNIGHT: pValue = _knightPositionalValue[getGame().getNumberOfPlies() <= 8 ? 0 : 1][ p.isWhite() ? i : ( ( 7 - (i >>> 3)) << 3) + ( i & 7)]; if( getGame().getNumberOfPlies() < 12) { // Check if this piece blocks a own pawn int row = i >>> 3; if( ( ( p.isWhite()) && ( ( row == 2) || ( row == 3)) && ( ( ( ( 1L << ( i - 8)) | ( 1L << ( i - 16))) & pawnPos[1]) != 0L)) || ( ! p.isWhite() && ( ( row == 4) || ( row == 5)) && ( ( ( ( 1L << ( i + 8)) | ( 1L << ( i + 16))) & pawnPos[0]) != 0L))) { pValue -= _pawnBlocker; } } mValue = 30; break; case Piece.BISHOP: pValue = _bishopPositionalValue[ getGame().getNumberOfPlies() <= 8 ? 0 : 1][ p.isWhite() ? i : ( ( 7 - (i >>> 3)) << 3) + ( i & 7)]; if( getGame().getNumberOfPlies() <= 12) { // Check if this piece blocks a own pawn int row = i >>> 3; if( ( ( p.isWhite()) && ( ( row == 2) || ( row == 3)) && ( ( ( ( 1L << ( i - 8)) | ( 1L << ( i - 16))) & pawnPos[1]) != 0L)) || ( ! p.isWhite() && ( ( row == 4) || ( row == 5)) && ( ( ( ( 1L << ( i + 8)) | ( 1L << ( i + 16))) & pawnPos[0]) != 0L))) { pValue -= _pawnBlocker; } } mValue = 30; break; case Piece.ROOK: mValue = 45; pValue = _rookPositionalValue[getGame().getNumberOfPlies() <= 8 ? 0 : 1][ p.isWhite() ? i : ( ( 7 - (i >>> 3)) << 3) + ( i & 7)]; break; case Piece.QUEEN: mValue = 80; pValue = _queenPositionalValue[getGame().getNumberOfPlies() <= 14 ? 0 : 1][ p.isWhite() ? i : ( ( 7 - (i >>> 3)) << 3) + ( i & 7)]; break; case Piece.KING: pValue = _kingPositionalValue[ p.isWhite() ? i : ( ( 7 - (i >>> 3)) << 3) + ( i & 7)]; break; } if( p.isWhite()) { materialValue += mValue; positionalValue += pValue; } else { materialValue -= mValue; positionalValue -= pValue; } } } // Shift the mask to test the next square emptySquareMask >>>= 1; } // Return a weighted score return (short)( (short)2 * positionalValue + (short)7 * materialValue + checkValue); } /** * Test, if the given player is in check. * * @param white Flag, if the white king is to test. * * @return true, if the king is in check, false otherwise. */ public final boolean isInCheck( boolean white) { // Get the position of the king. long kingPosition = getBoard().getPositionOfPieces( white ? Piece.KING << 1 | 1 : Piece.KING << 1 ); int kingSquare = BitUtils.getHighestBit( kingPosition); // Get and cache the empty squares of the current board. long emptySquares = getBoard().getEmptySquares(); // Now compute the moves backwards from the king's position. // Get all positions of bishops and queens long bishopPositions = getBoard().getPositionOfPieces( white ? Piece.BISHOP << 1 : ( Piece.BISHOP << 1) | 1); long queenPositions = getBoard().getPositionOfPieces( white ? Piece.QUEEN << 1 : ( Piece.QUEEN << 1) | 1); // The pieces, that attack diagonal long diagonalPositions = bishopPositions | queenPositions; // Move the king to the upper right. long kingMask = kingPosition; while( ( ( kingMask = ( ( kingMask & BitBoard._NOT_LINE_H & BitBoard._NOT_ROW_8) << 9)) & emptySquares) != 0L); if( ( kingMask & diagonalPositions) != 0L) { return true; // King is in check! } // Move the king to the lower right. kingMask = kingPosition; // Reset bitmask. while( ( ( kingMask = ( ( kingMask & BitBoard._NOT_LINE_A & BitBoard._NOT_ROW_1) >>> 7)) & emptySquares) != 0L); if( ( kingMask & diagonalPositions) != 0L) { return true; // King is in check! } // Move the king to the upper left. kingMask = kingPosition; // Reset bitmask. while( ( ( kingMask = ( ( kingMask & BitBoard._NOT_LINE_A & BitBoard._NOT_ROW_8) << 7)) & emptySquares) != 0L); if( ( kingMask & diagonalPositions) != 0L) { return true; // King is in check! } // Move the king to the lower left kingMask = kingPosition; // Reset bitmask. while( ( ( kingMask = ( ( kingMask & BitBoard._NOT_LINE_A & BitBoard._NOT_ROW_1) >>> 9)) & emptySquares) != 0L); if( ( kingMask & diagonalPositions) != 0L) { return true; // King is in check! } // Now we need the rooks, too. long rookPositions = getBoard().getPositionOfPieces( white ? Piece.ROOK << 1 : ( Piece.ROOK << 1) | 1); // The pieces, that attack horizontally or vertically. long horVertPositions = rookPositions | queenPositions; // Move the king downwards kingMask = kingPosition; // Reset bitmask. while( ( ( kingMask = ( ( kingMask & BitBoard._NOT_ROW_1) >>> 8)) & emptySquares) != 0L); if( ( kingMask & horVertPositions) != 0L) { return true; // King is in check! } // Move the king upwards kingMask = kingPosition; // Reset bitmask. while( ( ( kingMask = ( ( kingMask & BitBoard._NOT_ROW_8) << 8)) & emptySquares) != 0L); if( ( kingMask & horVertPositions) != 0L) { return true; // King is in check! } // Move the king to the left kingMask = kingPosition; // Reset bitmask. while( ( ( kingMask = ( ( kingMask & BitBoard._NOT_LINE_A) >>> 1)) & emptySquares) != 0L); if( ( kingMask & horVertPositions) != 0L) { return true; // King is in check! } // Move the king to the right kingMask = kingPosition; // Reset bitmask. while( ( ( kingMask = ( ( kingMask & BitBoard._NOT_LINE_H) << 1)) & emptySquares) != 0L); if( ( kingMask & horVertPositions) != 0L) { return true; // King is in check! } // Check, if the king is in check by a knight // Compute the knight moves backwards from the position of the // king and see, if there's a knight on this square. if( ( getPlyGenerator().getKnightPlies( kingSquare) & getBoard().getPositionOfPieces( white ? Piece.KNIGHT << 1 : ( Piece.KNIGHT << 1) | 1)) != 0L) { return true; } // Check if the king is in check by a pawn kingMask = kingPosition; // Reset bitmask. if( white) { // Get the positions of all black pawns and compare them with a moved king. return ( ( ( ( kingMask & BitBoard._NOT_LINE_H & BitBoard._NOT_ROW_8) << 9) | ( ( kingMask & BitBoard._NOT_LINE_A & BitBoard._NOT_ROW_8) << 7)) & getBoard().getPositionOfPieces( Piece.PAWN << 1)) != 0L; } else { // Get the positions of all white pawns and compare them with a moved king. return ( ( ( ( kingMask & BitBoard._NOT_LINE_A & BitBoard._NOT_ROW_1) >>> 7) | ( ( kingMask & BitBoard._NOT_LINE_A & BitBoard._NOT_ROW_1) >>> 9)) & getBoard().getPositionOfPieces( ( Piece.PAWN << 1) | 1)) != 0L; } } /** * Test if a king is in check on a given board. * * @param board The board to test. * @param white true, if the white king is checked, false otherwise. */ public final boolean isInCheck( BitBoard board, boolean white) { setBoard( board); return isInCheck( white); } /** * Analyzed a new board. * * @param board The new board to analyze. * @param white Flag to indicate, if white has the next move. */ public final short analyze( BitBoard board, boolean white) { setBoard( board); setMoveRight( white); return analyze(); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?