📄 plygenerator.java
字号:
// Since a queen can move like a bishop or rook, // I simply add the plies of both for this position. addPliesForBishopPos( square); addPliesForRookPos( square); } /** * Add all the plies for the king of the current color. */ private final void addPliesForKing() { long opponentKingPosition = getBoard().getPositionOfPieces( _white ? Piece.KING << 1 : Piece.KING << 1 | 1 ); int highestBit = BitUtils.getHighestBit( getBoard().getPositionOfPieces( _white ? (Piece.KING << 1) + 1 : Piece.KING << 1 )); long restrictedSquares = _kingMask[ BitUtils.getHighestBit( opponentKingPosition)]; long curMoves = _kingMask[ highestBit] & (_emptySquares | _attackablePieces) & ~restrictedSquares; int startBitRange = highestBit - 9; if( startBitRange < 0) { startBitRange = 0; } int endBitRange = highestBit + 9; if( endBitRange > 63) { endBitRange = 63; } addAbsolutePlies( curMoves, startBitRange, endBitRange, highestBit); // Check for castling if( _white) { // If the king has not been moved and is not in check if( !getGame().hasBeenMoved( new PositionImpl( 4)) && !getAnalyzer().isInCheck( getBoard(), true)) { long rookPositions = getBoard().getPositionOfPieces( ( Piece.ROOK << 1) + 1); if( !getGame().hasBeenMoved( new PositionImpl( 0)) && ( ( _emptySquares & 0xEL) == 0xEL) && ( !getAnalyzer().isInCheck( (BitBoard)(getBoard().getBoardAfterPly( new PlyImpl( new PositionImpl(4), new PositionImpl(3)))), true) /* && !getAnalyzer().isInCheck( (BitBoard)(getBoard().getBoardAfterPly( new PlyImpl( new PositionImpl(4), new PositionImpl(2)))), true) */ )) { // The addPly method checks for this check anyway, so it can be outcommented here... addCastlingPly( 4, true); } if( !getGame().hasBeenMoved( new PositionImpl( 7)) && ( ( _emptySquares & 0x60L) == 0x60L) && ( !getAnalyzer().isInCheck( (BitBoard)(getBoard().getBoardAfterPly( new PlyImpl( new PositionImpl(4), new PositionImpl(5)))), true) /* && !getAnalyzer().isInCheck( (BitBoard)(getBoard().getBoardAfterPly( new PlyImpl( new PositionImpl(4), new PositionImpl(6)))), true) */ )) { addCastlingPly( 4, false); } } } else { if( !getGame().hasBeenMoved( new PositionImpl( 60)) && !getAnalyzer().isInCheck( getBoard(), false)) { long rookPositions = getBoard().getPositionOfPieces( Piece.ROOK << 1); if( !getGame().hasBeenMoved( new PositionImpl( 56)) && ( ( _emptySquares & ( 0xEL << 56)) == ( 0xEL << 56)) && ( !getAnalyzer().isInCheck( (BitBoard)(getBoard().getBoardAfterPly( new PlyImpl( new PositionImpl(60), new PositionImpl(59)))), false) /* && !getAnalyzer().isInCheck( (BitBoard)(getBoard().getBoardAfterPly( new PlyImpl( new PositionImpl(60), new PositionImpl(58)))), false) */ )) { addCastlingPly( 4 + 56, true); } if( getGame().hasBeenMoved( new PositionImpl( 63)) && ( ( _emptySquares & 0x60L) == 0x60L) && ( !getAnalyzer().isInCheck( (BitBoard)(getBoard().getBoardAfterPly( new PlyImpl( new PositionImpl(60), new PositionImpl(61)))), false) /* && !getAnalyzer().isInCheck( (BitBoard)(getBoard().getBoardAfterPly( new PlyImpl( new PositionImpl(60), new PositionImpl(62)))), false) */)) { addCastlingPly( 4 + 56, false); } } } } /** * Convert a bitmask to a series of relative plies. * We pass the destination fields here along with a offset to compute the source square. * * @param destinationPos The destination positions for all the plies. * @param int startBit The bit to start scanning from. * @param int endBit The bit to end the scanning at. * int offset The offset for each ply. */ private final void addRelativePliesUpward( long destinationPos, int startBit, int endBit, int offset) { // Compute a bitmask to mask the bits in the destination bitfield. long bitmask = 1L << startBit; // End the loop also if the bitmask is 0, so there are no more destination fields // in the bitmask (so we don't have to check the entire chessboard for plies). for( int currentBit = startBit; currentBit <= endBit && destinationPos != 0; currentBit++) { // If the bit of the destination square is set, it's the destination for a ply. if(( destinationPos & bitmask) != 0) { // Add the ply to the buffer. addRegularPly( currentBit + offset, currentBit, (bitmask & _attackablePieces) != 0L ? MATERIAL_WIN : REGULAR_PLY); // Remove the bit, so we can check if there are more plies to find. destinationPos &= ~bitmask; } bitmask <<= 1; } } /** * Convert a bitmask to a series of relative plies. * * @param destinationPos The destination positions for all the plies. * @param int startBit The bit to start scanning from. * @param int endBit The bit to end the scanning at. * int offset The offset for each ply. */ private final void addRelativePliesDownward( long destinationPos, int startBit, int endBit, int offset) { long bitmask = 1L << startBit; for( int currentBit = startBit; currentBit >= endBit && destinationPos != 0; currentBit--) { if(( destinationPos & bitmask) != 0) { addRegularPly( currentBit + offset, currentBit, (bitmask & _attackablePieces) != 0L ? MATERIAL_WIN : REGULAR_PLY); destinationPos &= ~bitmask; } bitmask >>= 1; bitmask &= 0x7FFFFFFFFFFFFFFFL; } } /** * Convert a bitmask to a series of absolute plies. * * @param destinationPos The destination positions for all the plies. * @param int startBit The bit to start scanning from. * @param int endBit The bit to end the scanning at. * int pos The source for each ply. */ private final void addAbsolutePlies( long destinationPos, int startBit, int endBit, int pos) { long bitmask = 1L << startBit; for( int currentBit = startBit; currentBit <= endBit && destinationPos != 0; currentBit++) { if(( destinationPos & bitmask) != 0) { addRegularPly( pos, currentBit, (bitmask & _attackablePieces) != 0L ? MATERIAL_WIN : REGULAR_PLY); destinationPos &= ~bitmask; } bitmask <<= 1; } } /** * Get the current board. * * @return The current board. */ final BitBoard getBoard() { return _board; } /** * Set a new board. * * @param board The new board. */ final void setBoard(BitBoard board) { _board = board; } /** * Get a analyzer for check test. * * @return A analyzer for chess boards. */ final BitBoardAnalyzer getAnalyzer() { return _analyzer; } /** * Get the last ply. * * @return The last ply. */ final Ply getLastPly() { return getGame().getLastPly(); // return _lastPly; } /** * Set the last ply. * * @param lastPly The last ply. */ /*final void setLastPly( Ply lastPly) { // _lastPly = lastPly; }*/ /** * Set a analyzer for check tests. * * @param analyzer The new analyzer to set. */ public final void setAnalyzer( BitBoardAnalyzer analyzer) { _analyzer = analyzer; } /** * Reset the ply buffer. */ private final void resetPlies() { _plyCounter = 0; } /** * Add a ply to the buffer, if the own king is not in check after the ply. * * @param ply The ply to add. * @param score The presort score of this ply. */ private final void addPly( Ply ply, short score) { // Test if the own king is in check, before adding the ply if( ! getAnalyzer().isInCheck( (BitBoard)(getBoard().getBoardAfterPly( ply)), _white)) { _currentPlies[ _plyCounter++] = new AnalyzedPlyImpl( ply, score); } } /** * Add a regular ply. * * @param source The source square. * @param destination The destination square. * @param score The presort score of this ply. */ private final void addRegularPly( int source, int destination, short score) { addPly( new PlyImpl( new PositionImpl( source), new PositionImpl( destination)), score); } /** * Add a castling ply. * * @param source The position square of the king. * @param goesLeft The flag that indicates if the castling goes to the left. */ private final void addCastlingPly( int source, boolean goesLeft) { addPly( new CastlingPlyImpl( new PositionImpl( source), goesLeft), REGULAR_PLY); } /** * Add a transformation ply. * * @param source The source square of the old piece. * @param destination The destination square of the piece. * @param pieceType The new piece type after the ply. * @param score The presort score of this ply. */ private final void addTransformationPly( int source, int destination, byte pieceType, short score) { addPly( new TransformationPlyImpl( new PositionImpl( source), new PositionImpl( destination), pieceType), score); } /** * Get the knight plies for a given knight square. * * @param square The square, where the knight is located. * * @return All the knight plies as a 64 bit bitmask. */ public final long getKnightPlies( int square) { return _knightMask[ square]; } /** * Presort the scored plies. */ private final void presortPlies() { if( _plyCounter > 1) { // Check the array size, so the sort methods don't have to do it. quickersort( 0, _plyCounter - 1); } } /** * Perform a combined quick-/shakersort on a ply partition. * * @param l The left bound of the array partition. * @param r The right bound of the array partition. */ private final void quickersort( int l, int r) { int i = l, j = r; AnalyzedPly x = _currentPlies[ ( l + r) / 2]; do { while( _currentPlies[i].getScore() > x.getScore()) { i++; } while( x.getScore() > _currentPlies[j].getScore()) { j--; } if( i <= j) { AnalyzedPly w = _currentPlies[i]; _currentPlies[i++] = _currentPlies[j]; _currentPlies[j--] = w; } } while( i <= j); if( l < j) { if( ( l - j) > 7) { quickersort( l, j); } else { shakersort( l, j); } } if( i < r) { if( ( r - i) > 7) { quickersort( i, r); } else { shakersort( i, r); } } } /** * Perform a shakersort on a ply partition. * * @param l The left bound of the ply partition. * @param r The right bound of the ply partition. */ private final void shakersort( int l, int r) { int i = l + 1, j = r, k = r; do { for( int h = j; h >= i; h--) { if( _currentPlies[h-1].getScore() < _currentPlies[h].getScore()) { AnalyzedPly w = _currentPlies[h-1]; _currentPlies[h-1] = _currentPlies[h]; _currentPlies[h] = w; k = h; } } i = k + 1; for( int h = i; h <= j; h++) { if( _currentPlies[h-1].getScore() < _currentPlies[h].getScore()) { AnalyzedPly w = _currentPlies[h-1]; _currentPlies[h-1] = _currentPlies[h]; _currentPlies[h] = w; k = h; } } j = k - 1; } while( i <= j); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -