jkf 0.4.0 → 0.4.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.
@@ -2,6 +2,8 @@
2
2
 
3
3
  module Jkf::Parser
4
4
  class Ki2 < Base
5
+ include Kifuable
6
+
5
7
  def parse_root
6
8
  s0 = @current_pos
7
9
  s1 = []
@@ -13,75 +15,22 @@ module Jkf::Parser
13
15
  if s1 != :failed
14
16
  s2 = parse_initialboard
15
17
  s2 = nil if s2 == :failed
16
- if s2 != :failed
17
- s3 = []
18
+ s3 = []
19
+ s4 = parse_header
20
+ while s4 != :failed
21
+ s3 << s4
18
22
  s4 = parse_header
19
- while s4 != :failed
20
- s3 << s4
21
- s4 = parse_header
22
- end
23
- if s3 != :failed
24
- s4 = parse_moves
25
- if s4 != :failed
26
- s5 = []
27
- s6 = parse_fork
28
- while s6 != :failed
29
- s5 << s6
30
- s6 = parse_fork
31
- end
32
- if s5 != :failed
33
- @reported_pos = s0
34
- s1 = -> (headers, ini, headers2, moves, forks) {
35
- ret = { "header" => {}, "moves" => moves }
36
- headers.compact.each { |h| ret["header"][h["k"]] = h["v"] }
37
- headers2.compact.each { |h| ret["header"][h["k"]] = h["v"] }
38
- if ini
39
- ret["initial"] = ini
40
- elsif ret["header"]["手合割"]
41
- preset = preset2str(ret["header"]["手合割"])
42
- ret["initial"] = { "preset" => preset } if preset != "OTHER"
43
- end
44
- if ret["initial"] && ret["initial"]["data"]
45
- if ret["header"]["手番"]
46
- ret["initial"]["data"]["color"] = ("下先".index(ret["header"]["手番"]) >= 0 ? 0 : 1)
47
- ret["header"].delete("手番")
48
- else
49
- ret["initial"]["data"]["color"] = 0
50
- end
51
- ret["initial"]["data"]["hands"] = [
52
- make_hand(ret["header"]["先手の持駒"] || ret["header"]["下手の持駒"]),
53
- make_hand(ret["header"]["後手の持駒"] || ret["header"]["上手の持駒"])
54
- ]
55
- %w(先手の持駒 下手の持駒 後手の持駒 上手の持駒).each do |key|
56
- ret["header"].delete(key)
57
- end
58
- end
59
- fork_stack = [{ "te" => 0, "moves" => moves }]
60
- forks.each do |f|
61
- now_fork = f
62
- _fork = fork_stack.pop
63
- _fork = fork_stack.pop while _fork["te"] > now_fork["te"]
64
- move = _fork["moves"][now_fork["te"] - _fork["te"]]
65
- move["forks"] ||= []
66
- move["forks"] << now_fork["moves"]
67
- fork_stack << _fork
68
- fork_stack << now_fork
69
- end
70
- ret
71
- }.call(s1, s2, s3, s4, s5)
72
- s0 = s1
73
- else
74
- @current_pos = s0
75
- s0 = :failed
76
- end
77
- else
78
- @current_pos = s0
79
- s0 = :failed
80
- end
81
- else
82
- @current_pos = s0
83
- s0 = :failed
23
+ end
24
+ s4 = parse_moves
25
+ if s4 != :failed
26
+ s5 = []
27
+ s6 = parse_fork
28
+ while s6 != :failed
29
+ s5 << s6
30
+ s6 = parse_fork
84
31
  end
32
+ @reported_pos = s0
33
+ s0 = transform_root(s1, s2, s3, s4, s5)
85
34
  else
86
35
  @current_pos = s0
87
36
  s0 = :failed
@@ -95,9 +44,9 @@ module Jkf::Parser
95
44
 
96
45
  def parse_header
97
46
  s0 = @current_pos
98
- s1 = []
99
- s2 = match_regexp(/^[^:\r\n]/)
47
+ s2 = match_regexp(/^[^*:\r\n]/)
100
48
  if s2 != :failed
49
+ s1 = []
101
50
  while s2 != :failed
102
51
  s1 << s2
103
52
  s2 = match_regexp(/^[^:\r\n]/)
@@ -106,180 +55,21 @@ module Jkf::Parser
106
55
  s1 = :failed
107
56
  end
108
57
  if s1 != :failed
109
- s2 = match_str(":")
110
- if s2 != :failed
111
- s3 = []
112
- s4 = parse_nonl
113
- while s4 != :failed
114
- s3 << s4
115
- s4 = parse_nonl
116
- end
117
- if s3 != :failed
58
+ if match_str(":") != :failed
59
+ s3 = parse_nonls
60
+ s5 = parse_nl
61
+ if s5 != :failed
118
62
  s4 = []
119
- s5 = parse_nl
120
- if s5 != :failed
121
- while s5 != :failed
122
- s4 << s5
123
- s5 = parse_nl
124
- end
125
- else
126
- s4 = :failed
127
- end
128
- if s4 != :failed
129
- @reported_pos = s0
130
- s0 = s1 = { "k" => s1.join, "v" => s3.join }
131
- else
132
- @current_pos = s0
133
- s0 = :failed
134
- end
135
- else
136
- @current_pos = s0
137
- s0 = :failed
138
- end
139
- else
140
- @current_pos = s0
141
- s0 = :failed
142
- end
143
- else
144
- @current_pos = s0
145
- s0 = :failed
146
- end
147
- if s0 == :failed
148
- s0 = @current_pos
149
- s1 = match_regexp(/^[先後上下]/)
150
- if s1 != :failed
151
- s2 = match_str("手番")
152
- if s2 != :failed
153
- s3 = parse_nl
154
- if s3 != :failed
155
- @reported_pos = s0
156
- s0 = s1 = { "k" => "手番", "v" => s1 }
157
- else
158
- @current_pos = s0
159
- s0 = :failed
160
- end
161
- else
162
- @current_pos = s0
163
- s0 = :failed
164
- end
165
- else
166
- @current_pos = s0
167
- s0 = :failed
168
- end
169
- end
170
- s0
171
- end
172
-
173
- def parse_initialboard
174
- s0 = s1 = @current_pos
175
- s2 = match_str(" ")
176
- if s2 != :failed
177
- s3 = []
178
- s4 = parse_nonl
179
- while s4 != :failed
180
- s3 << s4
181
- s4 = parse_nonl
182
- end
183
- if s3 != :failed
184
- s4 = parse_nl
185
- if s4 != :failed
186
- s1 = s2 = [s2, s3, s4]
187
- else
188
- @current_pos = s1
189
- s1 = :failed
190
- end
191
- else
192
- @current_pos = s1
193
- s1 = :failed
194
- end
195
- else
196
- @current_pos = s1
197
- s1 = :failed
198
- end
199
- s1 = nil if s1 == :failed
200
- if s1 != :failed
201
- s2 = @current_pos
202
- s3 = match_str("+")
203
- if s3 != :failed
204
- s4 = []
205
- s5 = parse_nonl
206
- while s5 != :failed
207
- s4 << s5
208
- s5 = parse_nonl
209
- end
210
- if s4 != :failed
211
- s5 = parse_nl
212
- if s5 != :failed
213
- s2 = s3 = [s3, s4, s5]
214
- else
215
- @current_pos = s2
216
- s2 = :failed
63
+ while s5 != :failed
64
+ s4 << s5
65
+ s5 = parse_nl
217
66
  end
218
67
  else
219
- @current_pos = s2
220
- s2 = :failed
68
+ s4 = :failed
221
69
  end
222
- else
223
- @current_pos = s2
224
- s2 = :failed
225
- end
226
- s2 = nil if s2 == :failed
227
- if s2 != :failed
228
- s3 = []
229
- s4 = parse_ikkatsuline
230
70
  if s4 != :failed
231
- while s4 != :failed
232
- s3 << s4
233
- s4 = parse_ikkatsuline
234
- end
235
- else
236
- s3 = :failed
237
- end
238
- if s3 != :failed
239
- s4 = @current_pos
240
- s5 = match_str("+")
241
- if s5 != :failed
242
- s6 = []
243
- s7 = parse_nonl
244
- while s7 != :failed
245
- s6 << s7
246
- s7 = parse_nonl
247
- end
248
- if s6 != :failed
249
- s7 = parse_nl
250
- if s7 != :failed
251
- s4 = s5 = [s5, s6, s7]
252
- else
253
- @current_pos = s4
254
- s4 = :failed
255
- end
256
- else
257
- @current_pos = s4
258
- s4 = :failed
259
- end
260
- else
261
- @current_pos = s4
262
- s4 = :failed
263
- end
264
- s4 = nil if s4 == :failed
265
- if s4 != :failed
266
- @reported_pos = s0
267
- s1 = -> (lines) {
268
- board = []
269
- 9.times { |i|
270
- line = []
271
- 9.times { |j|
272
- line << lines[j][8-i]
273
- }
274
- board << line
275
- }
276
- { "preset" => "OTHER", "data" => { "board" => board } }
277
- }.call(s3)
278
- s0 = s1
279
- else
280
- @current_pos = s0
281
- s0 = :failed
282
- end
71
+ @reported_pos = s0
72
+ s0 = { "k" => s1.join, "v" => s3.join }
283
73
  else
284
74
  @current_pos = s0
285
75
  s0 = :failed
@@ -292,117 +82,32 @@ module Jkf::Parser
292
82
  @current_pos = s0
293
83
  s0 = :failed
294
84
  end
295
-
296
- return s0
85
+ s0 = parse_header_teban if s0 == :failed
86
+ s0
297
87
  end
298
88
 
299
- def parse_ikkatsuline
89
+ def parse_header_teban
300
90
  s0 = @current_pos
301
- s1 = match_str("|")
91
+ s1 = match_regexp(/^[先後上下]/)
302
92
  if s1 != :failed
303
- s2 = []
304
- s3 = parse_masu
305
- if s3 != :failed
306
- while s3 != :failed
307
- s2 << s3
308
- s3 = parse_masu
309
- end
310
- else
311
- s2 = :failed
312
- end
93
+ s2 = match_str("手番")
313
94
  if s2 != :failed
314
- s3 = match_str("|")
95
+ s3 = parse_nl
315
96
  if s3 != :failed
316
- s4 = []
317
- s5 = parse_nonl
318
- if s5 != :failed
319
- while s5 != :failed
320
- s4 << s5
321
- s5 = parse_nonl
322
- end
323
- else
324
- s4 = :failed
325
- end
326
- if s4 != :failed
327
- s5 = parse_nl
328
- if s5 != :failed
329
- @reported_pos = s0
330
- s0 = s1 = s2
331
- else
332
- @current_pos = s0
333
- s0 = :failed
334
- end
335
- else
336
- @current_pos = s0
337
- s0 = :failed
338
- end
97
+ @reported_pos = s0
98
+ { "k" => "手番", "v" => s1 }
339
99
  else
340
100
  @current_pos = s0
341
- s0 = :failed
101
+ :failed
342
102
  end
343
103
  else
344
104
  @current_pos = s0
345
- s0 = :failed
346
- end
347
- else
348
- @current_pos = s0
349
- s0 = :failed
350
- end
351
-
352
- return s0
353
- end
354
-
355
- def parse_masu
356
- s0 = @current_pos
357
- s1 = parse_teban
358
- if s1 != :failed
359
- s2 = parse_piece
360
- if s2 != :failed
361
- @reported_pos = s0
362
- s1 = { "color" => s1, "kind" => s2 }
363
- s0 = s1
364
- else
365
- @current_pos = s0
366
- s0 = :failed
105
+ :failed
367
106
  end
368
107
  else
369
108
  @current_pos = s0
370
- s0 = :failed
371
- end
372
- if s0 == :failed
373
- s0 = @current_pos
374
- s1 = match_str(" ・")
375
- if s1 != :failed
376
- @reported_pos = s0
377
- s1 = {}
378
- end
379
- s0 = s1
109
+ :failed
380
110
  end
381
-
382
- s0
383
- end
384
-
385
- def parse_teban
386
- s0 = @current_pos
387
- s1 = match_str(" ")
388
- s1 = match_str("+") if s1 == :failed
389
- s1 = match_str("^") if s1 == :failed
390
- if s1 != :failed
391
- @reported_pos = s0
392
- s1 = 0
393
- end
394
- s0 = s1
395
- if s0 == :failed
396
- s0 = @current_pos
397
- s1 = match_str("v")
398
- s1 = match_str("V") if s1 == :failed
399
- if s1 != :failed
400
- @reported_pos = s0
401
- s1 = 1
402
- end
403
- s0 = s1
404
- end
405
- s0
406
111
  end
407
112
 
408
113
  def parse_moves
@@ -415,25 +120,14 @@ module Jkf::Parser
415
120
  s2 << s3
416
121
  s3 = parse_move
417
122
  end
418
- if s2 != :failed
419
- s3 = parse_result
420
- s3 = nil if s3 == :failed
421
- if s3 != :failed
422
- @reported_pos = s0
423
- s1 = -> (hd, tl, res) {
424
- tl.unshift(hd)
425
- tl << { "special" => res } if res && !tl[tl.length-1]["special"]
426
- tl
427
- }.call(s1, s2, s3)
428
- s0 = s1
429
- else
430
- @current_pos = s0
431
- s0 = :failed
432
- end
433
- else
434
- @current_pos = s0
435
- s0 = :failed
436
- end
123
+ s3 = parse_result
124
+ s3 = nil if s3 == :failed
125
+ @reported_pos = s0
126
+ s0 = -> (hd, tl, res) do
127
+ tl.unshift(hd)
128
+ tl << { "special" => res } if res && !tl[tl.length - 1]["special"]
129
+ tl
130
+ end.call(s1, s2, s3)
437
131
  else
438
132
  @current_pos = s0
439
133
  s0 = :failed
@@ -449,22 +143,9 @@ module Jkf::Parser
449
143
  s1 << s2
450
144
  s2 = parse_comment
451
145
  end
452
- if s1 != :failed
453
- s2 = parse_pointer
454
- if s2 == :failed
455
- s2 = nil
456
- end
457
- if s2 != :failed
458
- @reported_pos = s0
459
- s0 = s1 = (s1.length == 0 ? {} : {"comments" =>s1})
460
- else
461
- @current_pos = s0
462
- s0 = :failed
463
- end
464
- else
465
- @current_pos = s0
466
- s0 = :failed
467
- end
146
+ parse_pointer
147
+ @reported_pos = s0
148
+ s0 = s1.empty? ? {} : { "comments" => s1 }
468
149
  s0
469
150
  end
470
151
 
@@ -478,40 +159,21 @@ module Jkf::Parser
478
159
  s2 << s3
479
160
  s3 = parse_comment
480
161
  end
481
- if s2 != :failed
482
- s3 = parse_pointer
483
- if s3 == :failed
484
- s3 = nil
485
- end
486
- if s3 != :failed
487
- s4 = []
488
- s5 = parse_nl
489
- s5 = match_str(" ") if s5 == :failed
490
- while s5 != :failed
491
- s4 << s5
492
- s5 = parse_nl
493
- s5 = match_str(" ") if s5 == :failed
494
- end
495
- if s4 != :failed
496
- @reported_pos = s0
497
- s1 = -> (line, c) {
498
- ret = { "move" => line }
499
- ret["comments"] = c if c.length > 0
500
- ret
501
- }.call(s1, s2)
502
- s0 = s1
503
- else
504
- @current_pos = s0
505
- s0 = :failed
506
- end
507
- else
508
- @current_pos = s0
509
- s0 = :failed
510
- end
511
- else
512
- @current_pos = s0
513
- s0 = :failed
162
+ parse_pointer
163
+ s4 = []
164
+ s5 = parse_nl
165
+ s5 = match_space if s5 == :failed
166
+ while s5 != :failed
167
+ s4 << s5
168
+ s5 = parse_nl
169
+ s5 = match_space if s5 == :failed
514
170
  end
171
+ @reported_pos = s0
172
+ s0 = -> (line, c) do
173
+ ret = { "move" => line }
174
+ ret["comments"] = c if !c.empty?
175
+ ret
176
+ end.call(s1, s2)
515
177
  else
516
178
  @current_pos = s0
517
179
  s0 = :failed
@@ -520,61 +182,27 @@ module Jkf::Parser
520
182
  s0
521
183
  end
522
184
 
523
- def parse_pointer
524
- s0 = @current_pos
525
- s1 = match_str("&")
526
- if s1 != :failed
527
- s2 = []
528
- s3 = parse_nonl
529
- while s3 != :failed
530
- s2 << s3
531
- s3 = parse_nonl
532
- end
533
- if s2 != :failed
534
- s3 = parse_nl
535
- if s3 != :failed
536
- s0 = s1 = [s1, s2, s3]
537
- else
538
- @current_pos = s0
539
- s0 = :failed
540
- end
541
- else
542
- @current_pos = s0
543
- s0 = :failed
544
- end
545
- else
546
- @current_pos = s0
547
- s0 = :failed
548
- end
549
- s0
550
- end
551
-
552
185
  def parse_line
553
186
  s0 = @current_pos
554
187
  s1 = match_regexp(/^[▲△]/)
555
188
  if s1 != :failed
556
- s1 = if s1 == ''
557
- { 'color' => 0 }
189
+ s1 = if s1 == ""
190
+ { "color" => 0 }
558
191
  else
559
- { 'color' => 1 }
192
+ { "color" => 1 }
560
193
  end
561
194
  s2 = parse_fugou
562
195
  if s2 != :failed
563
196
  s3 = []
564
197
  s4 = parse_nl
565
- s4 = match_str(" ") if s4 == :failed
198
+ s4 = match_space if s4 == :failed
566
199
  while s4 != :failed
567
200
  s3 << s4
568
201
  s4 = parse_nl
569
- s4 = match_str(" ") if s4 == :failed
570
- end
571
- if s3 != :failed
572
- @reported_pos = s0
573
- s0 = s1 = s2.merge(s1)
574
- else
575
- @current_pos = s0
576
- s0 = :failed
202
+ s4 = match_space if s4 == :failed
577
203
  end
204
+ @reported_pos = s0
205
+ s0 = s2.merge(s1)
578
206
  else
579
207
  @current_pos = s0
580
208
  s0 = :failed
@@ -594,60 +222,23 @@ module Jkf::Parser
594
222
  if s2 != :failed
595
223
  s3 = parse_soutai
596
224
  s3 = nil if s3 == :failed
597
- if s3 != :failed
598
- s4 = parse_dousa
599
- s4 = nil if s4 == :failed
600
- if s4 != :failed
601
- s5 = match_str("成")
602
- s5 = match_str("不成") if s5 == :failed
603
- s5 = nil if s5 == :failed
604
- if s5 != :failed
605
- s6 = match_str("打")
606
- s6 = nil if s6 == :failed
607
- if s6 != :failed
608
- @reported_pos = s0
609
- s1 = -> (pl, pi, sou, dou, pro, da) {
610
- ret = { "piece" => pi }
611
- if pl["same"]
612
- ret["same"] = true
613
- else
614
- ret["to"] = pl
615
- end
616
- ret["promote"] = (pro == "成") if pro
617
- if da
618
- ret["relative"] = "H"
619
- else
620
- rel = soutai2relative(sou) + dousa2relative(dou)
621
- ret["relative"] = rel unless rel.empty? !=""
622
- end
623
- ret
624
- }.call(s1, s2, s3, s4, s5, s6)
625
- s0 = s1
626
- else
627
- @current_pos = s0
628
- s0 = :failed
629
- end
630
- else
631
- @current_pos = s0
632
- s0 = :failed
633
- end
634
- else
635
- @current_pos = s0
636
- s0 = :failed
637
- end
638
- else
639
- @current_pos = s0
640
- s0 = :failed
641
- end
225
+ s4 = parse_dousa
226
+ s4 = nil if s4 == :failed
227
+ s5 = match_str("成")
228
+ s5 = match_str("不成") if s5 == :failed
229
+ s5 = nil if s5 == :failed
230
+ s6 = match_str("")
231
+ s6 = nil if s6 == :failed
232
+ @reported_pos = s0
233
+ transform_fugou(s1, s2, s3, s4, s5, s6)
642
234
  else
643
235
  @current_pos = s0
644
- s0 = :failed
236
+ :failed
645
237
  end
646
238
  else
647
239
  @current_pos = s0
648
- s0 = :failed
240
+ :failed
649
241
  end
650
- s0
651
242
  end
652
243
 
653
244
  def parse_place
@@ -657,7 +248,7 @@ module Jkf::Parser
657
248
  s2 = parse_numkan
658
249
  if s2 != :failed
659
250
  @reported_pos = s0
660
- s0 = s1 = { "x" => s1, "y" => s2 }
251
+ s0 = { "x" => s1, "y" => s2 }
661
252
  else
662
253
  @current_pos = s0
663
254
  s0 = :failed
@@ -668,17 +259,10 @@ module Jkf::Parser
668
259
  end
669
260
  if s0 == :failed
670
261
  s0 = @current_pos
671
- s1 = match_regexp("同")
672
- if s1 != :failed
673
- s2 = match_str(" ")
674
- s2 = nil if s2 == :failed
675
- if s2 != :failed
676
- @reported_pos = s0
677
- s0 = s1 = { "same" => true }
678
- else
679
- @current_pos = s0
680
- s0 = :failed
681
- end
262
+ if match_regexp("同") != :failed
263
+ match_str(" ")
264
+ @reported_pos = s0
265
+ s0 = { "same" => true }
682
266
  else
683
267
  @current_pos = s0
684
268
  s0 = :failed
@@ -687,26 +271,6 @@ module Jkf::Parser
687
271
  s0
688
272
  end
689
273
 
690
- def parse_piece
691
- s0 = @current_pos
692
- s1 = match_regexp("成")
693
- s1 = "" if s1 == :failed
694
- if s1 != :failed
695
- s2 = match_regexp(/^[歩香桂銀金角飛王玉と杏圭全馬竜龍]/)
696
- if s2 != :failed
697
- @reported_pos = s0
698
- s0 = s1 = kind2csa(s1 + s2)
699
- else
700
- @current_pos = s0
701
- s0 = :failed
702
- end
703
- else
704
- @current_pos = s0
705
- s0 = :failed
706
- end
707
-
708
- return s0
709
- end
710
274
 
711
275
  def parse_soutai
712
276
  match_regexp(/^[左直右]/)
@@ -716,47 +280,13 @@ module Jkf::Parser
716
280
  match_regexp(/^[上寄引]/)
717
281
  end
718
282
 
719
- def parse_num
720
- s0 = @current_pos
721
- s1 = match_regexp(/^[123456789]/)
722
- if s1 != :failed
723
- @reported_pos = s0
724
- s1 = zen2n(s1)
725
- end
726
- s0 = s1
727
- s0
728
- end
729
-
730
- def parse_numkan
731
- s0 = @current_pos
732
- s1 = match_regexp(/^[一二三四五六七八九]/)
733
- if s1 != :failed
734
- @reported_pos = s0
735
- s1 = kan2n(s1)
736
- end
737
- s0 = s1
738
- s0
739
- end
740
-
741
283
  def parse_comment
742
284
  s0 = @current_pos
743
- s1 = match_str("*")
744
- if s1 != :failed
745
- s2 = []
746
- s3 = parse_nonl
747
- while s3 != :failed
748
- s2 << s3
749
- s3 = parse_nonl
750
- end
751
- if s2 != :failed
752
- s3 = parse_nl
753
- if s3 != :failed
754
- @reported_pos = s0
755
- s0 = s1 = s2.join
756
- else
757
- @current_pos = s0
758
- s0 = :failed
759
- end
285
+ if match_str("*") != :failed
286
+ s2 = parse_nonls
287
+ if parse_nl != :failed
288
+ @reported_pos = s0
289
+ s0 = s2.join
760
290
  else
761
291
  @current_pos = s0
762
292
  s0 = :failed
@@ -768,237 +298,18 @@ module Jkf::Parser
768
298
  s0
769
299
  end
770
300
 
771
- def parse_result
301
+ def parse_fork
772
302
  s0 = @current_pos
773
- s1 = match_str("まで")
774
- if s1 != :failed
775
- s2 = []
776
- s3 = match_regexp(/^[0-9]/)
303
+ if match_str("変化:") != :failed
304
+ match_spaces
305
+ s3 = match_digits!
777
306
  if s3 != :failed
778
- while s3 != :failed
779
- s2 << s3
780
- s3 = match_regexp(/^[0-9]/)
781
- end
782
- else
783
- s2 = :failed
784
- end
785
- if s2 != :failed
786
- s3 = match_str("手")
787
- if s3 != :failed
788
- s4 = @current_pos
789
- s5 = match_str("で")
790
- if s5 != :failed
791
- s6 = parse_turn
307
+ if match_str("手") != :failed
308
+ if parse_nl != :failed
309
+ s6 = parse_moves
792
310
  if s6 != :failed
793
- s7 = match_str("手の")
794
- if s7 != :failed
795
- s8 = @current_pos
796
- s9 = match_str("勝ち")
797
- if s9 != :failed
798
- @reported_pos = s8
799
- s9 = "TORYO"
800
- end
801
- s8 = s9
802
- if s8 == :failed
803
- s8 = @current_pos
804
- s9 = match_str("反則")
805
- if s9 != :failed
806
- s10 = @current_pos
807
- s11 = match_str("勝ち")
808
- if s11 != :failed
809
- @reported_pos = s10
810
- s11 = "ILLEGAL_ACTION"
811
- end
812
- s10 = s11
813
- if s10 == :failed
814
- s10 = @current_pos
815
- s11 = match_str("負け")
816
- if s11 != :failed
817
- @reported_pos = s10
818
- s11 ="ILLEGAL_MOVE"
819
- end
820
- s10 = s11
821
- end
822
- if s10 != :failed
823
- @reported_pos = s8
824
- s8 = s9 = s10
825
- else
826
- @current_pos = s8
827
- s8 = :failed
828
- end
829
- else
830
- @current_pos = s8
831
- s8 = :failed
832
- end
833
- end
834
- if s8 != :failed
835
- @reported_pos = s4
836
- s4 = s5 = s8
837
- else
838
- @current_pos = s4
839
- s4 = :failed
840
- end
841
- else
842
- @current_pos = s4
843
- s4 = :failed
844
- end
845
- else
846
- @current_pos = s4
847
- s4 = :failed
848
- end
849
- else
850
- @current_pos = s4
851
- s4 = :failed
852
- end
853
- if s4 == :failed
854
- s4 = @current_pos
855
- s5 = match_str("で時間切れにより")
856
- if s5 != :failed
857
- s6 = parse_turn
858
- if s6 != :failed
859
- s7 = match_str("手の勝ち")
860
- if s7 != :failed
861
- @reported_pos = s4
862
- s5 = "TIME_UP"
863
- s4 = s5
864
- else
865
- @current_pos = s4
866
- s4 = :failed
867
- end
868
- else
869
- @current_pos = s4
870
- s4 = :failed
871
- end
872
- else
873
- @current_pos = s4
874
- s4 = :failed
875
- end
876
- if s4 == :failed
877
- s4 = @current_pos
878
- s5 = match_str("で中断")
879
- if s5 != :failed
880
- @reported_pos = s4
881
- s5 = "CHUDAN"
882
- end
883
- s4 = s5
884
- if s4 == :failed
885
- s4 = @current_pos
886
- s5 = match_str("で持将棋")
887
- if s5 != :failed
888
- @reported_pos = s4
889
- s5 = "JISHOGI"
890
- end
891
- s4 = s5
892
- if s4 == :failed
893
- s4 = @current_pos
894
- s5 = match_str("で千日手")
895
- if s5 != :failed
896
- @reported_pos = s4
897
- s5 = "SENNICHITE"
898
- end
899
- s4 = s5
900
- if s4 == :failed
901
- s4 = @current_pos
902
- s5 = match_str("で")
903
- s5 = nil if s5 == :failed
904
- if s5 != :failed
905
- s6 = match_str("詰")
906
- if s6 != :failed
907
- s7 = match_str("み")
908
- if s7 == :failed
909
- s7 = nil
910
- end
911
- if s7 != :failed
912
- @reported_pos = s4
913
- s4 = s5 = "TSUMI"
914
- else
915
- @current_pos = s4
916
- s4 = :failed
917
- end
918
- else
919
- @current_pos = s4
920
- s4 = :failed
921
- end
922
- else
923
- @current_pos = s4
924
- s4 = :failed
925
- end
926
- if s4 == :failed
927
- s4 = @current_pos
928
- s5 = match_str("で不詰")
929
- if s5 != :failed
930
- @reported_pos = s4
931
- s5 = "FUZUMI"
932
- end
933
- s4 = s5
934
- end
935
- end
936
- end
937
- end
938
- end
939
- end
940
- if s4 != :failed
941
- s5 = parse_nl
942
- if s5 != :failed || @input[@current_pos].nil?
943
311
  @reported_pos = s0
944
- s0 = s1 = s4
945
- else
946
- @current_pos = s0
947
- s0 = :failed
948
- end
949
- else
950
- @current_pos = s0
951
- s0 = :failed
952
- end
953
- else
954
- @current_pos = s0
955
- s0 = :failed
956
- end
957
- else
958
- @current_pos = s0
959
- s0 = :failed
960
- end
961
- else
962
- @current_pos = s0
963
- s0 = :failed
964
- end
965
- s0
966
- end
967
-
968
- def parse_fork
969
- s0 = @current_pos
970
- s1 = match_str( "変化:")
971
- if s1 != :failed
972
- s2 = []
973
- s3 = match_str(" ")
974
- while s3 != :failed
975
- s2 << s3
976
- s3 = match_str(" ")
977
- end
978
- if s2 != :failed
979
- s3 = []
980
- s4 = match_regexp(/^[0-9]/)
981
- if s4 != :failed
982
- while s4 != :failed
983
- s3 << s4
984
- s4 = match_regexp(/^[0-9]/)
985
- end
986
- else
987
- s3 = :failed
988
- end
989
- if s3 != :failed
990
- s4 = match_str("手")
991
- if s4 != :failed
992
- s5 = parse_nl
993
- if s5 != :failed
994
- s6 = parse_moves
995
- if s6 != :failed
996
- @reported_pos = s0
997
- s0 = s1 = { "te" => s3.join.to_i, "moves" => s6[1..-1] }
998
- else
999
- @current_pos = s0
1000
- s0 = :failed
1001
- end
312
+ s0 = { "te" => s3.join.to_i, "moves" => s6[1..-1] }
1002
313
  else
1003
314
  @current_pos = s0
1004
315
  s0 = :failed
@@ -1026,172 +337,45 @@ module Jkf::Parser
1026
337
  match_regexp(/^[先後上下]/)
1027
338
  end
1028
339
 
1029
- def parse_nl
1030
- s0 = @current_pos
1031
- s1 = []
1032
- s2 = parse_newline
1033
- if s2 != :failed
1034
- while s2 != :failed
1035
- s1 << s2
1036
- s2 = parse_newline
1037
- end
1038
- else
1039
- s1 = :failed
1040
- end
1041
- if s1 != :failed
1042
- s2 = []
1043
- s3 = parse_skipline
1044
- while s3 != :failed
1045
- s2 << s3
1046
- s3 = parse_skipline
1047
- end
1048
- if s2 != :failed
1049
- s0 = s1 = [s1, s2]
1050
- else
1051
- @current_pos = s0
1052
- s0 = :failed
1053
- end
1054
- else
1055
- @current_pos = s0
1056
- s0 = :failed
1057
- end
1058
- s0
1059
- end
1060
-
1061
- def parse_skipline
1062
- s0 = @current_pos
1063
- s1 = match_str("#")
1064
- if s1 != :failed
1065
- s2 = []
1066
- s3 = parse_nonl
1067
- while s3 != :failed
1068
- s2 << s3
1069
- s3 = parse_nonl
1070
- end
1071
- if s2 != :failed
1072
- s3 = parse_newline
1073
- if s3 != :failed
1074
- s0 = s1 = [s1, s2, s3]
1075
- else
1076
- @current_pos = s0
1077
- s0 = :failed
1078
- end
1079
- else
1080
- @current_pos = s0
1081
- s0 = :failed
1082
- end
1083
- else
1084
- @current_pos = s0
1085
- s0 = :failed
1086
- end
1087
- s0
1088
- end
1089
-
1090
- def parse_whitespace
1091
- s0 = match_str(" ")
1092
- s0 = match_str("\t") if s0 == :failed
1093
- s0
1094
- end
1095
-
1096
- def parse_newline
1097
- s0 = @current_pos
1098
- s1 = []
1099
- s2 = parse_whitespace
1100
- while s2 != :failed
1101
- s1 << s2
1102
- s2 = parse_whitespace
1103
- end
1104
- if s1 != :failed
1105
- s2 = match_str("\n")
1106
- if s2 == :failed
1107
- s2 = @current_pos
1108
- s3 = match_str("\r")
1109
- if s3 != :failed
1110
- s4 = match_str("\n")
1111
- s4 = nil if s4 == :failed
1112
- if s4 != :failed
1113
- s2 = s3 = [s3, s4]
1114
- else
1115
- @current_pos = s2
1116
- s2 = :failed
1117
- end
1118
- else
1119
- @current_pos = s2
1120
- s2 = :failed
1121
- end
1122
- end
1123
- if s2 != :failed
1124
- s0 = s1 = [s1, s2]
1125
- else
1126
- @current_pos = s0
1127
- s0 = :failed
1128
- end
1129
- else
1130
- @current_pos = s0
1131
- s0 = :failed
1132
- end
1133
- s0
1134
- end
1135
-
1136
- def parse_nonl
1137
- match_regexp(/^[^\r\n]/)
1138
- end
1139
-
1140
340
  protected
1141
341
 
1142
- def zen2n(s)
1143
- "0123456789".index(s)
1144
- end
1145
-
1146
- def kan2n(s)
1147
- "〇一二三四五六七八九".index(s)
342
+ def transform_root(headers, ini, headers2, moves, forks)
343
+ ret = { "header" => {}, "moves" => moves }
344
+ headers.compact.each { |h| ret["header"][h["k"]] = h["v"] }
345
+ headers2.compact.each { |h| ret["header"][h["k"]] = h["v"] }
346
+ if ini
347
+ ret["initial"] = ini
348
+ elsif ret["header"]["手合割"]
349
+ preset = preset2str(ret["header"]["手合割"])
350
+ ret["initial"] = { "preset" => preset } if preset != "OTHER"
351
+ end
352
+ transform_root_header_data(ret) if ret["initial"] && ret["initial"]["data"]
353
+ transform_root_forks(forks, moves)
354
+ ret
1148
355
  end
1149
356
 
1150
- def kan2n2(s)
1151
- case s.length
1152
- when 1
1153
- "〇一二三四五六七八九十".index(s)
1154
- when 2
1155
- "〇一二三四五六七八九十".index(s[1])+10
357
+ def transform_fugou(pl, pi, sou, dou, pro, da)
358
+ ret = { "piece" => pi }
359
+ if pl["same"]
360
+ ret["same"] = true
1156
361
  else
1157
- raise "21以上の数値に対応していません"
362
+ ret["to"] = pl
1158
363
  end
1159
- end
1160
-
1161
- def kind2csa(kind)
1162
- if kind[0] == "成"
1163
- {
1164
- "香" => "NY",
1165
- "桂" => "NK",
1166
- "銀" => "NG"
1167
- }[kind[1]]
364
+ ret["promote"] = (pro == "成") if pro
365
+ if da
366
+ ret["relative"] = "H"
1168
367
  else
1169
- {
1170
- "" => "FU",
1171
- "香" => "KY",
1172
- "桂" => "KE",
1173
- "銀" => "GI",
1174
- "金" => "KI",
1175
- "角" => "KA",
1176
- "飛" => "HI",
1177
- "玉" => "OU",
1178
- "王" => "OU",
1179
- "と" => "TO",
1180
- "杏" => "NY",
1181
- "圭" => "NK",
1182
- "全" => "NG",
1183
- "馬" => "UM",
1184
- "竜" => "RY",
1185
- "龍" => "RY"
1186
- }[kind]
368
+ rel = soutai2relative(sou) + dousa2relative(dou)
369
+ ret["relative"] = rel unless rel.empty?
1187
370
  end
371
+ ret
1188
372
  end
1189
373
 
1190
374
  def soutai2relative(str)
1191
375
  {
1192
376
  "左" => "L",
1193
377
  "直" => "C",
1194
- "右" => "R",
378
+ "右" => "R"
1195
379
  }[str] || ""
1196
380
  end
1197
381
 
@@ -1199,42 +383,24 @@ module Jkf::Parser
1199
383
  {
1200
384
  "上" => "U",
1201
385
  "寄" => "M",
1202
- "引" => "D",
386
+ "引" => "D"
1203
387
  }[str] || ""
1204
388
  end
1205
389
 
1206
- def preset2str(preset)
1207
- {
1208
- "平手" => "HIRATE",
1209
- "香落ち" => "KY",
1210
- "右香落ち" => "KY_R",
1211
- "角落ち" => "KA",
1212
- "飛車落ち" => "HI",
1213
- "飛香落ち" => "HIKY",
1214
- "二枚落ち" => "2",
1215
- "三枚落ち" => "3",
1216
- "四枚落ち" => "4",
1217
- "五枚落ち" => "5",
1218
- "左五枚落ち" => "5_L",
1219
- "六枚落ち" => "6",
1220
- "八枚落ち" => "8",
1221
- "十枚落ち" => "10",
1222
- "その他" => "OTHER",
1223
- }[preset.gsub(/\s/, "")]
1224
- end
1225
-
1226
390
  def make_hand(str)
1227
- kinds = str.gsub(/ $/, "").split(" ")
1228
-
1229
391
  ret = { "FU" => 0, "KY" => 0, "KE" => 0, "GI" => 0, "KI" => 0, "KA" => 0, "HI" => 0 }
1230
392
  return ret if str.empty?
1231
393
 
1232
- kinds.each do |kind|
394
+ str.gsub(/ $/, "").split(" ").each do |kind|
1233
395
  next if kind.empty?
1234
396
  ret[kind2csa(kind[0])] = kind.length == 1 ? 1 : kan2n2(kind[1..-1])
1235
397
  end
1236
398
 
1237
399
  ret
1238
400
  end
401
+
402
+ def eos?
403
+ @input[@current_pos].nil?
404
+ end
1239
405
  end
1240
406
  end