lib/jkf/parser/ki2.rb in jkf-0.4.0 vs lib/jkf/parser/ki2.rb in jkf-0.4.1

- old
+ new

@@ -1,9 +1,11 @@ # coding: utf-8 module Jkf::Parser class Ki2 < Base + include Kifuable + def parse_root s0 = @current_pos s1 = [] s2 = parse_header while s2 != :failed @@ -11,79 +13,26 @@ s2 = parse_header end if s1 != :failed s2 = parse_initialboard s2 = nil if s2 == :failed - if s2 != :failed - s3 = [] + s3 = [] + s4 = parse_header + while s4 != :failed + s3 << s4 s4 = parse_header - while s4 != :failed - s3 << s4 - s4 = parse_header + end + s4 = parse_moves + if s4 != :failed + s5 = [] + s6 = parse_fork + while s6 != :failed + s5 << s6 + s6 = parse_fork end - if s3 != :failed - s4 = parse_moves - if s4 != :failed - s5 = [] - s6 = parse_fork - while s6 != :failed - s5 << s6 - s6 = parse_fork - end - if s5 != :failed - @reported_pos = s0 - s1 = -> (headers, ini, headers2, moves, forks) { - ret = { "header" => {}, "moves" => moves } - headers.compact.each { |h| ret["header"][h["k"]] = h["v"] } - headers2.compact.each { |h| ret["header"][h["k"]] = h["v"] } - if ini - ret["initial"] = ini - elsif ret["header"]["手合割"] - preset = preset2str(ret["header"]["手合割"]) - ret["initial"] = { "preset" => preset } if preset != "OTHER" - end - if ret["initial"] && ret["initial"]["data"] - if ret["header"]["手番"] - ret["initial"]["data"]["color"] = ("下先".index(ret["header"]["手番"]) >= 0 ? 0 : 1) - ret["header"].delete("手番") - else - ret["initial"]["data"]["color"] = 0 - end - ret["initial"]["data"]["hands"] = [ - make_hand(ret["header"]["先手の持駒"] || ret["header"]["下手の持駒"]), - make_hand(ret["header"]["後手の持駒"] || ret["header"]["上手の持駒"]) - ] - %w(先手の持駒 下手の持駒 後手の持駒 上手の持駒).each do |key| - ret["header"].delete(key) - end - end - fork_stack = [{ "te" => 0, "moves" => moves }] - forks.each do |f| - now_fork = f - _fork = fork_stack.pop - _fork = fork_stack.pop while _fork["te"] > now_fork["te"] - move = _fork["moves"][now_fork["te"] - _fork["te"]] - move["forks"] ||= [] - move["forks"] << now_fork["moves"] - fork_stack << _fork - fork_stack << now_fork - end - ret - }.call(s1, s2, s3, s4, s5) - s0 = s1 - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end + @reported_pos = s0 + s0 = transform_root(s1, s2, s3, s4, s5) else @current_pos = s0 s0 = :failed end else @@ -93,196 +42,37 @@ s0 end def parse_header s0 = @current_pos - s1 = [] - s2 = match_regexp(/^[^:\r\n]/) + s2 = match_regexp(/^[^*:\r\n]/) if s2 != :failed + s1 = [] while s2 != :failed s1 << s2 s2 = match_regexp(/^[^:\r\n]/) end else s1 = :failed end if s1 != :failed - s2 = match_str(":") - if s2 != :failed - s3 = [] - s4 = parse_nonl - while s4 != :failed - s3 << s4 - s4 = parse_nonl - end - if s3 != :failed + if match_str(":") != :failed + s3 = parse_nonls + s5 = parse_nl + if s5 != :failed s4 = [] - s5 = parse_nl - if s5 != :failed - while s5 != :failed - s4 << s5 - s5 = parse_nl - end - else - s4 = :failed + while s5 != :failed + s4 << s5 + s5 = parse_nl end - if s4 != :failed - @reported_pos = s0 - s0 = s1 = { "k" => s1.join, "v" => s3.join } - else - @current_pos = s0 - s0 = :failed - end else - @current_pos = s0 - s0 = :failed + s4 = :failed end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - if s0 == :failed - s0 = @current_pos - s1 = match_regexp(/^[先後上下]/) - if s1 != :failed - s2 = match_str("手番") - if s2 != :failed - s3 = parse_nl - if s3 != :failed - @reported_pos = s0 - s0 = s1 = { "k" => "手番", "v" => s1 } - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - end - s0 - end - - def parse_initialboard - s0 = s1 = @current_pos - s2 = match_str(" ") - if s2 != :failed - s3 = [] - s4 = parse_nonl - while s4 != :failed - s3 << s4 - s4 = parse_nonl - end - if s3 != :failed - s4 = parse_nl if s4 != :failed - s1 = s2 = [s2, s3, s4] + @reported_pos = s0 + s0 = { "k" => s1.join, "v" => s3.join } else - @current_pos = s1 - s1 = :failed - end - else - @current_pos = s1 - s1 = :failed - end - else - @current_pos = s1 - s1 = :failed - end - s1 = nil if s1 == :failed - if s1 != :failed - s2 = @current_pos - s3 = match_str("+") - if s3 != :failed - s4 = [] - s5 = parse_nonl - while s5 != :failed - s4 << s5 - s5 = parse_nonl - end - if s4 != :failed - s5 = parse_nl - if s5 != :failed - s2 = s3 = [s3, s4, s5] - else - @current_pos = s2 - s2 = :failed - end - else - @current_pos = s2 - s2 = :failed - end - else - @current_pos = s2 - s2 = :failed - end - s2 = nil if s2 == :failed - if s2 != :failed - s3 = [] - s4 = parse_ikkatsuline - if s4 != :failed - while s4 != :failed - s3 << s4 - s4 = parse_ikkatsuline - end - else - s3 = :failed - end - if s3 != :failed - s4 = @current_pos - s5 = match_str("+") - if s5 != :failed - s6 = [] - s7 = parse_nonl - while s7 != :failed - s6 << s7 - s7 = parse_nonl - end - if s6 != :failed - s7 = parse_nl - if s7 != :failed - s4 = s5 = [s5, s6, s7] - else - @current_pos = s4 - s4 = :failed - end - else - @current_pos = s4 - s4 = :failed - end - else - @current_pos = s4 - s4 = :failed - end - s4 = nil if s4 == :failed - if s4 != :failed - @reported_pos = s0 - s1 = -> (lines) { - board = [] - 9.times { |i| - line = [] - 9.times { |j| - line << lines[j][8-i] - } - board << line - } - { "preset" => "OTHER", "data" => { "board" => board } } - }.call(s3) - s0 = s1 - else - @current_pos = s0 - s0 = :failed - end - else @current_pos = s0 s0 = :failed end else @current_pos = s0 @@ -290,152 +80,56 @@ end else @current_pos = s0 s0 = :failed end - - return s0 + s0 = parse_header_teban if s0 == :failed + s0 end - def parse_ikkatsuline + def parse_header_teban s0 = @current_pos - s1 = match_str("|") + s1 = match_regexp(/^[先後上下]/) if s1 != :failed - s2 = [] - s3 = parse_masu - if s3 != :failed - while s3 != :failed - s2 << s3 - s3 = parse_masu - end - else - s2 = :failed - end + s2 = match_str("手番") if s2 != :failed - s3 = match_str("|") + s3 = parse_nl if s3 != :failed - s4 = [] - s5 = parse_nonl - if s5 != :failed - while s5 != :failed - s4 << s5 - s5 = parse_nonl - end - else - s4 = :failed - end - if s4 != :failed - s5 = parse_nl - if s5 != :failed - @reported_pos = s0 - s0 = s1 = s2 - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end + @reported_pos = s0 + { "k" => "手番", "v" => s1 } else @current_pos = s0 - s0 = :failed + :failed end else @current_pos = s0 - s0 = :failed + :failed end else @current_pos = s0 - s0 = :failed + :failed end - - return s0 end - def parse_masu - s0 = @current_pos - s1 = parse_teban - if s1 != :failed - s2 = parse_piece - if s2 != :failed - @reported_pos = s0 - s1 = { "color" => s1, "kind" => s2 } - s0 = s1 - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - if s0 == :failed - s0 = @current_pos - s1 = match_str(" ・") - if s1 != :failed - @reported_pos = s0 - s1 = {} - end - s0 = s1 - end - - s0 - end - - def parse_teban - s0 = @current_pos - s1 = match_str(" ") - s1 = match_str("+") if s1 == :failed - s1 = match_str("^") if s1 == :failed - if s1 != :failed - @reported_pos = s0 - s1 = 0 - end - s0 = s1 - if s0 == :failed - s0 = @current_pos - s1 = match_str("v") - s1 = match_str("V") if s1 == :failed - if s1 != :failed - @reported_pos = s0 - s1 = 1 - end - s0 = s1 - end - s0 - end - def parse_moves s0 = @current_pos s1 = parse_firstboard if s1 != :failed s2 = [] s3 = parse_move while s3 != :failed s2 << s3 s3 = parse_move end - if s2 != :failed - s3 = parse_result - s3 = nil if s3 == :failed - if s3 != :failed - @reported_pos = s0 - s1 = -> (hd, tl, res) { - tl.unshift(hd) - tl << { "special" => res } if res && !tl[tl.length-1]["special"] - tl - }.call(s1, s2, s3) - s0 = s1 - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end + s3 = parse_result + s3 = nil if s3 == :failed + @reported_pos = s0 + s0 = -> (hd, tl, res) do + tl.unshift(hd) + tl << { "special" => res } if res && !tl[tl.length - 1]["special"] + tl + end.call(s1, s2, s3) else @current_pos = s0 s0 = :failed end s0 @@ -447,26 +141,13 @@ s2 = parse_comment while s2 != :failed s1 << s2 s2 = parse_comment end - if s1 != :failed - s2 = parse_pointer - if s2 == :failed - s2 = nil - end - if s2 != :failed - @reported_pos = s0 - s0 = s1 = (s1.length == 0 ? {} : {"comments" =>s1}) - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end + parse_pointer + @reported_pos = s0 + s0 = s1.empty? ? {} : { "comments" => s1 } s0 end def parse_move s0 = @current_pos @@ -476,107 +157,54 @@ s3 = parse_comment while s3 != :failed s2 << s3 s3 = parse_comment end - if s2 != :failed - s3 = parse_pointer - if s3 == :failed - s3 = nil - end - if s3 != :failed - s4 = [] - s5 = parse_nl - s5 = match_str(" ") if s5 == :failed - while s5 != :failed - s4 << s5 - s5 = parse_nl - s5 = match_str(" ") if s5 == :failed - end - if s4 != :failed - @reported_pos = s0 - s1 = -> (line, c) { - ret = { "move" => line } - ret["comments"] = c if c.length > 0 - ret - }.call(s1, s2) - s0 = s1 - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed + parse_pointer + s4 = [] + s5 = parse_nl + s5 = match_space if s5 == :failed + while s5 != :failed + s4 << s5 + s5 = parse_nl + s5 = match_space if s5 == :failed end + @reported_pos = s0 + s0 = -> (line, c) do + ret = { "move" => line } + ret["comments"] = c if !c.empty? + ret + end.call(s1, s2) else @current_pos = s0 s0 = :failed end s0 end - def parse_pointer - s0 = @current_pos - s1 = match_str("&") - if s1 != :failed - s2 = [] - s3 = parse_nonl - while s3 != :failed - s2 << s3 - s3 = parse_nonl - end - if s2 != :failed - s3 = parse_nl - if s3 != :failed - s0 = s1 = [s1, s2, s3] - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - s0 - end - def parse_line s0 = @current_pos s1 = match_regexp(/^[▲△]/) if s1 != :failed - s1 = if s1 == '▲' - { 'color' => 0 } + s1 = if s1 == "▲" + { "color" => 0 } else - { 'color' => 1 } + { "color" => 1 } end s2 = parse_fugou if s2 != :failed s3 = [] s4 = parse_nl - s4 = match_str(" ") if s4 == :failed + s4 = match_space if s4 == :failed while s4 != :failed s3 << s4 s4 = parse_nl - s4 = match_str(" ") if s4 == :failed + s4 = match_space if s4 == :failed end - if s3 != :failed - @reported_pos = s0 - s0 = s1 = s2.merge(s1) - else - @current_pos = s0 - s0 = :failed - end + @reported_pos = s0 + s0 = s2.merge(s1) else @current_pos = s0 s0 = :failed end else @@ -592,173 +220,75 @@ if s1 != :failed s2 = parse_piece if s2 != :failed s3 = parse_soutai s3 = nil if s3 == :failed - if s3 != :failed - s4 = parse_dousa - s4 = nil if s4 == :failed - if s4 != :failed - s5 = match_str("成") - s5 = match_str("不成") if s5 == :failed - s5 = nil if s5 == :failed - if s5 != :failed - s6 = match_str("打") - s6 = nil if s6 == :failed - if s6 != :failed - @reported_pos = s0 - s1 = -> (pl, pi, sou, dou, pro, da) { - ret = { "piece" => pi } - if pl["same"] - ret["same"] = true - else - ret["to"] = pl - end - ret["promote"] = (pro == "成") if pro - if da - ret["relative"] = "H" - else - rel = soutai2relative(sou) + dousa2relative(dou) - ret["relative"] = rel unless rel.empty? !="" - end - ret - }.call(s1, s2, s3, s4, s5, s6) - s0 = s1 - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end + s4 = parse_dousa + s4 = nil if s4 == :failed + s5 = match_str("成") + s5 = match_str("不成") if s5 == :failed + s5 = nil if s5 == :failed + s6 = match_str("打") + s6 = nil if s6 == :failed + @reported_pos = s0 + transform_fugou(s1, s2, s3, s4, s5, s6) else @current_pos = s0 - s0 = :failed + :failed end else @current_pos = s0 - s0 = :failed + :failed end - s0 end def parse_place s0 = @current_pos s1 = parse_num if s1 != :failed s2 = parse_numkan if s2 != :failed @reported_pos = s0 - s0 = s1 = { "x" => s1, "y" => s2 } + s0 = { "x" => s1, "y" => s2 } else @current_pos = s0 s0 = :failed end else @current_pos = s0 s0 = :failed end if s0 == :failed s0 = @current_pos - s1 = match_regexp("同") - if s1 != :failed - s2 = match_str(" ") - s2 = nil if s2 == :failed - if s2 != :failed - @reported_pos = s0 - s0 = s1 = { "same" => true } - else - @current_pos = s0 - s0 = :failed - end + if match_regexp("同") != :failed + match_str(" ") + @reported_pos = s0 + s0 = { "same" => true } else @current_pos = s0 s0 = :failed end end s0 end - def parse_piece - s0 = @current_pos - s1 = match_regexp("成") - s1 = "" if s1 == :failed - if s1 != :failed - s2 = match_regexp(/^[歩香桂銀金角飛王玉と杏圭全馬竜龍]/) - if s2 != :failed - @reported_pos = s0 - s0 = s1 = kind2csa(s1 + s2) - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - return s0 - end - def parse_soutai match_regexp(/^[左直右]/) end def parse_dousa match_regexp(/^[上寄引]/) end - def parse_num - s0 = @current_pos - s1 = match_regexp(/^[123456789]/) - if s1 != :failed - @reported_pos = s0 - s1 = zen2n(s1) - end - s0 = s1 - s0 - end - - def parse_numkan - s0 = @current_pos - s1 = match_regexp(/^[一二三四五六七八九]/) - if s1 != :failed - @reported_pos = s0 - s1 = kan2n(s1) - end - s0 = s1 - s0 - end - def parse_comment s0 = @current_pos - s1 = match_str("*") - if s1 != :failed - s2 = [] - s3 = parse_nonl - while s3 != :failed - s2 << s3 - s3 = parse_nonl - end - if s2 != :failed - s3 = parse_nl - if s3 != :failed - @reported_pos = s0 - s0 = s1 = s2.join - else - @current_pos = s0 - s0 = :failed - end + if match_str("*") != :failed + s2 = parse_nonls + if parse_nl != :failed + @reported_pos = s0 + s0 = s2.join else @current_pos = s0 s0 = :failed end else @@ -766,184 +296,22 @@ s0 = :failed end s0 end - def parse_result + def parse_fork s0 = @current_pos - s1 = match_str("まで") - if s1 != :failed - s2 = [] - s3 = match_regexp(/^[0-9]/) + if match_str("変化:") != :failed + match_spaces + s3 = match_digits! if s3 != :failed - while s3 != :failed - s2 << s3 - s3 = match_regexp(/^[0-9]/) - end - else - s2 = :failed - end - if s2 != :failed - s3 = match_str("手") - if s3 != :failed - s4 = @current_pos - s5 = match_str("で") - if s5 != :failed - s6 = parse_turn + if match_str("手") != :failed + if parse_nl != :failed + s6 = parse_moves if s6 != :failed - s7 = match_str("手の") - if s7 != :failed - s8 = @current_pos - s9 = match_str("勝ち") - if s9 != :failed - @reported_pos = s8 - s9 = "TORYO" - end - s8 = s9 - if s8 == :failed - s8 = @current_pos - s9 = match_str("反則") - if s9 != :failed - s10 = @current_pos - s11 = match_str("勝ち") - if s11 != :failed - @reported_pos = s10 - s11 = "ILLEGAL_ACTION" - end - s10 = s11 - if s10 == :failed - s10 = @current_pos - s11 = match_str("負け") - if s11 != :failed - @reported_pos = s10 - s11 ="ILLEGAL_MOVE" - end - s10 = s11 - end - if s10 != :failed - @reported_pos = s8 - s8 = s9 = s10 - else - @current_pos = s8 - s8 = :failed - end - else - @current_pos = s8 - s8 = :failed - end - end - if s8 != :failed - @reported_pos = s4 - s4 = s5 = s8 - else - @current_pos = s4 - s4 = :failed - end - else - @current_pos = s4 - s4 = :failed - end - else - @current_pos = s4 - s4 = :failed - end - else - @current_pos = s4 - s4 = :failed - end - if s4 == :failed - s4 = @current_pos - s5 = match_str("で時間切れにより") - if s5 != :failed - s6 = parse_turn - if s6 != :failed - s7 = match_str("手の勝ち") - if s7 != :failed - @reported_pos = s4 - s5 = "TIME_UP" - s4 = s5 - else - @current_pos = s4 - s4 = :failed - end - else - @current_pos = s4 - s4 = :failed - end - else - @current_pos = s4 - s4 = :failed - end - if s4 == :failed - s4 = @current_pos - s5 = match_str("で中断") - if s5 != :failed - @reported_pos = s4 - s5 = "CHUDAN" - end - s4 = s5 - if s4 == :failed - s4 = @current_pos - s5 = match_str("で持将棋") - if s5 != :failed - @reported_pos = s4 - s5 = "JISHOGI" - end - s4 = s5 - if s4 == :failed - s4 = @current_pos - s5 = match_str("で千日手") - if s5 != :failed - @reported_pos = s4 - s5 = "SENNICHITE" - end - s4 = s5 - if s4 == :failed - s4 = @current_pos - s5 = match_str("で") - s5 = nil if s5 == :failed - if s5 != :failed - s6 = match_str("詰") - if s6 != :failed - s7 = match_str("み") - if s7 == :failed - s7 = nil - end - if s7 != :failed - @reported_pos = s4 - s4 = s5 = "TSUMI" - else - @current_pos = s4 - s4 = :failed - end - else - @current_pos = s4 - s4 = :failed - end - else - @current_pos = s4 - s4 = :failed - end - if s4 == :failed - s4 = @current_pos - s5 = match_str("で不詰") - if s5 != :failed - @reported_pos = s4 - s5 = "FUZUMI" - end - s4 = s5 - end - end - end - end - end - end - if s4 != :failed - s5 = parse_nl - if s5 != :failed || @input[@current_pos].nil? @reported_pos = s0 - s0 = s1 = s4 + s0 = { "te" => s3.join.to_i, "moves" => s6[1..-1] } else @current_pos = s0 s0 = :failed end else @@ -963,278 +331,76 @@ s0 = :failed end s0 end - def parse_fork - s0 = @current_pos - s1 = match_str( "変化:") - if s1 != :failed - s2 = [] - s3 = match_str(" ") - while s3 != :failed - s2 << s3 - s3 = match_str(" ") - end - if s2 != :failed - s3 = [] - s4 = match_regexp(/^[0-9]/) - if s4 != :failed - while s4 != :failed - s3 << s4 - s4 = match_regexp(/^[0-9]/) - end - else - s3 = :failed - end - if s3 != :failed - s4 = match_str("手") - if s4 != :failed - s5 = parse_nl - if s5 != :failed - s6 = parse_moves - if s6 != :failed - @reported_pos = s0 - s0 = s1 = { "te" => s3.join.to_i, "moves" => s6[1..-1] } - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - s0 - end - def parse_turn match_regexp(/^[先後上下]/) end - def parse_nl - s0 = @current_pos - s1 = [] - s2 = parse_newline - if s2 != :failed - while s2 != :failed - s1 << s2 - s2 = parse_newline - end - else - s1 = :failed - end - if s1 != :failed - s2 = [] - s3 = parse_skipline - while s3 != :failed - s2 << s3 - s3 = parse_skipline - end - if s2 != :failed - s0 = s1 = [s1, s2] - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - s0 - end + protected - def parse_skipline - s0 = @current_pos - s1 = match_str("#") - if s1 != :failed - s2 = [] - s3 = parse_nonl - while s3 != :failed - s2 << s3 - s3 = parse_nonl - end - if s2 != :failed - s3 = parse_newline - if s3 != :failed - s0 = s1 = [s1, s2, s3] - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed - end - else - @current_pos = s0 - s0 = :failed + def transform_root(headers, ini, headers2, moves, forks) + ret = { "header" => {}, "moves" => moves } + headers.compact.each { |h| ret["header"][h["k"]] = h["v"] } + headers2.compact.each { |h| ret["header"][h["k"]] = h["v"] } + if ini + ret["initial"] = ini + elsif ret["header"]["手合割"] + preset = preset2str(ret["header"]["手合割"]) + ret["initial"] = { "preset" => preset } if preset != "OTHER" end - s0 + transform_root_header_data(ret) if ret["initial"] && ret["initial"]["data"] + transform_root_forks(forks, moves) + ret end - def parse_whitespace - s0 = match_str(" ") - s0 = match_str("\t") if s0 == :failed - s0 - end - - def parse_newline - s0 = @current_pos - s1 = [] - s2 = parse_whitespace - while s2 != :failed - s1 << s2 - s2 = parse_whitespace - end - if s1 != :failed - s2 = match_str("\n") - if s2 == :failed - s2 = @current_pos - s3 = match_str("\r") - if s3 != :failed - s4 = match_str("\n") - s4 = nil if s4 == :failed - if s4 != :failed - s2 = s3 = [s3, s4] - else - @current_pos = s2 - s2 = :failed - end - else - @current_pos = s2 - s2 = :failed - end - end - if s2 != :failed - s0 = s1 = [s1, s2] - else - @current_pos = s0 - s0 = :failed - end + def transform_fugou(pl, pi, sou, dou, pro, da) + ret = { "piece" => pi } + if pl["same"] + ret["same"] = true else - @current_pos = s0 - s0 = :failed + ret["to"] = pl end - s0 - end - - def parse_nonl - match_regexp(/^[^\r\n]/) - end - - protected - - def zen2n(s) - "0123456789".index(s) - end - - def kan2n(s) - "〇一二三四五六七八九".index(s) - end - - def kan2n2(s) - case s.length - when 1 - "〇一二三四五六七八九十".index(s) - when 2 - "〇一二三四五六七八九十".index(s[1])+10 + ret["promote"] = (pro == "成") if pro + if da + ret["relative"] = "H" else - raise "21以上の数値に対応していません" + rel = soutai2relative(sou) + dousa2relative(dou) + ret["relative"] = rel unless rel.empty? end + ret end - def kind2csa(kind) - if kind[0] == "成" - { - "香" => "NY", - "桂" => "NK", - "銀" => "NG" - }[kind[1]] - else - { - "歩" => "FU", - "香" => "KY", - "桂" => "KE", - "銀" => "GI", - "金" => "KI", - "角" => "KA", - "飛" => "HI", - "玉" => "OU", - "王" => "OU", - "と" => "TO", - "杏" => "NY", - "圭" => "NK", - "全" => "NG", - "馬" => "UM", - "竜" => "RY", - "龍" => "RY" - }[kind] - end - end - def soutai2relative(str) { "左" => "L", "直" => "C", - "右" => "R", + "右" => "R" }[str] || "" end def dousa2relative(str) { "上" => "U", "寄" => "M", - "引" => "D", + "引" => "D" }[str] || "" end - def preset2str(preset) - { - "平手" => "HIRATE", - "香落ち" => "KY", - "右香落ち" => "KY_R", - "角落ち" => "KA", - "飛車落ち" => "HI", - "飛香落ち" => "HIKY", - "二枚落ち" => "2", - "三枚落ち" => "3", - "四枚落ち" => "4", - "五枚落ち" => "5", - "左五枚落ち" => "5_L", - "六枚落ち" => "6", - "八枚落ち" => "8", - "十枚落ち" => "10", - "その他" => "OTHER", - }[preset.gsub(/\s/, "")] - end - def make_hand(str) - kinds = str.gsub(/ $/, "").split(" ") - ret = { "FU" => 0, "KY" => 0, "KE" => 0, "GI" => 0, "KI" => 0, "KA" => 0, "HI" => 0 } return ret if str.empty? - kinds.each do |kind| + str.gsub(/ $/, "").split(" ").each do |kind| next if kind.empty? ret[kind2csa(kind[0])] = kind.length == 1 ? 1 : kan2n2(kind[1..-1]) end ret + end + + def eos? + @input[@current_pos].nil? end end end