jkf 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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