ChessDotNet.ChessGame.MapPgnCharToPiece C# (CSharp) Method

MapPgnCharToPiece() public method

public MapPgnCharToPiece ( char c, Player owner ) : Piece
c char
owner Player
return Piece
        public virtual Piece MapPgnCharToPiece(char c, Player owner)
        {
            switch (c)
            {
                case 'K':
                    return owner == Player.White ? FenMappings['K'] : FenMappings['k'];
                case 'Q':
                    return owner == Player.White ? FenMappings['Q'] : FenMappings['q'];
                case 'R':
                    return owner == Player.White ? FenMappings['R'] : FenMappings['r'];
                case 'B':
                    return owner == Player.White ? FenMappings['B'] : FenMappings['b'];
                case 'N':
                    return owner == Player.White ? FenMappings['N'] : FenMappings['n'];
                case 'P':
                    return owner == Player.White ? FenMappings['P'] : FenMappings['p'];
                default:
                    if (!char.IsLower(c))
                    {
                        throw new PgnException("Unrecognized piece type: " + c.ToString());
                    }
                    return owner == Player.White ? FenMappings['P'] : FenMappings['p'];
            }
        }

Usage Example

Example #1
0
        /// <summary>
        /// 将 SAN 字符串解析为 Move。
        /// </summary>
        /// <param name="moveInStr"></param>
        /// <param name="player"></param>
        /// <param name="game"></param>
        /// <returns></returns>
        public static Move ParseMove(string moveInStr, Player player, ChessGame game)
        {
            try
            {
                string move = moveInStr.TrimEnd('#', '?', '!', '+').Trim();

                Position origin      = null;
                Position destination = null;
                Piece    piece       = null;
                char?    promotion   = null;

                if (move.Length == 0)
                {
                    throw new PgnException("The length of Move string is zero.");
                }

                if (move.Length > 2)
                {
                    string possiblePromotionPiece = move.Substring(move.Length - 2).ToUpperInvariant();
                    if (possiblePromotionPiece[0] == '=')
                    {
                        promotion = possiblePromotionPiece[1];
                        move      = move.Remove(move.Length - 2, 2);
                    }
                }

                if (move.ToUpperInvariant() == "O-O")
                {
                    int r = player == Player.White ? 1 : 8;
                    origin      = new Position(File.E, r);
                    destination = new Position(File.G, r);
                    piece       = new King(player);
                }
                else if (move.ToUpperInvariant() == "O-O-O")
                {
                    int r = player == Player.White ? 1 : 8;
                    origin      = new Position(File.E, r);
                    destination = new Position(File.C, r);
                    piece       = new King(player);
                }

                if (piece == null)
                {
                    piece = game.MapPgnCharToPiece(move[0], player);
                }
                if (!(piece is Pawn))
                {
                    move = move.Remove(0, 1);
                }

                int  rankRestriction = -1;
                File fileRestriction = File.None;
                if (destination == null)
                {
                    if (move.Length == 0)
                    {
                        throw new PgnException("The position of Move is empty.");
                    }

                    if (move[0] == 'x')
                    {
                        move = move.Remove(0, 1);
                    }
                    else if (move.Length == 4 && move[1] == 'x')
                    {
                        move = move.Remove(1, 1);
                    }

                    if (move.Length == 2)
                    {
                        destination = new Position(move);
                    }
                    else if (move.Length == 3)
                    {
                        if (char.IsDigit(move[0]))
                        {
                            rankRestriction = int.Parse(move[0].ToString());
                        }
                        else
                        {
                            bool recognized = Enum.TryParse <File>(move[0].ToString(), true, out fileRestriction);
                            if (!recognized)
                            {
                                throw new PgnException("Invalid PGN: unrecognized origin file.");
                            }
                        }
                        destination = new Position(move.Remove(0, 1));
                    }
                    else if (move.Length == 4)
                    {
                        origin      = new Position(move.Substring(0, 2));
                        destination = new Position(move.Substring(2, 2));
                    }
                    else
                    {
                        throw new PgnException("Invalid PGN.");
                    }
                }

                Move m;
                if (origin != null)
                {
                    m = new Move(origin, destination, player, promotion);
                    if (game.IsValidMove(m))
                    {
                        return(m);
                    }
                    else
                    {
                        throw new PgnException("Invalid PGN: contains invalid moves.");
                    }
                }
                else
                {
                    Piece[][]   board      = game.GetBoard();
                    List <Move> validMoves = new List <Move>();
                    for (int r = 0; r < game.BoardHeight; r++)
                    {
                        if (rankRestriction != -1 && r != 8 - rankRestriction)
                        {
                            continue;
                        }
                        for (int f = 0; f < game.BoardWidth; f++)
                        {
                            if (fileRestriction != File.None && f != (int)fileRestriction)
                            {
                                continue;
                            }
                            if (board[r][f] != piece)
                            {
                                continue;
                            }
                            m = new Move(new Position((File)f, 8 - r), destination, player, promotion);
                            if (game.IsValidMove(m, true))
                            {
                                validMoves.Add(m);
                            }
                        }
                    }
                    if (validMoves.Count == 0)
                    {
                        throw new PgnException("Invalid PGN: contains invalid moves.");
                    }
                    if (validMoves.Count > 1)
                    {
                        throw new PgnException("Invalid PGN: contains ambiguous moves.");
                    }
                    return(validMoves[0]);
                }
            }
            catch (Exception e)
            {
                if (e is PgnException eP)
                {
                    throw eP;
                }
                else
                {
                    throw new PgnException(e.Message + Environment.NewLine + e.StackTrace);
                }
            }
        }