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 (!ValidFenBoardRows.Contains(rows.Length))
            {
                throw new ArgumentException("The board in the FEN string has an invalid number of rows.");
            }
            GameCreationData data = new GameCreationData();

            data.Board = InterpretBoardOfFen(parts[0]);

            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);
        }
Beispiel #2
0
        protected virtual GameCreationData FenStringToGameCreationData(string fen)
        {
            Dictionary <char, ChessPiece> 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.");
            }
            ChessPiece[][] board = new ChessPiece[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];
                ChessPiece[] currentRow = new ChessPiece[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 = ChessPlayer.White;
            }
            else if (parts[1] == "b")
            {
                data.WhoseTurn = ChessPlayer.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
            {
                BoardPosition ep = new BoardPosition(parts[3]);
                if ((data.WhoseTurn == ChessPlayer.White && (ep.Rank != 6 || !(data.Board[3][(int)ep.File] is Pawn))) ||
                    (data.WhoseTurn == ChessPlayer.Black && (ep.Rank != 3 || !(data.Board[4][(int)ep.File] is Pawn))))
                {
                    throw new ArgumentException("Invalid en passant field in FEN.");
                }
                data.EnPassant = ep;
            }

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

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

            return(data);
        }