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