jkf 0.4.3 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +16 -0
- data/.rubocop.yml +46 -990
- data/.rubocop_todo.yml +1 -5
- data/CHANGELOG.md +63 -0
- data/Gemfile +11 -9
- data/Guardfile +3 -3
- data/README.en.md +28 -15
- data/README.md +9 -5
- data/Rakefile +7 -2
- data/bench.rb +12 -0
- data/bin/console +4 -4
- data/jkf.gemspec +14 -12
- data/lib/jkf/converter/base.rb +12 -10
- data/lib/jkf/converter/csa.rb +141 -150
- data/lib/jkf/converter/ki2.rb +93 -91
- data/lib/jkf/converter/kif.rb +105 -99
- data/lib/jkf/converter/kifuable.rb +160 -160
- data/lib/jkf/converter.rb +6 -8
- data/lib/jkf/parser/base.rb +81 -95
- data/lib/jkf/parser/csa.rb +652 -667
- data/lib/jkf/parser/ki2.rb +332 -338
- data/lib/jkf/parser/kif.rb +468 -485
- data/lib/jkf/parser/kifuable.rb +500 -518
- data/lib/jkf/parser.rb +5 -7
- data/lib/jkf/version.rb +1 -2
- data/lib/jkf.rb +6 -6
- data/manifest.scm +143 -0
- data/po/all.pot +176 -0
- data/po/en.po +199 -0
- data/po4a.cfg +11 -0
- metadata +13 -7
- data/.codeclimate.yml +0 -28
- data/.travis.yml +0 -9
data/lib/jkf/parser/ki2.rb
CHANGED
@@ -1,426 +1,420 @@
|
|
1
|
-
|
1
|
+
module Jkf
|
2
|
+
module Parser
|
3
|
+
# KI2 Parser
|
4
|
+
class Ki2 < Base
|
5
|
+
include Kifuable
|
2
6
|
|
3
|
-
|
4
|
-
# KI2 Parser
|
5
|
-
class Ki2 < Base
|
6
|
-
include Kifuable
|
7
|
+
protected
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
s0 = @current_pos
|
13
|
-
s1 = []
|
14
|
-
s2 = parse_header
|
15
|
-
while s2 != :failed
|
16
|
-
s1 << s2
|
9
|
+
# kifu : header* initialboard? header* moves fork*
|
10
|
+
def parse_root
|
11
|
+
s0 = @scanner.pos
|
12
|
+
s1 = []
|
17
13
|
s2 = parse_header
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
s2 = nil if s2 == :failed
|
22
|
-
s3 = []
|
23
|
-
s4 = parse_header
|
24
|
-
while s4 != :failed
|
25
|
-
s3 << s4
|
26
|
-
s4 = parse_header
|
14
|
+
while s2 != :failed
|
15
|
+
s1 << s2
|
16
|
+
s2 = parse_header
|
27
17
|
end
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
18
|
+
if s1 == :failed
|
19
|
+
@scanner.pos = s0
|
20
|
+
s0 = :failed
|
21
|
+
else
|
22
|
+
s2 = parse_initialboard
|
23
|
+
s2 = nil if s2 == :failed
|
24
|
+
s3 = []
|
25
|
+
s4 = parse_header
|
26
|
+
while s4 != :failed
|
27
|
+
s3 << s4
|
28
|
+
s4 = parse_header
|
29
|
+
end
|
30
|
+
s4 = parse_moves
|
31
|
+
if s4 == :failed
|
32
|
+
@scanner.pos = s0
|
33
|
+
s0 = :failed
|
34
|
+
else
|
35
|
+
s5 = []
|
34
36
|
s6 = parse_fork
|
37
|
+
while s6 != :failed
|
38
|
+
s5 << s6
|
39
|
+
s6 = parse_fork
|
40
|
+
end
|
41
|
+
@reported_pos = s0
|
42
|
+
s0 = transform_root(s1, s2, s3, s4, s5)
|
35
43
|
end
|
36
|
-
@reported_pos = s0
|
37
|
-
s0 = transform_root(s1, s2, s3, s4, s5)
|
38
|
-
else
|
39
|
-
@current_pos = s0
|
40
|
-
s0 = :failed
|
41
44
|
end
|
42
|
-
|
43
|
-
@current_pos = s0
|
44
|
-
s0 = :failed
|
45
|
+
s0
|
45
46
|
end
|
46
|
-
s0
|
47
|
-
end
|
48
47
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
s1
|
57
|
-
s2
|
48
|
+
# header : [^:\r\n]+ ":" nonls nl+ | header_teban
|
49
|
+
def parse_header
|
50
|
+
s0 = @scanner.pos
|
51
|
+
s2 = match_regexp(/[^*:\r\n]/)
|
52
|
+
if s2 == :failed
|
53
|
+
s1 = :failed
|
54
|
+
else
|
55
|
+
s1 = []
|
56
|
+
while s2 != :failed
|
57
|
+
s1 << s2
|
58
|
+
s2 = match_regexp(/[^:\r\n]/)
|
59
|
+
end
|
58
60
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
if match_str(":") != :failed
|
61
|
+
if s1 == :failed
|
62
|
+
@scanner.pos = s0
|
63
|
+
s0 = :failed
|
64
|
+
elsif match_str(':') != :failed
|
64
65
|
s3 = parse_nonls
|
65
66
|
s5 = parse_nl
|
66
|
-
if s5
|
67
|
+
if s5 == :failed
|
68
|
+
s4 = :failed
|
69
|
+
else
|
67
70
|
s4 = []
|
68
71
|
while s5 != :failed
|
69
72
|
s4 << s5
|
70
73
|
s5 = parse_nl
|
71
74
|
end
|
72
|
-
else
|
73
|
-
s4 = :failed
|
74
75
|
end
|
75
|
-
if s4
|
76
|
-
@
|
77
|
-
s0 = { "k" => s1.join, "v" => s3.join }
|
78
|
-
else
|
79
|
-
@current_pos = s0
|
76
|
+
if s4 == :failed
|
77
|
+
@scanner.pos = s0
|
80
78
|
s0 = :failed
|
79
|
+
else
|
80
|
+
@reported_pos = s0
|
81
|
+
s0 = { 'k' => s1.join, 'v' => s3.join }
|
81
82
|
end
|
82
83
|
else
|
83
|
-
@
|
84
|
+
@scanner.pos = s0
|
84
85
|
s0 = :failed
|
85
86
|
end
|
86
|
-
|
87
|
-
|
88
|
-
s0 = :failed
|
87
|
+
s0 = parse_header_teban if s0 == :failed
|
88
|
+
s0
|
89
89
|
end
|
90
|
-
s0 = parse_header_teban if s0 == :failed
|
91
|
-
s0
|
92
|
-
end
|
93
90
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
else
|
106
|
-
@current_pos = s0
|
91
|
+
# header_teban : [先後上下] "手番" nl
|
92
|
+
def parse_header_teban
|
93
|
+
s0 = @scanner.pos
|
94
|
+
s1 = parse_turn
|
95
|
+
if s1 == :failed
|
96
|
+
@scanner.pos = s0
|
97
|
+
:failed
|
98
|
+
else
|
99
|
+
s2 = match_str('手番')
|
100
|
+
if s2 == :failed
|
101
|
+
@scanner.pos = s0
|
107
102
|
:failed
|
103
|
+
else
|
104
|
+
s3 = parse_nl
|
105
|
+
if s3 == :failed
|
106
|
+
@scanner.pos = s0
|
107
|
+
:failed
|
108
|
+
else
|
109
|
+
@reported_pos = s0
|
110
|
+
{ 'k' => '手番', 'v' => s1 }
|
111
|
+
end
|
108
112
|
end
|
109
|
-
else
|
110
|
-
@current_pos = s0
|
111
|
-
:failed
|
112
113
|
end
|
113
|
-
else
|
114
|
-
@current_pos = s0
|
115
|
-
:failed
|
116
114
|
end
|
117
|
-
end
|
118
115
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
s2
|
116
|
+
# moves : firstboard : move* result?
|
117
|
+
def parse_moves
|
118
|
+
s0 = @scanner.pos
|
119
|
+
s1 = parse_firstboard
|
120
|
+
if s1 == :failed
|
121
|
+
@scanner.pos = s0
|
122
|
+
s0 = :failed
|
123
|
+
else
|
124
|
+
s2 = []
|
128
125
|
s3 = parse_move
|
126
|
+
while s3 != :failed
|
127
|
+
s2 << s3
|
128
|
+
s3 = parse_move
|
129
|
+
end
|
130
|
+
s3 = parse_result
|
131
|
+
s3 = nil if s3 == :failed
|
132
|
+
@reported_pos = s0
|
133
|
+
s0 = -> (hd, tl, res) do
|
134
|
+
tl.unshift(hd)
|
135
|
+
tl << { 'special' => res } if res && !tl[tl.length - 1]['special']
|
136
|
+
tl
|
137
|
+
end.call(s1, s2, s3)
|
129
138
|
end
|
130
|
-
|
131
|
-
s3 = nil if s3 == :failed
|
132
|
-
@reported_pos = s0
|
133
|
-
s0 = -> (hd, tl, res) do
|
134
|
-
tl.unshift(hd)
|
135
|
-
tl << { "special" => res } if res && !tl[tl.length - 1]["special"]
|
136
|
-
tl
|
137
|
-
end.call(s1, s2, s3)
|
138
|
-
else
|
139
|
-
@current_pos = s0
|
140
|
-
s0 = :failed
|
139
|
+
s0
|
141
140
|
end
|
142
|
-
s0
|
143
|
-
end
|
144
141
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
s2 = parse_comment
|
150
|
-
while s2 != :failed
|
151
|
-
s1 << s2
|
142
|
+
# firstboard : comment* pointer?
|
143
|
+
def parse_firstboard
|
144
|
+
s0 = @scanner.pos
|
145
|
+
s1 = []
|
152
146
|
s2 = parse_comment
|
147
|
+
while s2 != :failed
|
148
|
+
s1 << s2
|
149
|
+
s2 = parse_comment
|
150
|
+
end
|
151
|
+
parse_pointer
|
152
|
+
@reported_pos = s0
|
153
|
+
s1.empty? ? {} : { 'comments' => s1 }
|
153
154
|
end
|
154
|
-
parse_pointer
|
155
|
-
@reported_pos = s0
|
156
|
-
s0 = s1.empty? ? {} : { "comments" => s1 }
|
157
|
-
s0
|
158
|
-
end
|
159
155
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
s2
|
156
|
+
# move : line comment* pointer? (nl | " ")*
|
157
|
+
def parse_move
|
158
|
+
s0 = @scanner.pos
|
159
|
+
s1 = parse_line
|
160
|
+
if s1 == :failed
|
161
|
+
@scanner.pos = s0
|
162
|
+
s0 = :failed
|
163
|
+
else
|
164
|
+
s2 = []
|
169
165
|
s3 = parse_comment
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
s4 << s5
|
166
|
+
while s3 != :failed
|
167
|
+
s2 << s3
|
168
|
+
s3 = parse_comment
|
169
|
+
end
|
170
|
+
parse_pointer
|
171
|
+
s4 = []
|
177
172
|
s5 = parse_nl
|
178
173
|
s5 = match_space if s5 == :failed
|
174
|
+
while s5 != :failed
|
175
|
+
s4 << s5
|
176
|
+
s5 = parse_nl
|
177
|
+
s5 = match_space if s5 == :failed
|
178
|
+
end
|
179
|
+
@reported_pos = s0
|
180
|
+
s0 = -> (line, c) do
|
181
|
+
ret = { 'move' => line }
|
182
|
+
ret['comments'] = c unless c.empty?
|
183
|
+
ret
|
184
|
+
end.call(s1, s2)
|
179
185
|
end
|
180
|
-
@reported_pos = s0
|
181
|
-
s0 = -> (line, c) do
|
182
|
-
ret = { "move" => line }
|
183
|
-
ret["comments"] = c if !c.empty?
|
184
|
-
ret
|
185
|
-
end.call(s1, s2)
|
186
|
-
else
|
187
|
-
@current_pos = s0
|
188
|
-
s0 = :failed
|
189
|
-
end
|
190
186
|
|
191
|
-
|
192
|
-
|
187
|
+
s0
|
188
|
+
end
|
193
189
|
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
190
|
+
# line : [▲△] fugou (nl / " ")*
|
191
|
+
def parse_line
|
192
|
+
s0 = @scanner.pos
|
193
|
+
s1 = match_regexp(/[▲△]/)
|
194
|
+
if s1 == :failed
|
195
|
+
@scanner.pos = s0
|
196
|
+
s0 = :failed
|
197
|
+
else
|
198
|
+
s1 = if s1 == '▲'
|
199
|
+
{ 'color' => 0 }
|
200
|
+
else
|
201
|
+
{ 'color' => 1 }
|
202
|
+
end
|
203
|
+
s2 = parse_fugou
|
204
|
+
if s2 == :failed
|
205
|
+
@scanner.pos = s0
|
206
|
+
s0 = :failed
|
207
|
+
else
|
208
|
+
s3 = []
|
211
209
|
s4 = parse_nl
|
212
210
|
s4 = match_space if s4 == :failed
|
211
|
+
while s4 != :failed
|
212
|
+
s3 << s4
|
213
|
+
s4 = parse_nl
|
214
|
+
s4 = match_space if s4 == :failed
|
215
|
+
end
|
216
|
+
@reported_pos = s0
|
217
|
+
s0 = s2.merge(s1)
|
213
218
|
end
|
214
|
-
@reported_pos = s0
|
215
|
-
s0 = s2.merge(s1)
|
216
|
-
else
|
217
|
-
@current_pos = s0
|
218
|
-
s0 = :failed
|
219
219
|
end
|
220
|
-
|
221
|
-
@current_pos = s0
|
222
|
-
s0 = :failed
|
220
|
+
s0
|
223
221
|
end
|
224
|
-
s0
|
225
|
-
end
|
226
222
|
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
if s2 != :failed
|
234
|
-
s3 = parse_soutai
|
235
|
-
s3 = nil if s3 == :failed
|
236
|
-
s4 = parse_dousa
|
237
|
-
s4 = nil if s4 == :failed
|
238
|
-
s5 = match_str("成")
|
239
|
-
s5 = match_str("不成") if s5 == :failed
|
240
|
-
s5 = nil if s5 == :failed
|
241
|
-
s6 = match_str("打")
|
242
|
-
s6 = nil if s6 == :failed
|
243
|
-
@reported_pos = s0
|
244
|
-
transform_fugou(s1, s2, s3, s4, s5, s6)
|
245
|
-
else
|
246
|
-
@current_pos = s0
|
223
|
+
# fugou : place piece soutai? dousa? ("成" | "不成")? "打"?
|
224
|
+
def parse_fugou
|
225
|
+
s0 = @scanner.pos
|
226
|
+
s1 = parse_place
|
227
|
+
if s1 == :failed
|
228
|
+
@scanner.pos = s0
|
247
229
|
:failed
|
230
|
+
else
|
231
|
+
s2 = parse_piece
|
232
|
+
if s2 == :failed
|
233
|
+
@scanner.pos = s0
|
234
|
+
:failed
|
235
|
+
else
|
236
|
+
s3 = parse_soutai
|
237
|
+
s3 = nil if s3 == :failed
|
238
|
+
s4 = parse_dousa
|
239
|
+
s4 = nil if s4 == :failed
|
240
|
+
s5 = match_str('成')
|
241
|
+
s5 = match_str('不成') if s5 == :failed
|
242
|
+
s5 = nil if s5 == :failed
|
243
|
+
s6 = match_str('打')
|
244
|
+
s6 = nil if s6 == :failed
|
245
|
+
@reported_pos = s0
|
246
|
+
transform_fugou(s1, s2, s3, s4, s5, s6)
|
247
|
+
end
|
248
248
|
end
|
249
|
-
else
|
250
|
-
@current_pos = s0
|
251
|
-
:failed
|
252
249
|
end
|
253
|
-
end
|
254
250
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
if s2 != :failed
|
262
|
-
@reported_pos = s0
|
263
|
-
s0 = { "x" => s1, "y" => s2 }
|
264
|
-
else
|
265
|
-
@current_pos = s0
|
251
|
+
# place : num numkan
|
252
|
+
def parse_place
|
253
|
+
s0 = @scanner.pos
|
254
|
+
s1 = parse_num
|
255
|
+
if s1 == :failed
|
256
|
+
@scanner.pos = s0
|
266
257
|
s0 = :failed
|
267
|
-
end
|
268
|
-
else
|
269
|
-
@current_pos = s0
|
270
|
-
s0 = :failed
|
271
|
-
end
|
272
|
-
if s0 == :failed
|
273
|
-
s0 = @current_pos
|
274
|
-
if match_regexp("同") != :failed
|
275
|
-
match_str(" ")
|
276
|
-
@reported_pos = s0
|
277
|
-
s0 = { "same" => true }
|
278
258
|
else
|
279
|
-
|
280
|
-
|
259
|
+
s2 = parse_numkan
|
260
|
+
if s2 == :failed
|
261
|
+
@scanner.pos = s0
|
262
|
+
s0 = :failed
|
263
|
+
else
|
264
|
+
@reported_pos = s0
|
265
|
+
s0 = { 'x' => s1, 'y' => s2 }
|
266
|
+
end
|
281
267
|
end
|
268
|
+
if s0 == :failed
|
269
|
+
s0 = @scanner.pos
|
270
|
+
if match_regexp('同') == :failed
|
271
|
+
@scanner.pos = s0
|
272
|
+
s0 = :failed
|
273
|
+
else
|
274
|
+
match_str(' ')
|
275
|
+
@reported_pos = s0
|
276
|
+
s0 = { 'same' => true }
|
277
|
+
end
|
278
|
+
end
|
279
|
+
s0
|
282
280
|
end
|
283
|
-
s0
|
284
|
-
end
|
285
281
|
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
282
|
+
# soutai : [左直右]
|
283
|
+
def parse_soutai
|
284
|
+
match_regexp(/[左直右]/)
|
285
|
+
end
|
290
286
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
287
|
+
# dousa : [上寄引]
|
288
|
+
def parse_dousa
|
289
|
+
match_regexp(/[上寄引]/)
|
290
|
+
end
|
295
291
|
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
if parse_nl != :failed
|
302
|
-
@reported_pos = s0
|
303
|
-
s0 = s2.join
|
304
|
-
else
|
305
|
-
@current_pos = s0
|
292
|
+
# "*" nonls nl
|
293
|
+
def parse_comment
|
294
|
+
s0 = @scanner.pos
|
295
|
+
if match_str('*') == :failed
|
296
|
+
@scanner.pos = s0
|
306
297
|
s0 = :failed
|
298
|
+
else
|
299
|
+
s2 = parse_nonls
|
300
|
+
if parse_nl == :failed
|
301
|
+
@scanner.pos = s0
|
302
|
+
s0 = :failed
|
303
|
+
else
|
304
|
+
@reported_pos = s0
|
305
|
+
s0 = s2.join
|
306
|
+
end
|
307
307
|
end
|
308
|
-
|
309
|
-
@current_pos = s0
|
310
|
-
s0 = :failed
|
308
|
+
s0
|
311
309
|
end
|
312
|
-
s0
|
313
|
-
end
|
314
310
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
311
|
+
# fork : "変化:" " "* [0-9]+ "手" nl moves
|
312
|
+
def parse_fork
|
313
|
+
s0 = @scanner.pos
|
314
|
+
if match_str('変化:') == :failed
|
315
|
+
@scanner.pos = s0
|
316
|
+
s0 = :failed
|
317
|
+
else
|
318
|
+
match_spaces
|
319
|
+
s3 = match_digits!
|
320
|
+
if s3 == :failed
|
321
|
+
@scanner.pos = s0
|
322
|
+
s0 = :failed
|
323
|
+
elsif match_str('手') != :failed
|
324
|
+
if parse_nl == :failed
|
325
|
+
@scanner.pos = s0
|
326
|
+
s0 = :failed
|
327
|
+
else
|
324
328
|
s6 = parse_moves
|
325
|
-
if s6
|
326
|
-
@
|
327
|
-
s0 = { "te" => s3.join.to_i, "moves" => s6[1..-1] }
|
328
|
-
else
|
329
|
-
@current_pos = s0
|
329
|
+
if s6 == :failed
|
330
|
+
@scanner.pos = s0
|
330
331
|
s0 = :failed
|
332
|
+
else
|
333
|
+
@reported_pos = s0
|
334
|
+
s0 = { 'te' => s3.join.to_i, 'moves' => s6[1..-1] }
|
331
335
|
end
|
332
|
-
else
|
333
|
-
@current_pos = s0
|
334
|
-
s0 = :failed
|
335
336
|
end
|
336
337
|
else
|
337
|
-
@
|
338
|
+
@scanner.pos = s0
|
338
339
|
s0 = :failed
|
339
340
|
end
|
340
|
-
else
|
341
|
-
@current_pos = s0
|
342
|
-
s0 = :failed
|
343
341
|
end
|
344
|
-
|
345
|
-
@current_pos = s0
|
346
|
-
s0 = :failed
|
342
|
+
s0
|
347
343
|
end
|
348
|
-
s0
|
349
|
-
end
|
350
344
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
345
|
+
# turn : [先後上下]
|
346
|
+
def parse_turn
|
347
|
+
match_regexp(/[先後上下]/)
|
348
|
+
end
|
355
349
|
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
350
|
+
# transform to jkf
|
351
|
+
def transform_root(headers, ini, headers2, moves, forks)
|
352
|
+
ret = { 'header' => {}, 'moves' => moves }
|
353
|
+
headers.compact.each { |h| ret['header'][h['k']] = h['v'] }
|
354
|
+
headers2.compact.each { |h| ret['header'][h['k']] = h['v'] }
|
355
|
+
if ini
|
356
|
+
ret['initial'] = ini
|
357
|
+
elsif ret['header']['手合割']
|
358
|
+
preset = preset2str(ret['header']['手合割'])
|
359
|
+
ret['initial'] = { 'preset' => preset } if preset != 'OTHER'
|
360
|
+
end
|
361
|
+
transform_root_header_data(ret) if ret['initial'] && ret['initial']['data']
|
362
|
+
transform_root_forks(forks, moves)
|
363
|
+
ret
|
366
364
|
end
|
367
|
-
transform_root_header_data(ret) if ret["initial"] && ret["initial"]["data"]
|
368
|
-
transform_root_forks(forks, moves)
|
369
|
-
ret
|
370
|
-
end
|
371
365
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
366
|
+
# transfrom fugou to jkf
|
367
|
+
def transform_fugou(pl, pi, sou, dou, pro, da)
|
368
|
+
ret = { 'piece' => pi }
|
369
|
+
if pl['same']
|
370
|
+
ret['same'] = true
|
371
|
+
else
|
372
|
+
ret['to'] = pl
|
373
|
+
end
|
374
|
+
ret['promote'] = (pro == '成') if pro
|
375
|
+
if da
|
376
|
+
ret['relative'] = 'H'
|
377
|
+
else
|
378
|
+
rel = soutai2relative(sou) + dousa2relative(dou)
|
379
|
+
ret['relative'] = rel unless rel.empty?
|
380
|
+
end
|
381
|
+
ret
|
379
382
|
end
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
383
|
+
|
384
|
+
# relative string to jkf
|
385
|
+
def soutai2relative(str)
|
386
|
+
{
|
387
|
+
'左' => 'L',
|
388
|
+
'直' => 'C',
|
389
|
+
'右' => 'R'
|
390
|
+
}[str] || ''
|
386
391
|
end
|
387
|
-
ret
|
388
|
-
end
|
389
392
|
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
393
|
+
# movement string to jkf
|
394
|
+
def dousa2relative(str)
|
395
|
+
{
|
396
|
+
'上' => 'U',
|
397
|
+
'寄' => 'M',
|
398
|
+
'引' => 'D'
|
399
|
+
}[str] || ''
|
400
|
+
end
|
398
401
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
"寄" => "M",
|
404
|
-
"引" => "D"
|
405
|
-
}[str] || ""
|
406
|
-
end
|
402
|
+
# generate motigoma
|
403
|
+
def make_hand(str)
|
404
|
+
ret = { 'FU' => 0, 'KY' => 0, 'KE' => 0, 'GI' => 0, 'KI' => 0, 'KA' => 0, 'HI' => 0 }
|
405
|
+
return ret if str.empty?
|
407
406
|
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
407
|
+
str.gsub(/ $/, '').split(' ').each do |kind|
|
408
|
+
next if kind.empty?
|
409
|
+
ret[kind2csa(kind[0])] = kind.length == 1 ? 1 : kan2n2(kind[1..-1])
|
410
|
+
end
|
412
411
|
|
413
|
-
|
414
|
-
next if kind.empty?
|
415
|
-
ret[kind2csa(kind[0])] = kind.length == 1 ? 1 : kan2n2(kind[1..-1])
|
412
|
+
ret
|
416
413
|
end
|
417
414
|
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
# check eos
|
422
|
-
def eos?
|
423
|
-
@input[@current_pos].nil?
|
415
|
+
def eos?
|
416
|
+
@scanner.eos?
|
417
|
+
end
|
424
418
|
end
|
425
419
|
end
|
426
420
|
end
|