예제 #1
0
 public ChessGame(GameCreationData data)
 {
     UseGameCreationData(data);
 }
예제 #2
0
        public ChessGame(string fen)
        {
            GameCreationData data = FenStringToGameCreationData(fen);

            UseGameCreationData(data);
        }
예제 #3
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);
 }
예제 #4
0
        protected virtual GameCreationData FenStringToGameCreationData(string fen)
        {
            Dictionary<char, Piece> fenMappings = FenMappings;
            string[] parts = fen.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
            if (!AllowedFenPartsLength.Contains(parts.Length)) throw new ArgumentException("The FEN string has too much, or too few, parts.");
            Piece[][] board = new Piece[8][];
            string[] rows = parts[0].Split('/');
            if (rows.Length != 8) throw new ArgumentException("The board in the FEN string does not have 8 rows.");
            GameCreationData data = new GameCreationData();
            for (int i = 0; i < 8; i++)
            {
                string row = rows[i];
                Piece[] currentRow = new Piece[8] { null, null, null, null, null, null, null, null };
                int j = 0;
                foreach (char c in row)
                {
                    if (char.IsDigit(c))
                    {
                        j += (int)char.GetNumericValue(c);
                        continue;
                    }
                    if (!fenMappings.ContainsKey(c)) throw new ArgumentException("The FEN string contains an unknown piece.");
                    currentRow[j] = fenMappings[c];
                    j++;
                }
                if (j != 8)
                {
                    throw new ArgumentException("Not enough pieces provided for a row in the FEN string.");
                }
                board[i] = currentRow;
            }
            data.Board = board;

            if (parts[1] == "w")
            {
                data.WhoseTurn = Player.White;
            }
            else if (parts[1] == "b")
            {
                data.WhoseTurn = Player.Black;
            }
            else
            {
                throw new ArgumentException("Expected `w` or `b` for the active player in the FEN string.");
            }

            if (parts[2].Contains('K')) data.CanWhiteCastleKingSide = true;
            else data.CanWhiteCastleKingSide = false;

            if (parts[2].Contains('Q')) data.CanWhiteCastleQueenSide = true;
            else data.CanWhiteCastleQueenSide = false;

            if (parts[2].Contains('k')) data.CanBlackCastleKingSide = true;
            else data.CanBlackCastleKingSide = false;

            if (parts[2].Contains('q')) data.CanBlackCastleQueenSide = true;
            else data.CanBlackCastleQueenSide = false;

            if (parts[3] == "-") data.EnPassant = null;
            else
            {
                Position ep = new Position(parts[3]);
                if ((data.WhoseTurn == Player.White && (ep.Rank != 6 || !(data.Board[3][(int)ep.File] is Pawn))) ||
                    (data.WhoseTurn == Player.Black && (ep.Rank != 3 || !(data.Board[4][(int)ep.File] is Pawn))))
                {
                    throw new ArgumentException("Invalid en passant field in FEN.");
                }
                data.EnPassant = ep;
            }

            int halfmoveClock;
            if (int.TryParse(parts[4], out halfmoveClock))
            {
                data.HalfMoveClock = halfmoveClock;
            }
            else
            {
                throw new ArgumentException("Halfmove clock in FEN is invalid.");
            }

            int fullMoveNumber;
            if (int.TryParse(parts[5], out fullMoveNumber))
            {
                data.FullMoveNumber = fullMoveNumber;
            }
            else
            {
                throw new ArgumentException("Fullmove number in FEN is invalid.");
            }

            return data;
        }
예제 #5
0
        protected virtual void UseGameCreationData(GameCreationData data)
        {
            Board = CloneBoard(data.Board);
            WhoseTurn = data.WhoseTurn;
            Piece e1 = GetPieceAt(File.E, 1);
            Piece e8 = GetPieceAt(File.E, 8);
            Piece a1 = GetPieceAt(File.A, 1);
            Piece h1 = GetPieceAt(File.H, 1);
            Piece a8 = GetPieceAt(File.A, 8);
            Piece h8 = GetPieceAt(File.H, 8);
            CanBlackCastleKingSide = CanBlackCastleQueenSide = CanWhiteCastleKingSide = CanWhiteCastleQueenSide = CastlingCanBeLegal;
            if (CastlingCanBeLegal)
            {
                if (!(e1 is King) || e1.Owner != Player.White)
                    CanWhiteCastleKingSide = CanWhiteCastleQueenSide = false;
                if (!(e8 is King) || e8.Owner != Player.Black)
                    CanBlackCastleKingSide = CanBlackCastleQueenSide = false;
                if (!(a1 is Rook) || a1.Owner != Player.White || !data.CanWhiteCastleQueenSide)
                    CanWhiteCastleQueenSide = false;
                if (!(h1 is Rook) || h1.Owner != Player.White || !data.CanWhiteCastleKingSide)
                    CanWhiteCastleKingSide = false;
                if (!(a8 is Rook) || a8.Owner != Player.Black || !data.CanBlackCastleQueenSide)
                    CanBlackCastleQueenSide = false;
                if (!(h8 is Rook) || h8.Owner != Player.Black || !data.CanBlackCastleKingSide)
                    CanBlackCastleKingSide = false;
            }

            if (data.EnPassant != null)
            {
                DetailedMove latestMove = new DetailedMove(new Move(new Position(data.EnPassant.File, data.WhoseTurn == Player.White ? 7 : 2),
                                                                    new Position(data.EnPassant.File, data.WhoseTurn == Player.White ? 5 : 4),
                                                                    ChessUtilities.GetOpponentOf(data.WhoseTurn)),
                                          new Pawn(ChessUtilities.GetOpponentOf(data.WhoseTurn)),
                                          false,
                                          CastlingType.None);
                _moves.Add(latestMove);
            }

            _halfMoveClock = data.HalfMoveClock;
            _fullMoveNumber = data.FullMoveNumber;
        }
예제 #6
0
 public ChessGame(GameCreationData data)
 {
     UseGameCreationData(data);
 }