GetBoard() public method

public GetBoard ( ) : ChessDotNet.Piece[][]
return ChessDotNet.Piece[][]
Esempio n. 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);
                }
            }
        }
Esempio n. 2
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;
        }