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 + -
显示快捷键?