Beispiel #1
0
        /// <summary>
        /// このReaderで与えられたファイルを処理できるか調べます。
        /// </summary>
        public bool CanHandle(TextReader reader)
        {
            try
            {
                this.reader      = reader;
                this.currentLine = null;
                this.lineNumber  = 0;
                this.startBoard  = null;

                // ヘッダを1行読めれば、kif or ki2 or bod 形式の
                // どれかのファイルとします。
                var parser = new BodParser();
                for (var i = 0; i < 1; ++i)
                {
                    var line = ReadNextLine();

                    if (line == null)
                    {
                        return(true);
                    }

                    if (!ParseHeaderLine(line, parser))
                    {
                        return(false);
                    }
                }

                return(true);
            }
            catch (Exception)
            {
                return(false);
            }
        }
Beispiel #2
0
 /// <summary>
 /// 開始局面を取得します。
 /// </summary>
 /// <remarks>
 /// 局面はbod形式と"手合割"ヘッダの両方で与えられることがあり、
 /// しかも両者が矛盾していることがあります。
 ///
 /// そのため、開始局面については優先順位を与えて、
 /// その順序に従った局面を返すことにしています。
 ///
 /// 具体的な優先順位は
 //   1, bod形式の局面をパースしたもの
 //   2, "手合割"ヘッダで与えられる局面
 //   3, 平手局面
 // となります。
 /// </remarks>
 private Board MakeStartBoard(BodParser parser)
 {
     return(
         parser.IsCompleted ? parser.Board :
         this.startBoard != null ? this.startBoard :
         new Board());
 }
Beispiel #3
0
        /// <summary>
        /// ヘッダー部分をまとめてパースします。
        /// </summary>
        /// <remarks>
        /// 開始局面の設定も行います。
        /// </remarks>
        private KifuHeader ParseHeader(KifMoveNode head)
        {
            var header = new KifuHeader();
            var parser = new BodParser();

            while (ParseHeaderLine(this.currentLine, parser, header, head))
            {
                ReadNextLine();
            }

            if (parser.IsBoardParsing)
            {
                throw new FileFormatException(
                          "局面の読み取りを完了できませんでした。");
            }

            this.startBoard = MakeStartBoard(parser);
            return(header);
        }
Beispiel #4
0
        /// <summary>
        /// bod形式の文字列から、局面を読み取ります。
        /// </summary>
        public static Board Parse(string text)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }

            var parser = new BodParser();
            var lines  = text.Split(
                new char[] { '\n', '\r' },
                StringSplitOptions.RemoveEmptyEntries);

            foreach (var line in lines)
            {
                if (KifUtil.IsCommentLine(line))
                {
                    continue;
                }

                // 局面の読み取りを試みます。
                if (parser.TryParse(line))
                {
                    continue;
                }

                var item = KifUtil.ParseHeaderItem(line);
                if (item != null)
                {
                    continue;
                }

                break;
            }

            if (!parser.IsCompleted)
            {
                throw new ShogiException(
                          "局面の読み取りを完了できませんでした。");
            }

            return(parser.Board);
        }
Beispiel #5
0
        /// <summary>
        /// bod形式の文字列から、局面を読み取ります。
        /// </summary>
        public static Board Parse(string text)
        {
            if (text == null)
            {
                throw new ArgumentNullException("text");
            }

            var parser = new BodParser();
            var lines = text.Split(
                new char[] { '\n', '\r' },
                StringSplitOptions.RemoveEmptyEntries);

            foreach (var line in lines)
            {
                if (KifUtil.IsCommentLine(line))
                {
                    continue;
                }

                // 局面の読み取りを試みます。
                if (parser.TryParse(line))
                {
                    continue;
                }

                var item = KifUtil.ParseHeaderItem(line);
                if (item != null)
                {
                    continue;
                }

                break;
            }

            if (!parser.IsCompleted)
            {
                throw new ShogiException(
                    "局面の読み取りを完了できませんでした。");
            }

            return parser.Board;
        }
Beispiel #6
0
        /// <summary>
        /// このReaderで与えられたファイルを処理できるか調べます。
        /// </summary>
        public bool CanHandle(TextReader reader)
        {
            try
            {
                this.reader = reader;
                this.currentLine = null;
                this.lineNumber = 0;
                this.startBoard = null;

                // ヘッダを1行読めれば、kif or ki2 or bod 形式の
                // どれかのファイルとします。
                var parser = new BodParser();
                for (var i = 0; i < 1; ++i)
                {
                    var line = ReadNextLine();

                    if (line == null)
                    {
                        return true;
                    }

                    if (!ParseHeaderLine(line, parser))
                    {
                        return false;
                    }
                }

                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
Beispiel #7
0
        /// <summary>
        /// ヘッダー部分をまとめてパースします。
        /// </summary>
        /// <remarks>
        /// 開始局面の設定も行います。
        /// </remarks>
        private KifuHeader ParseHeader(KifMoveNode head)
        {
            var header = new KifuHeader();
            var parser = new BodParser();

            while (ParseHeaderLine(this.currentLine, parser, header, head))
            {
                ReadNextLine();
            }

            if (parser.IsBoardParsing)
            {
                throw new FileFormatException(
                    "局面の読み取りを完了できませんでした。");
            }

            this.startBoard = MakeStartBoard(parser);
            return header;
        }
Beispiel #8
0
        /// <summary>
        /// ヘッダー行をパースします。
        /// </summary>
        private bool ParseHeaderLine(string line, BodParser parser,
                                     KifuHeader header = null, KifMoveNode head = null)
        {
            if (line == null)
            {
                // ファイルの終了を意味します。
                return false;
            }

            var commentData = KifUtil.ParseCommentLine(line);
            if (commentData != null)
            {
                // コメントはパース結果に含めます。
                if (head != null && commentData.IsMoveComment)
                {
                    head.AddComment(commentData.Comment);
                }

                return true;
            }

            // 読み飛ばすべき説明行
            if (line.Contains("手数----指手---------消費時間"))
            {
                this.isKif = true; // kif形式です。
                return true;
            }

            // 局面の読み取りを試みます。
            if (parser.TryParse(line))
            {
                return true;
            }

            var item = KifUtil.ParseHeaderItem(line);
            if (item != null)
            {
                if (item.Key == "手合割" && item.Value != "その他")
                {
                    this.startBoard = BoardTypeUtil.CreateBoardFromName(item.Value);
                }

                if (header != null)
                {
                    // 可能ならヘッダアイテムを設定します。
                    var type = KifUtil.GetHeaderType(item.Key);
                    if (type != null)
                    {
                        header[type.Value] = item.Value;
                    }
                }

                return true;
            }

            // ヘッダが正しく読めない場合、
            // 区切りなしに指し手行に入っている可能性があります。
            if (MoveLineRegex.IsMatch(line))
            {
                this.isKif = true;
            }

            return false;
        }
Beispiel #9
0
 /// <summary>
 /// 開始局面を取得します。
 /// </summary>
 /// <remarks>
 /// 局面はbod形式と"手合割"ヘッダの両方で与えられることがあり、
 /// しかも両者が矛盾していることがあります。
 /// 
 /// そのため、開始局面については優先順位を与えて、
 /// その順序に従った局面を返すことにしています。
 /// 
 /// 具体的な優先順位は
 //   1, bod形式の局面をパースしたもの
 //   2, "手合割"ヘッダで与えられる局面
 //   3, 平手局面
 // となります。
 /// </remarks>
 private Board MakeStartBoard(BodParser parser)
 {
     return (
         parser.IsCompleted ? parser.Board :
         this.startBoard != null ? this.startBoard :
         new Board());
 }
Beispiel #10
0
        /// <summary>
        /// ヘッダー行をパースします。
        /// </summary>
        private bool ParseHeaderLine(string line, BodParser parser,
                                     KifuHeader header = null, KifMoveNode head = null)
        {
            if (line == null)
            {
                // ファイルの終了を意味します。
                return(false);
            }

            var commentData = KifUtil.ParseCommentLine(line);

            if (commentData != null)
            {
                // コメントはパース結果に含めます。
                if (head != null && commentData.IsMoveComment)
                {
                    head.AddComment(commentData.Comment);
                }

                return(true);
            }

            // 読み飛ばすべき説明行
            if (line.Contains("手数----指手---------消費時間"))
            {
                this.isKif = true; // kif形式です。
                return(true);
            }

            // 局面の読み取りを試みます。
            if (parser.TryParse(line))
            {
                return(true);
            }

            var item = KifUtil.ParseHeaderItem(line);

            if (item != null)
            {
                if (item.Key == "手合割" && item.Value != "その他")
                {
                    this.startBoard = BoardTypeUtil.CreateBoardFromName(item.Value);
                }

                if (header != null)
                {
                    // 可能ならヘッダアイテムを設定します。
                    var type = KifUtil.GetHeaderType(item.Key);
                    if (type != null)
                    {
                        header[type.Value] = item.Value;
                    }
                }

                return(true);
            }

            // ヘッダが正しく読めない場合、
            // 区切りなしに指し手行に入っている可能性があります。
            if (MoveLineRegex.IsMatch(line))
            {
                this.isKif = true;
            }

            return(false);
        }
Beispiel #11
0
        /// <summary>
        /// ヘッダー行をパースします。
        /// </summary>
        private bool ParseHeaderLine(string line, BodParser parser,
                                     KifuHeader header = null)
        {
            if (line == null)
            {
                // ファイルの終了を意味します。
                return false;
            }

            if (IsCommentLine(line))
            {
                return true;
            }

            // 読み飛ばすべき説明行
            if (line.Contains("手数----指手---------消費時間"))
            {
                this.isKif = true; // kif形式です。
                return true;
            }

            // 局面の読み取りを試みます。
            if (parser.TryParse(line))
            {
                return true;
            }

            var item = KifUtil.ParseHeaderItem(line);
            if (item != null)
            {
                if (item.Key == "手合割" && item.Value != "その他")
                {
                    this.startBoard = BoardTypeUtil.CreateBoardFromName(item.Value);
                }

                if (header != null)
                {
                    // 可能ならヘッダアイテムを設定します。
                    var type = KifUtil.GetHeaderType(item.Key);
                    if (type != null)
                    {
                        header[type.Value] = item.Value;
                    }
                }

                return true;
            }

            return false;
        }