/* eslint-disable no-irregular-whitespace */ import {parse} from "./kif-parser.pegjs"; function p(x, y) { return {x, y}; } describe("kif-parser", () => { it("simple", () => { expect( parse("1 7六歩(77)\n2 3四歩(33)\n3 2二角成(88)\n 4 同 銀(31)\n5 4五角打\n") ).toEqual({ header: {}, moves: [ {}, {move: {from: p(7, 7), to: p(7, 6), piece: "FU"}}, {move: {from: p(3, 3), to: p(3, 4), piece: "FU"}}, {move: {from: p(8, 8), to: p(2, 2), piece: "KA", promote: true}}, {move: {from: p(3, 1), same: true, piece: "GI"}}, {move: {to: p(4, 5), piece: "KA"}}, ], }); }); it("comment", () => { expect( parse( "*開始時コメント\n1 7六歩(77)\n*初手コメント\n*初手コメント2\n2 3四歩(33)\n3 2二角成(88)\n" ) ).toEqual({ header: {}, moves: [ {comments: ["開始時コメント"]}, { move: {from: p(7, 7), to: p(7, 6), piece: "FU"}, comments: ["初手コメント", "初手コメント2"], }, {move: {from: p(3, 3), to: p(3, 4), piece: "FU"}}, {move: {from: p(8, 8), to: p(2, 2), piece: "KA", promote: true}}, ], }); }); it("time", () => { expect( parse( "1 7六歩(77) (0:01/00:00:01)\n2 3四歩(33) (0:02/00:00:02)\n3 2二角成(88) (0:20/00:00:21)\n 4 同 銀(31) (0:03/00:00:05)\n5 4五角打 (0:39/00:01:00)\n" ) ).toEqual({ header: {}, moves: [ {}, { move: {from: p(7, 7), to: p(7, 6), piece: "FU"}, time: {now: {m: 0, s: 1}, total: {h: 0, m: 0, s: 1}}, }, { move: {from: p(3, 3), to: p(3, 4), piece: "FU"}, time: {now: {m: 0, s: 2}, total: {h: 0, m: 0, s: 2}}, }, { move: {from: p(8, 8), to: p(2, 2), piece: "KA", promote: true}, time: {now: {m: 0, s: 20}, total: {h: 0, m: 0, s: 21}}, }, { move: {from: p(3, 1), same: true, piece: "GI"}, time: {now: {m: 0, s: 3}, total: {h: 0, m: 0, s: 5}}, }, { move: {to: p(4, 5), piece: "KA"}, time: {now: {m: 0, s: 39}, total: {h: 0, m: 1, s: 0}}, }, ], }); }); it("special", () => { expect( parse( "1 7六歩(77)\n2 3四歩(33)\n3 7八銀(79)\n 4 8八角成(22)\n5 投了\nまで4手で後手の勝ち\n" ) ).toEqual({ header: {}, moves: [ {}, {move: {from: p(7, 7), to: p(7, 6), piece: "FU"}}, {move: {from: p(3, 3), to: p(3, 4), piece: "FU"}}, {move: {from: p(7, 9), to: p(7, 8), piece: "GI"}}, {move: {from: p(2, 2), to: p(8, 8), piece: "KA", promote: true}}, {special: "TORYO"}, ], }); }); describe("header", () => { it("手合割", () => { expect( parse( "手合割:平手\n1 7六歩(77)\n2 3四歩(33)\n3 2二角成(88)\n 4 同 銀(31)\n5 4五角打\n" ) ).toEqual({ header: { 手合割: "平手", }, initial: {preset: "HIRATE"}, moves: [ {}, {move: {from: p(7, 7), to: p(7, 6), piece: "FU"}}, {move: {from: p(3, 3), to: p(3, 4), piece: "FU"}}, {move: {from: p(8, 8), to: p(2, 2), piece: "KA", promote: true}}, {move: {from: p(3, 1), same: true, piece: "GI"}}, {move: {to: p(4, 5), piece: "KA"}}, ], }); expect( parse( "手合割:六枚落ち\n1 4二玉(51)\n2 7六歩(77)\n3 2二銀(31)\n 4 6六角(88)\n5 8二銀(71)\n" ) ).toEqual({ header: { 手合割: "六枚落ち", }, initial: {preset: "6"}, moves: [ {}, {move: {from: p(5, 1), to: p(4, 2), piece: "OU"}}, {move: {from: p(7, 7), to: p(7, 6), piece: "FU"}}, {move: {from: p(3, 1), to: p(2, 2), piece: "GI"}}, {move: {from: p(8, 8), to: p(6, 6), piece: "KA"}}, {move: {from: p(7, 1), to: p(8, 2), piece: "GI"}}, ], }); }); }); describe("initial", () => { it("simple", () => { expect( parse( `手合割:その他  上手の持駒:銀四 桂四  9 8 7 6 5 4 3 2 1 +---------------------------+ | ・ ・ ・ ・ ・ ・ ・v歩v玉|一 | ・ ・ ・ ・ ・ ・ ・v歩 ・|二 | ・ ・ ・ ・ ・ ・ ・v歩 ・|三 | ・ ・ ・ ・ ・ ・ ・v歩 ・|四 | ・ ・ ・ ・ ・ ・ ・v歩 ・|五 | ・ ・ ・ ・ ・ ・ ・v歩 ・|六 | ・ ・ ・ ・ ・ ・ ・v歩 ・|七 | ・ ・ ・ ・ ・ ・ ・v歩 ・|八 | ・ ・ ・ ・ ・ ・ ・v歩 ・|九 +---------------------------+ 下手の持駒:飛二 香四  下手番 下手:shitate 上手:uwate 1 1三香打 2 1二桂打 3 同 香成(13) ` ) ).toEqual({ header: { 手合割: "その他 ", 上手: "uwate", 下手: "shitate", }, initial: { preset: "OTHER", data: { board: [ [{color: 1, kind: "OU"}, {}, {}, {}, {}, {}, {}, {}, {}], [ {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, ], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], ], color: 0, hands: [ {FU: 0, KY: 4, KE: 0, GI: 0, KI: 0, KA: 0, HI: 2}, {FU: 0, KY: 0, KE: 4, GI: 4, KI: 0, KA: 0, HI: 0}, ], }, }, moves: [ {}, {move: {to: p(1, 3), piece: "KY"}}, {move: {to: p(1, 2), piece: "KE"}}, {move: {from: p(1, 3), same: true, piece: "KY", promote: true}}, ], }); }); it("empty mochigoma case", () => { expect( parse(`後手の持駒:なし 9 8 7 6 5 4 3 2 1 +---------------------------+ | ・ ・ ・ ・ ・ ・ ・v玉v歩|一 | ・ ・ ・ ・ ・ ・ ・ ・ ・|二 | ・ ・ ・ ・ ・ ・ ・ 歩 ・|三 | ・ ・ ・ ・ ・ ・ ・ ・ 歩|四 | ・ ・ ・ ・ ・ ・ ・ ・ 桂|五 | ・ ・ ・ ・ ・ ・ ・ ・ ・|六 | ・ ・ ・ ・ ・ ・ ・ ・ ・|七 | ・ ・ ・ ・ ・ ・ ・ ・ ・|八 | ・ ・ ・ ・ ・ ・ ・ ・ ・|九 +---------------------------+ 先手の持駒:なし `) ).toMatchInlineSnapshot( `{"header":{},"moves":[{}],"initial":{"preset":"OTHER","data":{"board":[[{"color":1,"kind":"FU"},{},{},{"color":0,"kind":"FU"},{"color":0,"kind":"KE"},{},{},{},{}],[{"color":1,"kind":"OU"},{},{"color":0,"kind":"FU"},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{}],[{},{},{},{},{},{},{},{},{}]],"color":0,"hands":[{"FU":0,"KY":0,"KE":0,"GI":0,"KI":0,"KA":0,"HI":0},{"FU":0,"KY":0,"KE":0,"GI":0,"KI":0,"KA":0,"HI":0}]}}}` ); }); it("Kifu for iPhone dialect", () => { // 持ち駒が半角スペース区切り // 手合割が平手 expect( parse( `手合割:平手 上手の持駒:銀四 桂四 9 8 7 6 5 4 3 2 1 +---------------------------+ | ・ ・ ・ ・ ・ ・ ・v歩v玉|一 | ・ ・ ・ ・ ・ ・ ・v歩 ・|二 | ・ ・ ・ ・ ・ ・ ・v歩 ・|三 | ・ ・ ・ ・ ・ ・ ・v歩 ・|四 | ・ ・ ・ ・ ・ ・ ・v歩 ・|五 | ・ ・ ・ ・ ・ ・ ・v歩 ・|六 | ・ ・ ・ ・ ・ ・ ・v歩 ・|七 | ・ ・ ・ ・ ・ ・ ・v歩 ・|八 | ・ ・ ・ ・ ・ ・ ・v歩 ・|九 +---------------------------+ 下手の持駒:飛二 香四 下手番 下手:shitate 上手:uwate 1 1三香打 2 1二桂打 3 同 香成(13) ` ) ).toEqual({ header: { 手合割: "平手", 上手: "uwate", 下手: "shitate", }, initial: { preset: "OTHER", // 上書き data: { board: [ [{color: 1, kind: "OU"}, {}, {}, {}, {}, {}, {}, {}, {}], [ {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, {color: 1, kind: "FU"}, ], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], [{}, {}, {}, {}, {}, {}, {}, {}, {}], ], color: 0, hands: [ {FU: 0, KY: 4, KE: 0, GI: 0, KI: 0, KA: 0, HI: 2}, {FU: 0, KY: 0, KE: 4, GI: 4, KI: 0, KA: 0, HI: 0}, ], }, }, moves: [ {}, {move: {to: p(1, 3), piece: "KY"}}, {move: {to: p(1, 2), piece: "KE"}}, {move: {from: p(1, 3), same: true, piece: "KY", promote: true}}, ], }); }); }); describe("fork", () => { it("normal", () => { expect( parse( `手合割:平手 1 7六歩(77) 2 3四歩(33) 3 2二角成(88)+ 4 同 銀(31) 5 4五角打 6 中断 変化:3手 3 6六歩(67) 4 8四歩(83) ` ) ).toEqual({ header: { 手合割: "平手", }, initial: {preset: "HIRATE"}, moves: [ {}, {move: {from: p(7, 7), to: p(7, 6), piece: "FU"}}, {move: {from: p(3, 3), to: p(3, 4), piece: "FU"}}, { move: {from: p(8, 8), to: p(2, 2), piece: "KA", promote: true}, forks: [ [ // {}, {move: {from: p(6, 7), to: p(6, 6), piece: "FU"}}, {move: {from: p(8, 3), to: p(8, 4), piece: "FU"}}, ], ], }, {move: {from: p(3, 1), same: true, piece: "GI"}}, {move: {to: p(4, 5), piece: "KA"}}, {special: "CHUDAN"}, ], }); }); it("Multiple forks", () => { expect( parse( `1 7六歩(77)+ 2 3四歩(33)+ 変化:2手 2 8四歩(83)+ 変化:2手 2 4四歩(43) 変化:1手 1 2六歩(27)+ 変化:1手 1 8六歩(87)+ 変化:1手 1 7八金(69) ` ) ).toEqual({ header: {}, moves: [ {}, { move: {from: p(7, 7), to: p(7, 6), piece: "FU"}, forks: [ [{move: {from: p(2, 7), to: p(2, 6), piece: "FU"}}], [{move: {from: p(8, 7), to: p(8, 6), piece: "FU"}}], [{move: {from: p(6, 9), to: p(7, 8), piece: "KI"}}], ], }, { move: {from: p(3, 3), to: p(3, 4), piece: "FU"}, forks: [ [{move: {from: p(8, 3), to: p(8, 4), piece: "FU"}}], [{move: {from: p(4, 3), to: p(4, 4), piece: "FU"}}], ], }, ], }); }); }); describe("split", () => { it("normal", () => { expect( parse( `手合割:平手 手数----指手-- *開始コメント 1 7六歩(77) *初手コメント 2 3四歩(33) 3 2二角成(88)+ 4 中断 ` ) ).toEqual({ header: { 手合割: "平手", }, initial: {preset: "HIRATE"}, moves: [ {comments: ["開始コメント"]}, {move: {from: p(7, 7), to: p(7, 6), piece: "FU"}, comments: ["初手コメント"]}, {move: {from: p(3, 3), to: p(3, 4), piece: "FU"}}, {move: {from: p(8, 8), to: p(2, 2), piece: "KA", promote: true}}, {special: "CHUDAN"}, ], }); }); it("after initial comment", () => { expect( parse( `手合割:平手 *開始コメント 手数----指手-- 1 7六歩(77) *初手コメント 2 3四歩(33) 3 2二角成(88)+ 4 中断 ` ) ).toEqual({ header: { 手合割: "平手", }, initial: {preset: "HIRATE"}, moves: [ {comments: ["開始コメント"]}, {move: {from: p(7, 7), to: p(7, 6), piece: "FU"}, comments: ["初手コメント"]}, {move: {from: p(3, 3), to: p(3, 4), piece: "FU"}}, {move: {from: p(8, 8), to: p(2, 2), piece: "KA", promote: true}}, {special: "CHUDAN"}, ], }); }); }); describe("unsupported annotations", () => { it("盤面回転", () => { expect( parse( "盤面回転\n1 7六歩(77)\n2 3四歩(33)\n3 2二角成(88)\n 4 同 銀(31)\n5 4五角打\n" ) ).toEqual({ header: {}, moves: [ {}, {move: {from: p(7, 7), to: p(7, 6), piece: "FU"}}, {move: {from: p(3, 3), to: p(3, 4), piece: "FU"}}, {move: {from: p(8, 8), to: p(2, 2), piece: "KA", promote: true}}, {move: {from: p(3, 1), same: true, piece: "GI"}}, {move: {to: p(4, 5), piece: "KA"}}, ], }); }); it("&読み込み時表示", () => { expect( parse( "1 7六歩(77)\n2 3四歩(33)\n&読み込み時表示\n3 2二角成(88)\n 4 同 銀(31)\n5 4五角打\n" ) ).toEqual({ header: {}, moves: [ {}, {move: {from: p(7, 7), to: p(7, 6), piece: "FU"}}, { move: {from: p(3, 3), to: p(3, 4), piece: "FU"}, comments: ["&読み込み時表示"], }, {move: {from: p(8, 8), to: p(2, 2), piece: "KA", promote: true}}, {move: {from: p(3, 1), same: true, piece: "GI"}}, {move: {to: p(4, 5), piece: "KA"}}, ], }); }); }); it("same at first fork", () => { expect( parse(` 1 7六歩(77) ( 0:00/00:00:00) 2 3四歩(33) ( 0:00/00:00:00) 3 2六歩(27) ( 0:00/00:00:00) 4 中断 ( 0:00/00:00:00) まで3手で中断 変化:3手 3 2二角成(88) ( 0:00/00:00:00) 4 同 銀(31) ( 0:00/00:00:00)+ 5 中断 ( 0:00/00:00:00) まで4手で中断 変化:4手 4 同 飛(82) ( 0:00/00:00:00) 5 中断 ( 0:00/00:00:00) まで4手で中断 `) ).toMatchSnapshot(); }); });