/// <summary> /// Removes castling possibility if needed. /// </summary> /// <param name="bitboard">The bitboard.</param> private void CalculateCastling(Bitboard bitboard) { switch (Piece) { case PieceType.King: { var shortCastlingIndex = FastArray.GetCastlingIndex(Color, CastlingType.Short); var longCastlingIndex = FastArray.GetCastlingIndex(Color, CastlingType.Long); IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Short, bitboard); IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Long, bitboard); bitboard.CastlingPossibility[shortCastlingIndex] = false; bitboard.CastlingPossibility[longCastlingIndex] = false; break; } case PieceType.Rook: { if (From == new Position(1, 1) || From == new Position(1, 8)) { IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Long, bitboard); bitboard.CastlingPossibility[FastArray.GetCastlingIndex(Color, CastlingType.Long)] = false; } else if (From == new Position(8, 1) || From == new Position(8, 8)) { IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Short, bitboard); bitboard.CastlingPossibility[FastArray.GetCastlingIndex(Color, CastlingType.Short)] = false; } break; } } }
/// <summary> /// Removes en passant piece from the specified bitboard. /// </summary> /// <param name="bitboard">The bitboard.</param> /// <param name="enemyColor">The enemy color.</param> /// <param name="fieldLSB">The bitboard with set field.</param> private void RemoveEnPassantPiece(Bitboard bitboard, Color enemyColor, ulong fieldLSB) { var enPassantPiece = Color == Color.White ? fieldLSB >> 8 : fieldLSB << 8; bitboard.Pieces[FastArray.GetPieceIndex(enemyColor, PieceType.Pawn)] &= ~enPassantPiece; bitboard.Occupancy[(int)enemyColor] ^= enPassantPiece; IncrementalMaterial.RemovePiece(bitboard, enemyColor, PieceType.Pawn); IncrementalPosition.RemovePiece(bitboard, enemyColor, PieceType.Pawn, enPassantPiece); IncrementalZobrist.AddOrRemovePiece(enemyColor, PieceType.Pawn, enPassantPiece, bitboard); }
/// <summary> /// Removes castling possibility from the specified bitboard. /// </summary> /// <param name="bitboard">The bitboard.</param> private void RemoveCastlingPossibility(Bitboard bitboard) { IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Short, bitboard); IncrementalZobrist.RemoveCastlingPossibility(Color, CastlingType.Long, bitboard); bitboard.CastlingPossibility[FastArray.GetCastlingIndex(Color, CastlingType.Short)] = false; bitboard.CastlingPossibility[FastArray.GetCastlingIndex(Color, CastlingType.Long)] = false; IncrementalCastling.SetCastlingDone(bitboard, Color); bitboard.CastlingDone[(int)Color] = true; }
/// <summary> /// Initializes a new instance of the <see cref="Bitboard"/> class. /// </summary> /// <param name="bitboard">The previous bitboard.</param> /// <param name="move">The move to apply.</param> public Bitboard(Bitboard bitboard, Move move) : this(bitboard) { IncrementalZobrist.ClearEnPassant(ColorOperations.Invert(move.Color), this); EnPassant[(int)ColorOperations.Invert(move.Color)] = 0; ReversibleMoves++; move.Do(this); CalculateGamePhase(); UpdateHistory(); }
/// <summary> /// Calculates en passant fields if current piece type is pawn. /// </summary> /// <param name="bitboard">The bitboard.</param> private void CalculateEnPassant(Bitboard bitboard) { if (Piece == PieceType.Pawn) { var enPassantPosition = GetEnPassantPosition(); if (enPassantPosition.HasValue) { var enPassantLSB = BitPositionConverter.ToULong(enPassantPosition.Value); bitboard.EnPassant[(int)Color] |= enPassantLSB; IncrementalZobrist.AddEnPassant(Color, enPassantLSB, bitboard); } } }
/// <summary> /// Helper method for derived classes, calculates move with the specified parameters. /// </summary> /// <param name="bitboard">The bitboard.</param> /// <param name="pieceFrom">The source piece type.</param> /// <param name="from">The piece source position.</param> /// <param name="pieceTo">The destination piece type.</param> /// <param name="to">The piece destination position.</param> protected void CalculatePieceMove(Bitboard bitboard, PieceType pieceFrom, ulong from, PieceType pieceTo, ulong to) { bitboard.Pieces[FastArray.GetPieceIndex(Color, pieceFrom)] &= ~from; bitboard.Pieces[FastArray.GetPieceIndex(Color, pieceTo)] |= to; bitboard.Occupancy[(int)Color] ^= from | to; IncrementalPosition.RemovePiece(bitboard, Color, pieceFrom, from); IncrementalPosition.AddPiece(bitboard, Color, pieceTo, to); IncrementalZobrist.AddOrRemovePiece(Color, pieceFrom, from, bitboard); IncrementalZobrist.AddOrRemovePiece(Color, pieceTo, to, bitboard); if (pieceFrom == PieceType.Pawn) { bitboard.ReversibleMoves = 0; } }
/// <summary> /// Removes killed piece from the specified bitboard. /// </summary> /// <param name="bitboard">The bitboard.</param> /// <param name="enemyColor">The enemy color.</param> /// <param name="fieldLSB">The bitboard with set field.</param> protected void CalculateKill(Bitboard bitboard, Color enemyColor, ulong fieldLSB) { for (var piece = 0; piece < 6; piece++) { var index = FastArray.GetPieceIndex(enemyColor, (PieceType)piece); if ((bitboard.Pieces[index] & fieldLSB) != 0) { bitboard.Pieces[index] &= ~fieldLSB; bitboard.Occupancy[(int)enemyColor] &= ~fieldLSB; IncrementalMaterial.RemovePiece(bitboard, enemyColor, (PieceType)piece); IncrementalPosition.RemovePiece(bitboard, enemyColor, (PieceType)piece, fieldLSB); IncrementalZobrist.AddOrRemovePiece(enemyColor, (PieceType)piece, fieldLSB, bitboard); bitboard.ReversibleMoves = 0; break; } } }