private static Position CalculateTo(ChessPlayer owner, CastlingType castlingType) { switch (owner) { case ChessPlayer.White: switch (castlingType) { case CastlingType.Long: return(Positions.C1); case CastlingType.Short: return(Positions.G1); default: throw new ArgumentOutOfRangeException(nameof(castlingType), owner, null); } case ChessPlayer.Black: switch (castlingType) { case CastlingType.Long: return(Positions.C8); case CastlingType.Short: return(Positions.G8); default: throw new ArgumentOutOfRangeException(nameof(castlingType), owner, null); } default: throw new ArgumentOutOfRangeException(nameof(owner), owner, null); } }
private static void PopulateKingCastlingMoves( ICollection <GameMoveData2> resultMoves, Square sourceSquare, Bitboard target, CastlingOptions allowedCastlingOptions, Bitboard nonEmptySquares, CastlingType castlingType) { var option = castlingType.ToOption(); if ((allowedCastlingOptions & option) == 0) { return; } var info = KingCastlingInfos[GetCastlingTypeArrayIndexInternal(castlingType)]; if (info.KingMove.From != sourceSquare || (info.ExpectedEmptySquares & nonEmptySquares).IsAny || (info.KingMove.To.Bitboard & target).IsNone) { return; } var moveData = new GameMoveData2(info.KingMove, GameMoveFlags.IsKingCastling); resultMoves.Add(moveData); }
public DetailedMove(Position originalPosition, Position newPosition, Player player, char?promotion, Piece piece, bool isCapture, CastlingType castling) : base(originalPosition, newPosition, player, promotion) { Piece = piece; IsCapture = isCapture; Castling = castling; }
public DetailedMove(Position originalPosition, Position newPosition, Player player, char? promotion, Piece piece, bool isCapture, CastlingType castling) : base(originalPosition, newPosition, player, promotion) { Piece = piece; IsCapture = isCapture; Castling = castling; }
public static long GetCastlingHash(CastlingType castlingType) { var castlingIndex = CastlingMap[castlingType]; var result = (long)Randoms[RandomsCastlingOffset + castlingIndex]; return(result); }
internal CastlingInfo2( CastlingType castlingType, GameMove2 kingMove, GameMove2 rookMove, [NotNull] params Square[] emptySquares) { castlingType.EnsureDefined(); if (emptySquares is null) { throw new ArgumentNullException(nameof(emptySquares)); } if (kingMove.From.Rank != kingMove.To.Rank || Math.Abs(kingMove.From.SquareIndex - kingMove.To.SquareIndex) != 2) { throw new ArgumentException( $@"Invalid castling move '{kingMove.ToUciNotation()}'.", nameof(kingMove)); } CastlingType = castlingType; CastlingSide = castlingType.GetSide(); Option = castlingType.ToOption(); KingMove = kingMove; RookMove = rookMove; EmptySquares = emptySquares.AsReadOnly(); PassedSquare = new Square((kingMove.From.SquareIndex + kingMove.To.SquareIndex) / 2); GameSide = Option.IsAnySet(CastlingOptions.WhiteMask) ? GameSide.White : GameSide.Black; }
/// <summary> /// Removes castling possibility Zobrist hash. /// </summary> /// <param name="color">The piece color.</param> /// <param name="castlingType">The castling type.</param> /// <param name="bitboard">The bitboard.</param> public static void RemoveCastlingPossibility(Color color, CastlingType castlingType, Bitboard bitboard) { var castlingIndex = FastArray.GetCastlingIndex(color, castlingType); if (bitboard.CastlingPossibility[castlingIndex]) { bitboard.Hash ^= ZobristContainer.Castling[castlingIndex]; } }
public static string CastlingTypeToNotation(CastlingType castlingType) { switch (castlingType) { case CastlingType.KingSide: return "O-O"; case CastlingType.QueenSide: return "O-O-O"; } return ""; }
public KingCastlingMove(ChessPlayer owner, CastlingType castlingType) : base(owner, CalculateFrom(owner), CalculateTo(owner, castlingType)) { CastlingType = castlingType; switch (owner) { case ChessPlayer.White: switch (castlingType) { case CastlingType.Long: RookFrom = Positions.A1; RookTo = Positions.D1; break; case CastlingType.Short: RookFrom = Positions.H1; RookTo = Positions.F1; break; default: throw new ArgumentOutOfRangeException(nameof(castlingType), owner, null); } break; case ChessPlayer.Black: switch (castlingType) { case CastlingType.Long: RookFrom = Positions.A8; RookTo = Positions.D8; break; case CastlingType.Short: RookFrom = Positions.H8; RookTo = Positions.F8; break; default: throw new ArgumentOutOfRangeException(nameof(castlingType), owner, null); } break; default: throw new ArgumentOutOfRangeException(nameof(owner), owner, null); } }
protected override MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured, out CastlingType castlingType) { MoveType type = base.ApplyMove(move, alreadyValidated, out captured, out castlingType); if (!type.HasFlag(MoveType.Capture)) { return(type); } var surroundingSquares = new int[][] { new int[] { 1, 0 }, new int[] { 1, 1 }, new int[] { 0, 1 }, new int[] { -1, -1 }, new int[] { -1, 0 }, new int[] { 0, -1 }, new int[] { -1, 1 }, new int[] { 1, -1 } }; SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, null); foreach (int[] surroundingSquaresDistance in surroundingSquares) { File f = move.NewPosition.File + surroundingSquaresDistance[0]; int r = move.NewPosition.Rank + surroundingSquaresDistance[1]; if (f < 0 || (int)f >= BoardWidth || r < 1 || r > BoardHeight) { continue; } if (!(GetPieceAt(f, r) is Pawn)) { SetPieceAt(f, r, null); } } if (CanBlackCastleKingSide && GetPieceAt(InitialBlackRookFileKingsideCastling, 8) == null) { CanBlackCastleKingSide = false; } if (CanBlackCastleQueenSide && GetPieceAt(InitialBlackRookFileQueensideCastling, 8) == null) { CanBlackCastleQueenSide = false; } if (CanWhiteCastleKingSide && GetPieceAt(InitialWhiteRookFileKingsideCastling, 1) == null) { CanWhiteCastleKingSide = false; } if (CanWhiteCastleQueenSide && GetPieceAt(InitialWhiteRookFileQueensideCastling, 1) == null) { CanWhiteCastleQueenSide = false; } return(type); }
public DetailedMove(Position originalPosition, Position newPosition, Player player, char?promotion, Piece piece, bool isCapture, CastlingType castling, string san, Piece captured, int?lastHalfMoveClock, bool enPassant) : this(originalPosition, newPosition, player, promotion, piece, isCapture, castling, san) { CapturedPiece = captured; LastHalfMoveClock = lastHalfMoveClock; EnPassant = enPassant; }
public DetailedMove(Move move, Piece piece, Piece capturedPiece, CastlingType castling, string san, int halfMoveClock, bool enPassant) : this(move.OriginalPosition, move.NewPosition, move.Player, move.Promotion, piece, capturedPiece != null, castling, san, capturedPiece, halfMoveClock, enPassant) { }
public virtual MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured) { ChessUtilities.ThrowIfNull(move, "move"); captured = null; if (!alreadyValidated && !IsValidMove(move)) { return(MoveType.Invalid); } MoveType type = MoveType.Move; Piece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank); Piece capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank); captured = capturedPiece; Piece newPiece = movingPiece; enp = "-1"; bool isCapture = capturedPiece != null; CastlingType castle = CastlingType.None; if (movingPiece is Pawn) { i_halfMoveClock = 0; PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition); if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition) == null) { // en passant isCapture = true; captured = GetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank); enp = move.NewPosition.File.ToString().ToLower() + move.OriginalPosition.Rank.ToString(); SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, null); } if (move.NewPosition.Rank == (move.Player == Player.White ? 8 : 1)) { //get promotion type char PromoteTo; if (move.Promotion == null) { string promote; Console.Write("enter promotion type:"); promote = Console.ReadLine(); switch (promote) { case "queen": PromoteTo = 'Q'; break; case "bishop": PromoteTo = 'B'; break; case "knight": PromoteTo = 'N'; break; case "rook": PromoteTo = 'R'; break; default: PromoteTo = 'Q'; break; } } else { PromoteTo = 'Q'; } newPiece = MapPgnCharToPiece(PromoteTo, move.Player).AsPromotion(); type |= MoveType.Promotion; } } else if (movingPiece is King) { if (movingPiece.Owner == Player.White) { CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false; } else { CanBlackCastleKingSide = CanBlackCastleQueenSide = false; } if (CastlingCanBeLegal && ((GetPieceAt(move.NewPosition) is Rook && GetPieceAt(move.NewPosition).Owner == move.Player) || ((move.NewPosition.File == File.C || move.NewPosition.File == File.G) && (move.Player == Player.White ? InitialWhiteKingFile : InitialBlackKingFile) == File.E && move.OriginalPosition.File == File.E))) { castle = ApplyCastle(move); type |= MoveType.Castling; isCapture = false; } } else if (movingPiece is Rook) { if (move.Player == Player.White) { if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 1) { CanWhiteCastleQueenSide = false; } else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 1) { CanWhiteCastleKingSide = false; } } else { if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 8) { CanBlackCastleQueenSide = false; } else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 8) { CanBlackCastleKingSide = false; } } } if (isCapture) { type |= MoveType.Capture; i_halfMoveClock = 0; if (move.NewPosition.File == File.A && move.NewPosition.Rank == 1) { CanWhiteCastleQueenSide = false; } else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 1) { CanWhiteCastleKingSide = false; } else if (move.NewPosition.File == File.A && move.NewPosition.Rank == 8) { CanBlackCastleQueenSide = false; } else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 8) { CanBlackCastleKingSide = false; } } if (!isCapture && !(movingPiece is Pawn)) { i_halfMoveClock++; if (i_halfMoveClock >= 100) { fiftyMoves = true; } else { fiftyMoves = false; } } if (move.Player == Player.Black) { i_fullMoveNumber++; } if (castle == CastlingType.None) { SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece); SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null); } WhoseTurn = ChessUtilities.GetOpponentOf(move.Player); AddDetailedMove(new DetailedMove(move, movingPiece, isCapture, castle)); return(type); }
/// <summary> /// æž„é€ å‡½æ•°ã€‚ /// </summary> /// <param name="originalPosition"></param> /// <param name="newPosition"></param> /// <param name="player"></param> /// <param name="promotion"></param> /// <param name="piece"></param> /// <param name="isCapture"></param> /// <param name="castling"></param> /// <param name="capturedPiece"></param> /// <param name="isEnpassant"></param> /// <param name="isChecking"></param> /// <param name="isCheckmate"></param> public MoreDetailedMove(Position originalPosition, Position newPosition, Player player, char? promotion, Piece piece, bool isCapture, CastlingType castling, Piece capturedPiece, bool isEnpassant, bool isChecking, bool isCheckmate) : base(originalPosition, newPosition, player, promotion, piece, isCapture, castling) { CapturedPiece = capturedPiece; IsEnpassant = isEnpassant; IsChecking = isChecking; IsCheckmate = isCheckmate; }
protected override MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured, out CastlingType castlingType) { MoveType ret = base.ApplyMove(move, alreadyValidated, out captured, out castlingType); if (ret == MoveType.Invalid) { return(ret); } if (WhoseTurn == Player.White && IsInCheck(Player.White)) { ChecksByBlack++; } if (WhoseTurn == Player.Black && IsInCheck(Player.Black)) { ChecksByWhite++; } return(ret); }
public static CastlingOptions ToOption(this CastlingType castlingType) { return(unchecked ((CastlingOptions)(1 << (int)castlingType))); }
private static int GetCastlingTypeArrayIndexInternal(CastlingType castlingType) { return((int)castlingType); }
public CastlingMove(CastlingType castlingType, Piece movingPiece, Space newSpace) : base(movingPiece, newSpace) { this.castlingType = castlingType; }
private static int GetCastlingTypeArrayIndexInternal(CastlingType castlingType) => (int)castlingType;
public DetailedMove(Move move, Piece piece, bool isCapture, CastlingType castling) : this(move.OriginalPosition, move.NewPosition, move.Player, move.Promotion, piece, isCapture, castling) { }
private static bool Castling(Player currentPlayer, CastlingType castlingType, Figures[,] board) { return(true); }
/// <summary> /// Checks if castling with the specified type is possible. /// </summary> /// <param name="type">The castling type.</param> /// <param name="opt">The generator parameters.</param> /// <returns>True if castling is possible, otherwise false.</returns> private static bool IsCastlingPossible(CastlingType type, GeneratorParameters opt) { return(opt.Bitboard.CastlingPossibility[FastArray.GetCastlingIndex(opt.FriendlyColor, type)]); }
public static bool Castling(Player currentPlayer, CastlingType castlingType, Cell[,] board) { // TODO: implement later return(true); }
protected override MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured, out CastlingType castlingType) { MoveType ret = base.ApplyMove(move, alreadyValidated, out captured, out castlingType); if (ret.HasFlag(MoveType.Capture)) { (move.Player == Player.White ? whitePocket : blackPocket).Add(!captured.IsPromotionResult ? captured.GetWithInvertedOwner() : new Pawn(ChessUtilities.GetOpponentOf(captured.Owner))); } return(ret); }
public virtual MoveType ApplyMove(Move move, bool alreadyValidated, out Piece captured) { ChessUtilities.ThrowIfNull(move, "move"); captured = null; if (!alreadyValidated && !IsValidMove(move)) { return(MoveType.Invalid); } MoveType type = MoveType.Move; Piece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank); Piece capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank); captured = capturedPiece; Piece newPiece = movingPiece; bool isCapture = capturedPiece != null; CastlingType castle = CastlingType.None; if (movingPiece is Pawn) { i_halfMoveClock = 0; PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition); if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition) == null) { // en passant isCapture = true; captured = GetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank); SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, null); } if (move.NewPosition.Rank == (move.Player == Player.White ? 8 : 1)) { newPiece = MapPgnCharToPiece(move.Promotion.Value, move.Player).AsPromotion(); type |= MoveType.Promotion; } } else if (movingPiece is King) { if (movingPiece.Owner == Player.White) { CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false; } else { CanBlackCastleKingSide = CanBlackCastleQueenSide = false; } if (CastlingCanBeLegal && ((GetPieceAt(move.NewPosition) is Rook && GetPieceAt(move.NewPosition).Owner == move.Player) || ((move.NewPosition.File == File.C || move.NewPosition.File == File.G) && (move.Player == Player.White ? InitialWhiteKingFile : InitialBlackKingFile) == File.E && move.OriginalPosition.File == File.E))) { castle = ApplyCastle(move); type |= MoveType.Castling; isCapture = false; } } else if (movingPiece is Rook) { if (move.Player == Player.White) { if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 1) { CanWhiteCastleQueenSide = false; } else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 1) { CanWhiteCastleKingSide = false; } } else { if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 8) { CanBlackCastleQueenSide = false; } else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 8) { CanBlackCastleKingSide = false; } } } if (isCapture) { type |= MoveType.Capture; i_halfMoveClock = 0; if (move.NewPosition.File == File.A && move.NewPosition.Rank == 1) { CanWhiteCastleQueenSide = false; } else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 1) { CanWhiteCastleKingSide = false; } else if (move.NewPosition.File == File.A && move.NewPosition.Rank == 8) { CanBlackCastleQueenSide = false; } else if (move.NewPosition.File == File.H && move.NewPosition.Rank == 8) { CanBlackCastleKingSide = false; } } if (!isCapture && !(movingPiece is Pawn)) { i_halfMoveClock++; if (i_halfMoveClock >= 100) { fiftyMoves = true; } else { fiftyMoves = false; } } if (move.Player == Player.Black) { i_fullMoveNumber++; } if (castle == CastlingType.None) { SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece); SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null); } WhoseTurn = ChessUtilities.GetOpponentOf(move.Player); AddDetailedMove(new DetailedMove(move, movingPiece, isCapture, castle)); return(type); }
public MoreDetailedMove(Move move, Piece piece, bool isCapture, CastlingType castling, Piece capturedPiece, bool isEnpassant, bool isChecking, bool isCheckmate) : this(move.OriginalPosition, move.NewPosition, move.Player, move.Promotion, piece, isCapture, castling, capturedPiece, isEnpassant, isChecking, isCheckmate) { }
public static CastlingSide GetSide(this CastlingType castlingType) { //// ReSharper disable once BitwiseOperatorOnEnumWithoutFlags //// ReSharper disable once RedundantOverflowCheckingContext return((CastlingSide) unchecked ((int)castlingType & 1)); }
public static int GetCastlingIndex(Color color, CastlingType castlingType) { return(((int)color << 1) + (int)castlingType); }
public CastlingTemplate(CastlingType type) : base(null, false, true) { CType = type; }
protected virtual string GetSanForMove(Move move, Piece movingPiece, bool isCapture, CastlingType castle, List <Position> ambiguities) { if (castle == CastlingType.KingSide) { return("O-O"); } if (castle == CastlingType.QueenSide) { return("O-O-O"); } bool needsUnambigFile = false; bool needsUnambigRank = false; if (ambiguities.Count > 0) { foreach (Position amb in ambiguities) { if (amb.Rank == move.OriginalPosition.Rank) { needsUnambigFile = true; } if (amb.File == move.OriginalPosition.File) { needsUnambigRank = true; } } if (!needsUnambigFile && !needsUnambigRank) { needsUnambigFile = true; } } StringBuilder sanBuilder = new StringBuilder(); if (!(movingPiece is Pawn)) { sanBuilder.Append(char.ToUpperInvariant(movingPiece.GetFenCharacter())); } else if (isCapture) { sanBuilder.Append(move.OriginalPosition.File.ToString().ToLowerInvariant()); needsUnambigFile = false; needsUnambigRank = false; } if (needsUnambigFile) { sanBuilder.Append(move.OriginalPosition.File.ToString().ToLowerInvariant()); } if (needsUnambigRank) { sanBuilder.Append(move.OriginalPosition.Rank.ToString()); } if (isCapture) { sanBuilder.Append("x"); } sanBuilder.Append(move.NewPosition.ToString().ToLowerInvariant()); if (move.Promotion.HasValue) { sanBuilder.Append("="); sanBuilder.Append(move.Promotion.Value); } if (IsWinner(ChessUtilities.GetOpponentOf(WhoseTurn))) { sanBuilder.Append("#"); } else if (IsInCheck(WhoseTurn)) { sanBuilder.Append("+"); } return(sanBuilder.ToString()); }
public virtual MoveType ApplyMove(Move move, bool alreadyValidated) { ChessUtility.ThrowIfNull(move, "move"); if (!alreadyValidated && !IsValidMove(move)) { return(MoveType.Invalid); } MoveType type = MoveType.Move; ChessPiece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank); ChessPiece capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank); ChessPiece newPiece = movingPiece; bool isCapture = capturedPiece != null; CastlingType castle = CastlingType.None; if (movingPiece is Pawn) { _halfMoveClock = 0; BoardDistance pd = new BoardDistance(move.OriginalPosition, move.NewPosition); if (pd.X == 1 && pd.Y == 1 && GetPieceAt(move.NewPosition) == null) { // en passant isCapture = true; SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, null); } if (move.NewPosition.Rank == (move.Player == ChessPlayer.White ? 8 : 1)) { newPiece = MapPgnCharToPiece(move.Promotion.Value, move.Player); type |= MoveType.Promotion; } } else if (movingPiece is King) { if (movingPiece.Owner == ChessPlayer.White) { CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false; } else { CanBlackCastleKingSide = CanBlackCastleQueenSide = false; } if (new BoardDistance(move.OriginalPosition, move.NewPosition).X == 2 && CastlingCanBeLegal) { castle = ApplyCastle(move); type |= MoveType.Castling; } } else if (movingPiece is Rook) { if (move.Player == ChessPlayer.White) { if (move.OriginalPosition.File == ChessFile.A && move.OriginalPosition.Rank == 1) { CanWhiteCastleQueenSide = false; } else if (move.OriginalPosition.File == ChessFile.H && move.OriginalPosition.Rank == 1) { CanWhiteCastleKingSide = false; } } else { if (move.OriginalPosition.File == ChessFile.A && move.OriginalPosition.Rank == 8) { CanBlackCastleQueenSide = false; } else if (move.OriginalPosition.File == ChessFile.H && move.OriginalPosition.Rank == 8) { CanBlackCastleKingSide = false; } } } if (isCapture) { type |= MoveType.Capture; _halfMoveClock = 0; if (move.NewPosition.File == ChessFile.A && move.NewPosition.Rank == 1) { CanWhiteCastleQueenSide = false; } else if (move.NewPosition.File == ChessFile.H && move.NewPosition.Rank == 1) { CanWhiteCastleKingSide = false; } else if (move.NewPosition.File == ChessFile.A && move.NewPosition.Rank == 8) { CanBlackCastleQueenSide = false; } else if (move.NewPosition.File == ChessFile.H && move.NewPosition.Rank == 8) { CanBlackCastleKingSide = false; } } if (!isCapture && !(movingPiece is Pawn)) { _halfMoveClock++; if (_halfMoveClock >= 100) { fiftyMoves = true; } else { fiftyMoves = false; } } if (move.Player == ChessPlayer.Black) { _fullMoveNumber++; } SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece); SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null); WhoseTurn = ChessUtility.GetOpponentOf(move.Player); _moves.Add(new DetailedMove(move, movingPiece, isCapture, castle)); _positions.Add(GetPosition()); return(type); }
/// <summary> /// Initializes a new instance of the <see cref="CastlingMove"/> class. /// </summary> /// <param name="from">The source piece position.</param> /// <param name="to">The destination piece position.</param> /// <param name="piece">The piece type.</param> /// <param name="color">The piece color.</param> /// <param name="castlingType">The castling type.</param> public CastlingMove(Position from, Position to, PieceType piece, Color color, CastlingType castlingType) : base(from, to, piece, color) { CastlingType = castlingType; }