public bool WouldBeInCheckAfter(Move move, Player player) { ChessUtilities.ThrowIfNull(move, nameof(move)); var gcd = new GameCreationData(); gcd.Board = Board; gcd.CanWhiteCastleKingSide = !_whiteRookHMoved && !_whiteKingMoved; gcd.CanWhiteCastleQueenSide = !_whiteRookAMoved && !_whiteKingMoved; gcd.CanBlackCastleKingSide = !_blackRookHMoved && !_blackKingMoved; gcd.CanBlackCastleQueenSide = !_blackRookAMoved && !_blackKingMoved; gcd.EnPassant = null; if (_moves.Count > 0) { var last = _moves.Last(); if (last.Piece is Pawn && new SquareDistance(last.OriginalPosition, last.NewPosition).DistanceY == 2) { gcd.EnPassant = new Square(last.NewPosition.File, last.Player == Player.White ? 3 : 6); } } gcd.HalfMoveClock = _halfMoveClock; gcd.FullMoveNumber = _fullMoveNumber; var copy = new ChessGame(gcd); copy.ApplyMove(move, true); var status = copy.CalculateStatus(player, false); return(status.Event == GameEvent.Check && status.PlayerWhoCausedEvent != player); }
public virtual bool WouldBeInCheckAfter(Move move, Player player) { ChessUtilities.ThrowIfNull(move, "move"); GameCreationData gcd = new GameCreationData(); gcd.Board = Board; gcd.CanWhiteCastleKingSide = CanWhiteCastleKingSide; gcd.CanWhiteCastleQueenSide = CanWhiteCastleQueenSide; gcd.CanBlackCastleKingSide = CanBlackCastleKingSide; gcd.CanBlackCastleQueenSide = CanBlackCastleQueenSide; gcd.EnPassant = null; if (_moves.Count > 0) { DetailedMove last = _moves.Last(); if (last.Piece is Pawn && new PositionDistance(last.OriginalPosition, last.NewPosition).DistanceY == 2) { gcd.EnPassant = new Position(last.NewPosition.File, last.Player == Player.White ? 3 : 6); } } gcd.HalfMoveClock = i_halfMoveClock; gcd.FullMoveNumber = i_fullMoveNumber; ChessGame copy = new ChessGame(gcd); Piece p = copy.GetPieceAt(move.OriginalPosition); copy.SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null); copy.SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, p); return(copy.IsInCheck(player)); }
public virtual bool HasAnyValidMoves(Position from) { ChessUtilities.ThrowIfNull(from, "from"); ReadOnlyCollection <Move> validMoves = GetValidMoves(from, true); return(validMoves.Count > 0); }
ReadOnlyCollection <Move> GetValidMoves(Square from, bool returnIfAny) { ChessUtilities.ThrowIfNull(from, nameof(from)); var piece = GetPieceAt(from); return(piece == null || piece.Owner != WhoseTurn ? new ReadOnlyCollection <Move>(new List <Move>()) : piece.GetValidMoves(from, returnIfAny, this)); }
protected virtual ReadOnlyCollection <Move> GetValidMoves(Position from, bool returnIfAny) { ChessUtilities.ThrowIfNull(from, "from"); Piece piece = GetPieceAt(from); if (piece == null || piece.Owner != WhoseTurn) { return(new ReadOnlyCollection <Move>(new List <Move>())); } return(piece.GetValidMoves(from, returnIfAny, this, IsValidMove)); }
protected static Piece[][] CloneBoard(Piece[][] originalBoard) { ChessUtilities.ThrowIfNull(originalBoard, "originalBoard"); Piece[][] newBoard = new Piece[originalBoard.Length][]; for (int i = 0; i < originalBoard.Length; i++) { newBoard[i] = new Piece[originalBoard[i].Length]; Array.Copy(originalBoard[i], newBoard[i], originalBoard[i].Length); } return(newBoard); }
protected virtual bool IsValidMove(Move move, bool validateCheck, bool careAboutWhoseTurnItIs) { ChessUtilities.ThrowIfNull(move, "move"); if (move.OriginalPosition.Equals(move.NewPosition)) { return(false); } Piece piece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank); if (careAboutWhoseTurnItIs && move.Player != WhoseTurn) { return(false); } if (piece == null || piece.Owner != move.Player) { return(false); } Piece pieceAtDestination = GetPieceAt(move.NewPosition); bool isCastle = pieceAtDestination is Rook && piece is King && pieceAtDestination.Owner == piece.Owner; if (pieceAtDestination != null && pieceAtDestination.Owner == move.Player && !isCastle) { return(false); } if (!piece.IsValidMove(move, this)) { return(false); } if (validateCheck) { if (!isCastle && WouldBeInCheckAfter(move, move.Player)) { return(false); } } return(true); }
bool IsValidMove(Move move, bool validateCheck, bool careAboutWhoseTurnItIs) // this is the weirdest bool ever. why wouldn't you care? { ChessUtilities.ThrowIfNull(move, nameof(move)); if (move.OriginalPosition.Equals(move.NewPosition)) { return(false); } var piece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank); if (careAboutWhoseTurnItIs && move.Player != WhoseTurn) { return(false); } if (piece.Owner != move.Player) { return(false); } var pieceAtDestination = GetPieceAt(move.NewPosition); if (pieceAtDestination != null && pieceAtDestination.Owner == move.Player) { return(false); } if (!piece.IsValidMove(move, this)) { return(false); } if (validateCheck && WouldBeInCheckAfter(move, move.Player)) { return(false); } return(true); }
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); }
public ReadOnlyCollection <Move> GetValidMoves(Position from) { ChessUtilities.ThrowIfNull(from, "from"); return(GetValidMoves(from, false)); }
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); }
protected bool IsValidMove(Move move, bool validateCheck) { ChessUtilities.ThrowIfNull(move, "move"); return(IsValidMove(move, validateCheck, true)); }
public bool IsValidMove(Move move) { ChessUtilities.ThrowIfNull(move, "move"); return(IsValidMove(move, true, true)); }
public Piece GetPieceAt(Position position) { ChessUtilities.ThrowIfNull(position, "position"); return(GetPieceAt(position.File, position.Rank)); }
bool IsValidMove(Move move, bool validateCheck) { ChessUtilities.ThrowIfNull(move, nameof(move)); return(IsValidMove(move, validateCheck, true)); }
public Piece GetPieceAt(Square position) { ChessUtilities.ThrowIfNull(position, nameof(position)); return(GetPieceAt(position.File, position.Rank)); }
public bool HasAnyValidMoves(Square from) { ChessUtilities.ThrowIfNull(from, nameof(from)); return(GetValidMoves(from, true).Count > 0); }
public MoveType ApplyMove(Move move, bool alreadyValidated) { ChessUtilities.ThrowIfNull(move, nameof(move)); if (!alreadyValidated && !IsValidMove(move)) { return(MoveType.Invalid); } var type = MoveType.Move; var movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank); var capturedPiece = GetPieceAt(move.NewPosition.File, move.NewPosition.Rank); var newPiece = movingPiece; var isCapture = capturedPiece != null; var castle = CastlingType.None; if (movingPiece is Pawn) { _halfMoveClock = 0; var pd = new SquareDistance(move.OriginalPosition, move.NewPosition); if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition) == null) { // en passant isCapture = true; SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, null); } if (move.NewPosition.Rank == (move.Player == Player.White ? 8 : 1)) { newPiece = move.Promotion; type |= MoveType.Promotion; } } else if (movingPiece is King) { if (movingPiece.Owner == Player.White) { _whiteKingMoved = true; } else { _blackKingMoved = true; } if (new SquareDistance(move.OriginalPosition, move.NewPosition).DistanceX == 2) { castle = ApplyCastle(move); type |= MoveType.Castling; } } else if (movingPiece is Rook) { if (move.Player == Player.White) { if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 1) { _whiteRookAMoved = true; } else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 1) { _whiteRookHMoved = true; } } else { if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == 8) { _blackRookAMoved = true; } else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == 8) { _blackRookHMoved = true; } } } if (isCapture) { type |= MoveType.Capture; _halfMoveClock = 0; } if (!isCapture && !(movingPiece is Pawn)) { _halfMoveClock++; canClaimDraw = _halfMoveClock == 100; // ahaa so THAT's the HalfMove clock .. number of Plys } if (move.Player == Player.Black) { _fullMoveNumber++; } SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece); SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, null); WhoseTurn = ChessUtilities.GetOpponentOf(move.Player); _moves.Add(new DetailedMove(move, movingPiece, isCapture, castle)); return(type); }
public ReadOnlyCollection <Move> GetValidMoves(Square from) { ChessUtilities.ThrowIfNull(from, nameof(from)); return(GetValidMoves(from, false)); }