/// <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); } }
/// <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()); }
/// <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); }
/// <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); }
/// <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; }
/// <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; } }
/// <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; }
/// <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; }
/// <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()); }
/// <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); }
/// <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; }