Ejemplo n.º 1
0
        static void Main(string[] args)
        {
            // Let's start by creating a chess game instance.
            ChessGame game = new ChessGame();

            // Now the game's board is in the start position and it's white's turn.
            Console.WriteLine("It's this color's turn: {0}", game.WhoseTurn);

            // This is how to find out which piece is at a certain position:
            Piece pieceAtA1 = game.GetPieceAt(new Position("A1")); // Or "a1", the casing doesn't matter
            /* There are other overloading options as well:
             * game.GetPieceAt(new Position(File.A, 1));
             * game.GetPieceAt(File.A, 1);
             * All those three options return the same. */
            Console.WriteLine("What piece is there at A1? {0}", pieceAtA1.GetFenCharacter());
            // GetFenCharacter() returns the FEN character for the given piece. White piece: uppercase, black piece: lowercase. The character is the first char of a piece's name (exception: Knight -> N/n because King -> K/k).
            // The Piece class is the abstract base class for pieces. All piece classes (e.g. Rook) derive from this class.

            // White has to make a turn. They want to move their E2 pawn to E4. Is that valid?
            Move e2e4 = new Move("E2", "E4", Player.White);
            bool isValid = game.IsValidMove(e2e4);
            Console.WriteLine("E2-E4 for white is valid: {0}", isValid);

            // Great, it's valid! So white wants to actually make that move.
            MoveType type = game.ApplyMove(e2e4, true);
            // The first argument is the move, the second argument indicates whether it's already validated. Here it is, so pass 'true'. If it's not validated yet, ApplyMove will do it. **Only pass `true` if it's really validated! If you pass `true`, ApplyMove won't do ANY validity checks.**
            // The return type is the MoveType enum. It holds one, or a combination, of these values: Invalid, Move, Capture, Castling, Promotion
            // Each valid move will always carry the 'Move' value. If it's also something else, it will carry both values (e.g. if the move is a capture, `type` will have the value MoveType.Move | MoveType.Capture).
            // MoveType is a flags enumeration. https://msdn.microsoft.com/en-us/library/ms229062%28v=vs.100%29.aspx
            // e4 is just a normal move, so `type` will just be MoveType.Move.
            Console.WriteLine("Move type: {0}", type);

            // When a move has been made, check the Status property. It will let you know if there is a special event: check, checkmate, stalemate ...
            GameStatus status = game.Status;
            Console.WriteLine("Special event? {0}", status.Event);
            // Here it just returns 'None' because nothing special happened.
            // GameStatus has two other properties: PlayerWhoCausedEvent (quite self-explanatory) and EventExplanation (used if Chess.NET needs to be more specific about an event, e.g. when it's a draw, explaining why).

            // Now it's black's turn.
            Console.WriteLine("It's this color's turn: {0}", game.WhoseTurn);

            // You can figure out all valid moves using GetValidMoves.
            IEnumerable<Move> validMoves = game.GetValidMoves(Player.Black);
            // Here it returns all valid moves for black, but you can also find all valid moves *from a certain position* by passing a Position instance as argument.
            Console.WriteLine("How many valid moves does black have? {0}", validMoves.Count());

            // It might happen that you don't really care about all valid moves, but just want to know if there are valid moves. Chess.NET also has a method for that:
            bool hasValidMoves = game.HasAnyValidMoves(Player.Black);
            // Again, you can also pass a Position instance here.
            Console.WriteLine("Black has any valid moves: {0}", hasValidMoves);

            // Congratulations! You have learned about the most important methods of Chess.NET. Enjoy using the library :)
            Console.ReadKey();
        }
Ejemplo n.º 2
0
        public void CantMoveIfNotTurn()
        {
            // arrange
            var game = GetInitiatedGame();

            game.Start(player1Id);
            var move = new ChessDotNet.Move("e7", "e5", Player.Black);

            // act
            var moveWasSuccessful = game.Move(player2Id, move);

            Assert.False(moveWasSuccessful.WasSuccessful, "Player was able to move despite not being their turn");
        }
Ejemplo n.º 3
0
        public void CanMove()
        {
            // arrange
            var game = GetInitiatedGame();

            game.Start(player1Id);
            var move = new ChessDotNet.Move("e2", "e4", Player.White);

            // act
            var moveWasSuccessful = game.Move(player1Id, move);

            // assert
            Assert.True(moveWasSuccessful.WasSuccessful, "Failed to move despite all conditions being fine");
        }
Ejemplo n.º 4
0
        public void CantMoveTwiceInARow()
        {
            // arrange
            var game = GetInitiatedGame();

            game.Start(player1Id);
            var move1 = new ChessDotNet.Move("e2", "e4", Player.White);
            var move2 = new ChessDotNet.Move("f2", "f4", Player.White);

            // act
            var move1Result = game.Move(player1Id, move1);
            var move2Result = game.Move(player1Id, move2);

            Assert.True(move1Result.WasSuccessful, "Player was unable to move despite it being their turn");
            Assert.False(move2Result.WasSuccessful, "Player moved despite it not being their turn");
        }
Ejemplo n.º 5
0
 protected virtual ReadOnlyCollection<Move> GetValidMovesBishop(Position from, bool returnIfAny)
 {
     Utilities.ThrowIfNull(from, "from");
     List<Move> validMoves = new List<Move>();
     ChessPiece cp = GetPieceAt(from);
     int l0 = Board.Length;
     int l1 = Board[0].Length;
     for (int i = -7; i < 8; i++)
     {
         if (i == 0)
             continue;
         if ((int)from.Rank + i > -1 && (int)from.Rank + i < l0
             && (int)from.File + i > -1 && (int)from.File + i < l1)
         {
             Move move = new Move(from, new Position(from.File + i, from.Rank + i), cp.Player);
             if (IsValidMove(move))
             {
                 validMoves.Add(move);
                 if (returnIfAny)
                     return new ReadOnlyCollection<Move>(validMoves);
             }
         }
         if ((int)from.Rank - i > -1 && (int)from.Rank - i < l0
             && (int)from.File + i > -1 && (int)from.File + i < l1)
         {
             Move move = new Move(from, new Position(from.File + i, from.Rank - i), cp.Player);
             if (IsValidMove(move))
             {
                 validMoves.Add(move);
                 if (returnIfAny)
                     return new ReadOnlyCollection<Move>(validMoves);
             }
         }
     }
     return new ReadOnlyCollection<Move>(validMoves);
 }
Ejemplo n.º 6
0
        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);
            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;
        }
Ejemplo n.º 7
0
        protected virtual bool IsValidMove(Move move, bool validateCheck)
        {
            Utilities.ThrowIfNull(move, "move");
            if (move.OriginalPosition.Equals(move.NewPosition))
                return false;
            ChessPiece piece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
            if (move.Player != WhoseTurn) return false;
            if (piece.Player != move.Player) return false;
            if (GetPieceAt(move.NewPosition).Player == move.Player)
            {
                return false;
            }
            switch (piece.Piece)
            {
                case Piece.King:
                    if (!IsValidMoveKing(move))
                        return false;
                    break;
                case Piece.Pawn:
                    if (!IsValidMovePawn(move))
                        return false;
                    break;
                case Piece.Queen:
                    if (!IsValidMoveQueen(move))
                        return false;
                    break;
                case Piece.Rook:
                    if (!IsValidMoveRook(move))
                        return false;
                    break;
                case Piece.Bishop:
                    if (!IsValidMoveBishop(move))
                        return false;
                    break;
                case Piece.Knight:
                    if (!IsValidMoveKnight(move))
                        return false;
                    break;
                default:
                    return false;
            }
            if (validateCheck && WouldBeInCheckAfter(move, move.Player))
            {
                return false;
            }

            return true;
        }
Ejemplo n.º 8
0
        protected virtual bool ApplyMove(Move move, bool alreadyValidated, bool validateHasAnyValidMoves)
        {
            Utilities.ThrowIfNull(move, "move");
            if (!alreadyValidated && !IsValidMove(move))
                return false;
            ChessPiece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
            ChessPiece newPiece = movingPiece;
            if (movingPiece.Piece == Piece.Pawn)
            {
                PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition);
                if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition).Piece == Piece.None)
                { // en passant
                    SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, ChessPiece.None);
                }
                if (move.NewPosition.Rank == (move.Player == Player.White ? Rank.Eight : Rank.One))
                {
                    newPiece = new ChessPiece(move.Promotion, move.Player);
                }
            }
            else if (movingPiece.Piece == Piece.King)
            {
                if (movingPiece.Player == Player.White)
                    _whiteKingMoved = true;
                else
                    _blackKingMoved = true;

                if (new PositionDistance(move.OriginalPosition, move.NewPosition).DistanceX == 2)
                {
                    Rank rank = move.Player == Player.White ? Rank.One : Rank.Eight;
                    File rookFile = move.NewPosition.File == File.C ? File.A : File.H;
                    File newRookFile = move.NewPosition.File == File.C ? File.D : File.F;
                    SetPieceAt(newRookFile, rank, new ChessPiece(Piece.Rook, move.Player));
                    SetPieceAt(rookFile, rank, ChessPiece.None);
                }
            }
            else if (movingPiece.Piece == Piece.Rook)
            {
                if (move.Player == Player.White)
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == Rank.One)
                        _whiteRookAMoved = true;
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == Rank.One)
                        _whiteRookHMoved = true;
                }
                else
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == Rank.Eight)
                        _blackRookAMoved = true;
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == Rank.Eight)
                        _blackRookHMoved = true;
                }
            }
            SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece);
            SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, ChessPiece.None);
            WhoseTurn = Utilities.GetOpponentOf(move.Player);
            _moves.Add(move);
            return true;
        }
Ejemplo n.º 9
0
 public abstract bool IsValidMove(Move move, ChessGame game);
Ejemplo n.º 10
0
 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 = _halfMoveClock;
     gcd.FullMoveNumber = _fullMoveNumber;
     ChessGame copy = new ChessGame(gcd);
     copy.ApplyMove(move, true);
     return copy.IsInCheck(player);
 }
Ejemplo n.º 11
0
 protected virtual CastlingType ApplyCastle(Move move)
 {
     CastlingType castle;
     int rank = move.Player == Player.White ? 1 : 8;
     File rookFile;
     File newRookFile;
     if (move.NewPosition.File == File.C)
     {
         castle = CastlingType.QueenSide;
         rookFile = File.A;
         newRookFile = File.D;
     }
     else
     {
         castle = CastlingType.KingSide;
         rookFile = File.H;
         newRookFile = File.F;
     }
     SetPieceAt(newRookFile, rank, new Rook(move.Player));
     SetPieceAt(rookFile, rank, null);
     return castle;
 }
Ejemplo n.º 12
0
 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)
 { }
Ejemplo n.º 13
0
        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);
        }
Ejemplo n.º 14
0
        public virtual MoveType ApplyMove(Move move, bool alreadyValidated)
        {
            ChessUtilities.ThrowIfNull(move, "move");
            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);
            Piece newPiece = movingPiece;
            bool isCapture = capturedPiece != null;
            CastlingType castle = CastlingType.None;
            if (movingPiece is Pawn)
            {
                _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;
                    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);
                    type |= MoveType.Promotion;
                }
            }
            else if (movingPiece is King)
            {
                if (movingPiece.Owner == Player.White)
                    CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false;
                else
                    CanBlackCastleKingSide = CanBlackCastleQueenSide = false;

                if (new PositionDistance(move.OriginalPosition, move.NewPosition).DistanceX == 2 && CastlingCanBeLegal)
                {
                    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)
                        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;
                _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))
            {
                _halfMoveClock++;
                if (_halfMoveClock >= 100)
                {
                    fiftyMoves = true;
                }
                else
                {
                    fiftyMoves = false;
                }
            }
            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;
        }
Ejemplo n.º 15
0
        public virtual MoveType ApplyMove(Move move, bool alreadyValidated)
        {
            Piece captured;

            return(ApplyMove(move, alreadyValidated, out captured));
        }
Ejemplo n.º 16
0
 protected bool IsValidMove(Move move, bool validateCheck)
 {
     ChessUtilities.ThrowIfNull(move, "move");
     return(IsValidMove(move, validateCheck, true));
 }
Ejemplo n.º 17
0
        public virtual bool IsInCheck(Player player)
        {
            if (player == Player.None)
            {
                throw new ArgumentException("IsInCheck: Player.None is an invalid argument.");
            }
            Cache <bool> cache = player == Player.White ? inCheckCacheWhite : inCheckCacheBlack;

            if (cache.CachedAt == Moves.Count)
            {
                return(cache.Value);
            }

            Position kingPos = new Position(File.None, -1);

            for (int r = 1; r <= Board.Length; r++)
            {
                for (int f = 0; f < Board[8 - r].Length; f++)
                {
                    Piece curr = GetPieceAt((File)f, r);
                    if (curr is King && curr.Owner == player)
                    {
                        kingPos = new Position((File)f, r);
                        break;
                    }
                }
                if (kingPos != new Position(File.None, -1))
                {
                    break;
                }
            }

            if (kingPos.File == File.None)
            {
                return(cache.UpdateCache(false, Moves.Count));
            }

            for (int r = 1; r <= Board.Length; r++)
            {
                for (int f = 0; f < Board[8 - r].Length; f++)
                {
                    Piece curr = GetPieceAt((File)f, r);
                    if (curr == null)
                    {
                        continue;
                    }
                    Player      p     = curr.Owner;
                    Move        move  = new Move(new Position((File)f, r), kingPos, p);
                    List <Move> moves = new List <Move>();
                    if (curr is Pawn && ((move.NewPosition.Rank == 8 && move.Player == Player.White) || (move.NewPosition.Rank == 1 && move.Player == Player.Black)))
                    {
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'Q'));
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'R'));
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'B'));
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'N'));
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'K'));
                    }
                    else
                    {
                        moves.Add(move);
                    }
                    foreach (Move m in moves)
                    {
                        if (IsValidMove(m, false, false))
                        {
                            return(cache.UpdateCache(true, Moves.Count));
                        }
                    }
                }
            }
            return(cache.UpdateCache(false, Moves.Count));
        }
Ejemplo n.º 18
0
 public bool ApplyMove(Move move, bool alreadyValidated)
 {
     Utilities.ThrowIfNull(move, "move");
     return(ApplyMove(move, alreadyValidated, true));
 }
Ejemplo n.º 19
0
 protected virtual bool IsValidMoveKing(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     PositionDistance distance = new PositionDistance(move.OriginalPosition, move.NewPosition);
     if ((distance.DistanceX != 1 || distance.DistanceY != 1)
                 && (distance.DistanceX != 0 || distance.DistanceY != 1)
                 && (distance.DistanceX != 1 || distance.DistanceY != 0)
                 && (distance.DistanceX != 2 || distance.DistanceY != 0))
         return false;
     if (distance.DistanceX != 2)
         return true;
     return CanCastle(move);
 }
Ejemplo n.º 20
0
        protected virtual bool ApplyMove(Move move, bool alreadyValidated, bool validateHasAnyValidMoves)
        {
            Utilities.ThrowIfNull(move, "move");
            if (!alreadyValidated && !IsValidMove(move))
            {
                return(false);
            }
            ChessPiece movingPiece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);
            ChessPiece newPiece    = movingPiece;

            if (movingPiece.Piece == Piece.Pawn)
            {
                PositionDistance pd = new PositionDistance(move.OriginalPosition, move.NewPosition);
                if (pd.DistanceX == 1 && pd.DistanceY == 1 && GetPieceAt(move.NewPosition).Piece == Piece.None)
                { // en passant
                    SetPieceAt(move.NewPosition.File, move.OriginalPosition.Rank, ChessPiece.None);
                }
                if (move.NewPosition.Rank == (move.Player == Player.White ? Rank.Eight : Rank.One))
                {
                    newPiece = new ChessPiece(move.Promotion, move.Player);
                }
            }
            else if (movingPiece.Piece == Piece.King)
            {
                if (movingPiece.Player == Player.White)
                {
                    _whiteKingMoved = true;
                }
                else
                {
                    _blackKingMoved = true;
                }

                if (new PositionDistance(move.OriginalPosition, move.NewPosition).DistanceX == 2)
                {
                    Rank rank        = move.Player == Player.White ? Rank.One : Rank.Eight;
                    File rookFile    = move.NewPosition.File == File.C ? File.A : File.H;
                    File newRookFile = move.NewPosition.File == File.C ? File.D : File.F;
                    SetPieceAt(newRookFile, rank, new ChessPiece(Piece.Rook, move.Player));
                    SetPieceAt(rookFile, rank, ChessPiece.None);
                }
            }
            else if (movingPiece.Piece == Piece.Rook)
            {
                if (move.Player == Player.White)
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == Rank.One)
                    {
                        _whiteRookAMoved = true;
                    }
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == Rank.One)
                    {
                        _whiteRookHMoved = true;
                    }
                }
                else
                {
                    if (move.OriginalPosition.File == File.A && move.OriginalPosition.Rank == Rank.Eight)
                    {
                        _blackRookAMoved = true;
                    }
                    else if (move.OriginalPosition.File == File.H && move.OriginalPosition.Rank == Rank.Eight)
                    {
                        _blackRookHMoved = true;
                    }
                }
            }
            SetPieceAt(move.NewPosition.File, move.NewPosition.Rank, newPiece);
            SetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank, ChessPiece.None);
            WhoseTurn = Utilities.GetOpponentOf(move.Player);
            _moves.Add(move);
            return(true);
        }
Ejemplo n.º 21
0
 protected virtual bool IsValidMovePawn(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);
     if ((posDelta.DistanceX != 0 || posDelta.DistanceY != 1) && (posDelta.DistanceX != 1 || posDelta.DistanceY != 1)
                 && (posDelta.DistanceX != 0 || posDelta.DistanceY != 2))
         return false;
     if (move.Player == Player.White)
     {
         if ((int)move.OriginalPosition.Rank < (int)move.NewPosition.Rank)
             return false;
         if (move.NewPosition.Rank == Rank.Eight && move.Promotion == Piece.None)
             return false;
     }
     if (move.Player == Player.Black)
     {
         if ((int)move.OriginalPosition.Rank > (int)move.NewPosition.Rank)
             return false;
         if (move.NewPosition.Rank == Rank.One && move.Promotion == Piece.None)
             return false;
     }
     bool checkEnPassant = false;
     if (posDelta.DistanceY == 2)
     {
         if ((move.OriginalPosition.Rank != Rank.Two && move.Player == Player.White)
             || (move.OriginalPosition.Rank != Rank.Seven && move.Player == Player.Black))
             return false;
         if (move.OriginalPosition.Rank == Rank.Two && GetPieceAt(move.OriginalPosition.File, Rank.Three).Piece != Piece.None)
             return false;
         if (move.OriginalPosition.Rank == Rank.Seven && GetPieceAt(move.OriginalPosition.File, Rank.Six).Piece != Piece.None)
             return false;
     }
     if (posDelta.DistanceX == 0 && (posDelta.DistanceY == 1 || posDelta.DistanceY == 2))
     {
         if (GetPieceAt(move.NewPosition).Player != Player.None)
             return false;
     }
     else
     {
         if (GetPieceAt(move.NewPosition).Player != Utilities.GetOpponentOf(move.Player))
             checkEnPassant = true;
         if (GetPieceAt(move.NewPosition).Player == move.Player)
             return false;
     }
     if (checkEnPassant)
     {
         if (_moves.Count == 0)
         {
             return false;
         }
         if ((move.OriginalPosition.Rank != Rank.Five && move.Player == Player.White)
             || (move.OriginalPosition.Rank != Rank.Four && move.Player == Player.Black))
             return false;
         Move latestMove = _moves[_moves.Count - 1];
         if (latestMove.Player != Utilities.GetOpponentOf(move.Player))
             return false;
         if (move.Player == Player.White)
         {
             if (latestMove.OriginalPosition.Rank != Rank.Seven || latestMove.NewPosition.Rank != Rank.Five)
                 return false;
         }
         else // (m.Player == Players.Black)
         {
             if (latestMove.OriginalPosition.Rank != Rank.Two || latestMove.NewPosition.Rank != Rank.Four)
                 return false;
         }
         if (move.NewPosition.File != latestMove.NewPosition.File)
             return false;
     }
     return true;
 }
Ejemplo n.º 22
0
        /// <summary>
        /// 生成 SAN 字符串。
        /// </summary>
        /// <param name="gameBeforeTheMove"></param>
        /// <returns></returns>
        public string GenerateSANString(ChessGame gameBeforeTheMove)
        {
            string SANResult;
            if (Castling.Equals(CastlingType.KingSide))
            {
                SANResult = "O-O";
            }
            else if (Castling.Equals(CastlingType.QueenSide))
            {
                SANResult = "O-O-O";
            }
            else
            {
                var sb = new System.Text.StringBuilder();

                if (!(Piece is Pieces.Pawn))
                {
                    sb.Append(char.ToUpper(Piece.GetFenCharacter()));
                }

                Piece[][] board = gameBeforeTheMove.GetBoard();
                List<Move> validMoves = new List<Move>();
                for (int r = 0; r < 8; r++)
                {
                    for (int f = 0; f < 8; f++)
                    {
                        if (board[r][f] != Piece) continue;
                        Move m = new Move(new Position((File)f, 8 - r), this.NewPosition, this.Player, this.Promotion);
                        if (gameBeforeTheMove.IsValidMove(m))
                        {
                            validMoves.Add(m);
                        }
                    }
                }
                if (validMoves.Count == 0) throw new PgnException("This move " + this.ToString() + " is not valid for gameBeforeTheMove.");
                else if (validMoves.Count > 1)
                {
                    bool fileUnique = true;
                    bool rankUnique = true;
                    foreach (var move in validMoves)
                    {
                        if(!(move.OriginalPosition.Equals(this.OriginalPosition)))
                        {
                            if (move.OriginalPosition.File == this.OriginalPosition.File)
                            {
                                fileUnique = false;
                            }
                            if (move.OriginalPosition.Rank == this.OriginalPosition.Rank)
                            {
                                rankUnique = false;
                            }
                        }
                    }

                    if (fileUnique)
                        sb.Append((char)((int)'a' + (int)this.OriginalPosition.File));
                    else if (rankUnique)
                        sb.Append(this.OriginalPosition.Rank.ToString());
                    else
                    {
                        sb.Append((char)((int)'a' + (int)this.OriginalPosition.File));
                        sb.Append(this.OriginalPosition.Rank.ToString());
                    }
                }

                if (IsCapture)
                    sb.Append("x");

                sb.Append(this.NewPosition.ToString().ToLower());

                if (Promotion.HasValue)
                {
                    sb.Append("=");
                    sb.Append(Promotion.Value);
                }

                if (IsCheckmate.HasValue && IsCheckmate.Value)
                {
                    sb.Append("#");
                }
                else if (IsChecking.HasValue && IsChecking.Value)
                {
                    sb.Append("+");
                }

                SANResult = sb.ToString();
            }
            try
            {
                ChessDotNet.PgnMoveReader.ParseMove(SANResult, Player, gameBeforeTheMove);
            }
            catch (PgnException)
            {
                throw new System.ArgumentException("This move " + SANResult + " is not valid for gameBeforeTheMove.");
            }
            catch (System.ArgumentException)
            {
                throw new System.ArgumentException("This move " + SANResult + " is not valid for gameBeforeTheMove.");
            }
            this._storedSANString = SANResult;
            return SANResult;
        }
Ejemplo n.º 23
0
 protected virtual bool IsValidMoveKnight(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);
     if ((posDelta.DistanceX != 2 || posDelta.DistanceY != 1) && (posDelta.DistanceX != 1 || posDelta.DistanceY != 2))
         return false;
     return true;
 }
Ejemplo n.º 24
0
 public bool IsValidMove(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     return IsValidMove(move, true);
 }
Ejemplo n.º 25
0
        public virtual bool IsInCheck(Player player)
        {
            if (player == Player.None)
            {
                throw new ArgumentException("IsInCheck: Player.None is an invalid argument.");
            }
            Cache<bool> cache = player == Player.White ? inCheckCacheWhite : inCheckCacheBlack;
            if (cache.CachedAt == Moves.Count)
            {
                return cache.Value;
            }

            Position kingPos = new Position(File.None, -1);

            for (int r = 1; r <= Board.Length; r++)
            {
                for (int f = 0; f < Board[8 - r].Length; f++)
                {
                    Piece curr = GetPieceAt((File)f, r);
                    if (curr is King && curr.Owner == player)
                    {
                        kingPos = new Position((File)f, r);
                        break;
                    }
                }
                if (kingPos != new Position(File.None, -1))
                {
                    break;
                }
            }

            if (kingPos.File == File.None)
                return cache.UpdateCache(false, Moves.Count);

            for (int r = 1; r <= Board.Length; r++)
            {
                for (int f = 0; f < Board[8 - r].Length; f++)
                {
                    Piece curr = GetPieceAt((File)f, r);
                    if (curr == null) continue;
                    Player p = curr.Owner;
                    Move move = new Move(new Position((File)f, r), kingPos, p);
                    List<Move> moves = new List<Move>();
                    if (curr is Pawn && ((move.NewPosition.Rank == 8 && move.Player == Player.White) || (move.NewPosition.Rank == 1 && move.Player == Player.Black)))
                    {
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'Q'));
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'R'));
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'B'));
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'N'));
                        moves.Add(new Move(move.OriginalPosition, move.NewPosition, move.Player, 'K'));
                    }
                    else
                    {
                        moves.Add(move);
                    }
                    foreach (Move m in moves)
                    {
                        if (IsValidMove(m, false, false))
                        {
                            return cache.UpdateCache(true, Moves.Count);
                        }
                    }
                }
            }
            return cache.UpdateCache(false, Moves.Count);
        }
Ejemplo n.º 26
0
 protected virtual bool CanCastle(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     if (move.Player == Player.White)
     {
         if (move.OriginalPosition.File != File.E || move.OriginalPosition.Rank != Rank.One)
             return false;
         if (_whiteKingMoved || (Status.Event == GameEvent.Check && Status.PlayerWhoCausedEvent == Player.Black))
             return false;
         if (move.NewPosition.File == File.C)
         {
             if (_whiteRookAMoved || GetPieceAt(File.D, Rank.One).Piece != Piece.None
                 || GetPieceAt(File.C, Rank.One).Piece != Piece.None
                 || GetPieceAt(File.B, Rank.One).Piece != Piece.None
                 || WouldBeInCheckAfter(new Move(new Position(File.E, Rank.One), new Position(File.D, Rank.One), Player.White), Player.White)
                 || WouldBeInCheckAfter(new Move(new Position(File.E, Rank.One), new Position(File.C, Rank.One), Player.White), Player.White))
                 return false;
         }
         else
         {
             if (_whiteRookHMoved || GetPieceAt(File.F, Rank.One).Piece != Piece.None
                 || GetPieceAt(File.G, Rank.One).Piece != Piece.None
                 || WouldBeInCheckAfter(new Move(new Position(File.E, Rank.One), new Position(File.F, Rank.One), Player.White), Player.White)
                 || WouldBeInCheckAfter(new Move(new Position(File.E, Rank.One), new Position(File.G, Rank.One), Player.White), Player.White))
                 return false;
         }
     }
     else
     {
         if (move.OriginalPosition.File != File.E || move.OriginalPosition.Rank != Rank.Eight)
             return false;
         if (_blackKingMoved || (Status.Event == GameEvent.Check && Status.PlayerWhoCausedEvent == Player.White))
             return false;
         if (move.NewPosition.File == File.C)
         {
             if (_blackRookAMoved || GetPieceAt(File.D, Rank.Eight).Piece != Piece.None
                 || GetPieceAt(File.C, Rank.Eight).Piece != Piece.None
                 || GetPieceAt(File.B, Rank.Eight).Piece != Piece.None
                 || WouldBeInCheckAfter(new Move(new Position(File.E, Rank.Eight), new Position(File.D, Rank.Eight), Player.Black), Player.Black)
                 || WouldBeInCheckAfter(new Move(new Position(File.E, Rank.Eight), new Position(File.C, Rank.Eight), Player.Black), Player.Black))
                 return false;
         }
         else
         {
             if (_blackRookHMoved || GetPieceAt(File.F, Rank.Eight).Piece != Piece.None
                 || GetPieceAt(File.G, Rank.Eight).Piece != Piece.None
                 || WouldBeInCheckAfter(new Move(new Position(File.E, Rank.Eight), new Position(File.F, Rank.Eight), Player.Black), Player.Black)
                 || WouldBeInCheckAfter(new Move(new Position(File.E, Rank.Eight), new Position(File.G, Rank.Eight), Player.Black), Player.Black))
                 return false;
         }
     }
     return true;
 }
Ejemplo n.º 27
0
 public bool IsValidMove(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     return(IsValidMove(move, true));
 }
Ejemplo n.º 28
0
 protected virtual bool IsValidMoveBishop(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);
     if (posDelta.DistanceX != posDelta.DistanceY)
         return false;
     bool increasingRank = (int)move.NewPosition.Rank > (int)move.OriginalPosition.Rank;
     bool increasingFile = (int)move.NewPosition.File > (int)move.OriginalPosition.File;
     for (int f = (int)move.OriginalPosition.File + (increasingFile ? 1 : -1), r = (int)move.OriginalPosition.Rank + (increasingRank ? 1 : -1);
          increasingFile ? f < (int)move.NewPosition.File : f > (int)move.NewPosition.File;
          f += increasingFile ? 1 : -1, r += increasingRank ? 1 : -1)
     {
         if (Board[r][f].Player != Player.None)
         {
             return false;
         }
     }
     return true;
 }
Ejemplo n.º 29
0
 protected virtual bool CanCastle(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     if (move.Player == Player.White)
     {
         if (move.OriginalPosition.File != File.E || move.OriginalPosition.Rank != Rank.One)
         {
             return(false);
         }
         if (_whiteKingMoved || (Status.Event == GameEvent.Check && Status.PlayerWhoCausedEvent == Player.Black))
         {
             return(false);
         }
         if (move.NewPosition.File == File.C)
         {
             if (_whiteRookAMoved || GetPieceAt(File.D, Rank.One).Piece != Piece.None ||
                 GetPieceAt(File.C, Rank.One).Piece != Piece.None ||
                 GetPieceAt(File.B, Rank.One).Piece != Piece.None ||
                 WouldBeInCheckAfter(new Move(new Position(File.E, Rank.One), new Position(File.D, Rank.One), Player.White), Player.White) ||
                 WouldBeInCheckAfter(new Move(new Position(File.E, Rank.One), new Position(File.C, Rank.One), Player.White), Player.White))
             {
                 return(false);
             }
         }
         else
         {
             if (_whiteRookHMoved || GetPieceAt(File.F, Rank.One).Piece != Piece.None ||
                 GetPieceAt(File.G, Rank.One).Piece != Piece.None ||
                 WouldBeInCheckAfter(new Move(new Position(File.E, Rank.One), new Position(File.F, Rank.One), Player.White), Player.White) ||
                 WouldBeInCheckAfter(new Move(new Position(File.E, Rank.One), new Position(File.G, Rank.One), Player.White), Player.White))
             {
                 return(false);
             }
         }
     }
     else
     {
         if (move.OriginalPosition.File != File.E || move.OriginalPosition.Rank != Rank.Eight)
         {
             return(false);
         }
         if (_blackKingMoved || (Status.Event == GameEvent.Check && Status.PlayerWhoCausedEvent == Player.White))
         {
             return(false);
         }
         if (move.NewPosition.File == File.C)
         {
             if (_blackRookAMoved || GetPieceAt(File.D, Rank.Eight).Piece != Piece.None ||
                 GetPieceAt(File.C, Rank.Eight).Piece != Piece.None ||
                 GetPieceAt(File.B, Rank.Eight).Piece != Piece.None ||
                 WouldBeInCheckAfter(new Move(new Position(File.E, Rank.Eight), new Position(File.D, Rank.Eight), Player.Black), Player.Black) ||
                 WouldBeInCheckAfter(new Move(new Position(File.E, Rank.Eight), new Position(File.C, Rank.Eight), Player.Black), Player.Black))
             {
                 return(false);
             }
         }
         else
         {
             if (_blackRookHMoved || GetPieceAt(File.F, Rank.Eight).Piece != Piece.None ||
                 GetPieceAt(File.G, Rank.Eight).Piece != Piece.None ||
                 WouldBeInCheckAfter(new Move(new Position(File.E, Rank.Eight), new Position(File.F, Rank.Eight), Player.Black), Player.Black) ||
                 WouldBeInCheckAfter(new Move(new Position(File.E, Rank.Eight), new Position(File.G, Rank.Eight), Player.Black), Player.Black))
             {
                 return(false);
             }
         }
     }
     return(true);
 }
Ejemplo n.º 30
0
 protected virtual bool IsValidMoveQueen(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     return IsValidMoveBishop(move) || IsValidMoveRook(move);
 }
Ejemplo n.º 31
0
        protected virtual bool IsValidMovePawn(Move move)
        {
            Utilities.ThrowIfNull(move, "move");
            PositionDistance posDelta = new PositionDistance(move.OriginalPosition, move.NewPosition);

            if ((posDelta.DistanceX != 0 || posDelta.DistanceY != 1) && (posDelta.DistanceX != 1 || posDelta.DistanceY != 1) &&
                (posDelta.DistanceX != 0 || posDelta.DistanceY != 2))
            {
                return(false);
            }
            if (move.Player == Player.White)
            {
                if ((int)move.OriginalPosition.Rank < (int)move.NewPosition.Rank)
                {
                    return(false);
                }
                if (move.NewPosition.Rank == Rank.Eight && move.Promotion == Piece.None)
                {
                    return(false);
                }
            }
            if (move.Player == Player.Black)
            {
                if ((int)move.OriginalPosition.Rank > (int)move.NewPosition.Rank)
                {
                    return(false);
                }
                if (move.NewPosition.Rank == Rank.One && move.Promotion == Piece.None)
                {
                    return(false);
                }
            }
            bool checkEnPassant = false;

            if (posDelta.DistanceY == 2)
            {
                if ((move.OriginalPosition.Rank != Rank.Two && move.Player == Player.White) ||
                    (move.OriginalPosition.Rank != Rank.Seven && move.Player == Player.Black))
                {
                    return(false);
                }
                if (move.OriginalPosition.Rank == Rank.Two && GetPieceAt(move.OriginalPosition.File, Rank.Three).Piece != Piece.None)
                {
                    return(false);
                }
                if (move.OriginalPosition.Rank == Rank.Seven && GetPieceAt(move.OriginalPosition.File, Rank.Six).Piece != Piece.None)
                {
                    return(false);
                }
            }
            if (posDelta.DistanceX == 0 && (posDelta.DistanceY == 1 || posDelta.DistanceY == 2))
            {
                if (GetPieceAt(move.NewPosition).Player != Player.None)
                {
                    return(false);
                }
            }
            else
            {
                if (GetPieceAt(move.NewPosition).Player != Utilities.GetOpponentOf(move.Player))
                {
                    checkEnPassant = true;
                }
                if (GetPieceAt(move.NewPosition).Player == move.Player)
                {
                    return(false);
                }
            }
            if (checkEnPassant)
            {
                if (_moves.Count == 0)
                {
                    return(false);
                }
                if ((move.OriginalPosition.Rank != Rank.Five && move.Player == Player.White) ||
                    (move.OriginalPosition.Rank != Rank.Four && move.Player == Player.Black))
                {
                    return(false);
                }
                Move latestMove = _moves[_moves.Count - 1];
                if (latestMove.Player != Utilities.GetOpponentOf(move.Player))
                {
                    return(false);
                }
                if (move.Player == Player.White)
                {
                    if (latestMove.OriginalPosition.Rank != Rank.Seven || latestMove.NewPosition.Rank != Rank.Five)
                    {
                        return(false);
                    }
                }
                else // (m.Player == Players.Black)
                {
                    if (latestMove.OriginalPosition.Rank != Rank.Two || latestMove.NewPosition.Rank != Rank.Four)
                    {
                        return(false);
                    }
                }
                if (move.NewPosition.File != latestMove.NewPosition.File)
                {
                    return(false);
                }
            }
            return(true);
        }
Ejemplo n.º 32
0
 public bool ApplyMove(Move move, bool alreadyValidated)
 {
     Utilities.ThrowIfNull(move, "move");
     return ApplyMove(move, alreadyValidated, true);
 }
Ejemplo n.º 33
0
 protected virtual bool IsValidMoveQueen(Move move)
 {
     Utilities.ThrowIfNull(move, "move");
     return(IsValidMoveBishop(move) || IsValidMoveRook(move));
 }
Ejemplo n.º 34
0
 protected virtual ReadOnlyCollection<Move> GetValidMovesKnight(Position from, bool returnIfAny)
 {
     Utilities.ThrowIfNull(from, "from");
     List<Move> validMoves = new List<Move>();
     ChessPiece cp = GetPieceAt(from);
     int l0 = Board.Length;
     int l1 = Board[0].Length;
     int[][] directions = new int[][] { new int[] { 2, 1 }, new int[] { -2, -1 }, new int[] { 1, 2 }, new int[] { -1, -2 },
                 new int[] { 1, -2 }, new int[] { -1, 2 }, new int[] { 2, -1 }, new int[] { -2, 1 } };
     foreach (int[] dir in directions)
     {
         if ((int)from.File + dir[0] < 0 || (int)from.File + dir[0] >= l1
             || (int)from.Rank + dir[1] < 0 || (int)from.Rank + dir[1] >= l0)
             continue;
         Move move = new Move(from, new Position(from.File + dir[0], from.Rank + dir[1]), cp.Player);
         if (IsValidMove(move))
         {
             validMoves.Add(move);
             if (returnIfAny)
                 return new ReadOnlyCollection<Move>(validMoves);
         }
     }
     return new ReadOnlyCollection<Move>(validMoves);
 }
Ejemplo n.º 35
0
        protected virtual bool IsValidMove(Move move, bool validateCheck)
        {
            Utilities.ThrowIfNull(move, "move");
            if (move.OriginalPosition.Equals(move.NewPosition))
            {
                return(false);
            }
            ChessPiece piece = GetPieceAt(move.OriginalPosition.File, move.OriginalPosition.Rank);

            if (move.Player != WhoseTurn)
            {
                return(false);
            }
            if (piece.Player != move.Player)
            {
                return(false);
            }
            if (GetPieceAt(move.NewPosition).Player == move.Player)
            {
                return(false);
            }
            switch (piece.Piece)
            {
            case Piece.King:
                if (!IsValidMoveKing(move))
                {
                    return(false);
                }
                break;

            case Piece.Pawn:
                if (!IsValidMovePawn(move))
                {
                    return(false);
                }
                break;

            case Piece.Queen:
                if (!IsValidMoveQueen(move))
                {
                    return(false);
                }
                break;

            case Piece.Rook:
                if (!IsValidMoveRook(move))
                {
                    return(false);
                }
                break;

            case Piece.Bishop:
                if (!IsValidMoveBishop(move))
                {
                    return(false);
                }
                break;

            case Piece.Knight:
                if (!IsValidMoveKnight(move))
                {
                    return(false);
                }
                break;

            default:
                return(false);
            }
            if (validateCheck && WouldBeInCheckAfter(move, move.Player))
            {
                return(false);
            }

            return(true);
        }
Ejemplo n.º 36
0
 protected virtual bool WouldBeInCheckAfter(Move move, Player player)
 {
     Utilities.ThrowIfNull(move, "move");
     ChessGame copy = new ChessGame(Board, player, false);
     copy.ApplyMove(move, true, false);
     GameStatus status = copy.CalculateStatus(player, false);
     return status.Event == GameEvent.Check && status.PlayerWhoCausedEvent != player;
 }
Ejemplo n.º 37
0
 protected bool IsValidMove(Move move, bool validateCheck)
 {
     ChessUtilities.ThrowIfNull(move, "move");
     return IsValidMove(move, validateCheck, true);
 }