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.
@@ -1,28 +1,19 @@
1
1
  module Jkf::Converter
2
- class Ki2
3
- def convert(jkf)
4
- hash = if jkf.is_a?(Hash)
5
- jkf
6
- else
7
- JSON.parse(jkf)
8
- end
9
- @forks = []
2
+ class Ki2 < Base
3
+ protected
4
+
5
+ include Kifuable
10
6
 
11
- players_flag = :sengo
12
- hash['header'] && hash['header'].keys.find { |key| key =~ /[上下]手/ } && players_flag = :uwasimo
13
- @players = if players_flag == :uwasimo
14
- ['下', '上']
15
- else
16
- ['先', '後']
17
- end
18
- @header2 = []
7
+ def convert_root(jkf)
8
+ reset!
9
+ setup_players!(jkf)
19
10
 
20
- result = ''
21
- result += convert_header(hash['header']) if hash['header']
22
- result += convert_initial(hash['initial']) if hash['initial']
23
- result += @header2.join
24
- result += convert_moves(hash['moves']) if hash['moves']
25
- if @forks.size > 0
11
+ result = ""
12
+ result += convert_header(jkf["header"]) if jkf["header"]
13
+ result += convert_initial(jkf["initial"]) if jkf["initial"]
14
+ result += @header2.join + "\n"
15
+ result += convert_moves(jkf["moves"]) if jkf["moves"]
16
+ if !@forks.empty?
26
17
  result += "\n"
27
18
  result += @forks.join("\n")
28
19
  end
@@ -31,242 +22,91 @@ module Jkf::Converter
31
22
  end
32
23
 
33
24
  def convert_header(header)
34
- header.map { |(key, value)|
35
- result = "#{key}:#{value}\n"
25
+ header.map do |(key, value)|
26
+ result = add_header(key, value)
36
27
  if key =~ /\A[先後上下]手\Z/
37
- if key =~ /[先下]/
38
- @header2.unshift result
39
- else
40
- @header2 << result
41
- end
42
28
  nil
43
29
  else
44
30
  result
45
31
  end
46
- }.compact.join
32
+ end.compact.join
47
33
  end
48
34
 
49
-
50
- def convert_initial(initial)
51
- result = ''
52
- result += "手合割:#{preset2str(initial["preset"])}\n" if initial["preset"] != "OTHER"
53
- footer = ''
54
-
55
- data = initial["data"]
56
-
57
- if data
58
- result += "#{@players[1]}手番\n" if data['color'] == 1
59
-
60
- if data['hands']
61
- if data['hands'][1]
62
- result += "#{@players[1]}手の持駒:"
63
- result += convert_motigoma(data['hands'][1])
64
- end
65
- if data['hands'][0]
66
- footer += "#{@players[0]}手の持駒:"
67
- footer += convert_motigoma(data['hands'][0])
68
- end
69
- end
70
-
71
- footer += "#{@players[0]}手番\n" if data['color'] == 0
72
-
73
- if data['board']
74
- result += " 9 8 7 6 5 4 3 2 1\n"
75
- result += "+---------------------------+\n"
76
- 9.times { |y|
77
- line = "|"
78
- 9.times { |x|
79
- line += convert_board_piece(data['board'][8-x][y])
80
- }
81
- line += "|#{n2kan(y+1)}\n"
82
- result += line
83
- }
84
- result += "+---------------------------+\n"
35
+ def add_header(key, value)
36
+ result = "#{key}:#{value}\n"
37
+ if key =~ /\A[先後上下]手\Z/
38
+ if key =~ /[先下]/
39
+ @header2.unshift result
40
+ else
41
+ @header2 << result
85
42
  end
86
43
  end
87
-
88
- result += footer
89
-
90
44
  result
91
45
  end
92
46
 
93
- def convert_moves(moves, idx=0)
94
- result = "\n"
95
- i = 0
96
- before_split = ''
97
- moves.each_with_index { |move, j|
98
- if move['special']
99
- result += "\n"
47
+ def convert_moves(moves, idx = 0)
48
+ result = ""
49
+ j = 0
50
+ before_split = ""
51
+ moves.each_with_index do |move, i|
52
+ if move["special"]
100
53
  # first_board+speical分を引く(-2)
101
- result += convert_special(move['special'], j-2+idx) if move['special']
54
+ result += convert_special_and_split(move, i + idx - 2)
102
55
  else
103
56
  result += before_split
104
- if move['move']
105
- result_move = convert_move(move['move'])
106
- i += 1
107
- before_split = if i % 6 == 0
108
- "\n"
109
- else
110
- result_move.size == 4 ? " "*4 : " "*2
111
- end
57
+ if move["move"]
58
+ j += 1
59
+ result_move, before_split = convert_move_and_split(move, j)
112
60
  result += result_move
113
61
  end
114
62
 
115
- if move['comments']
116
- result += "\n" if result[-1] != "\n"
117
- result += convert_comments(move['comments'])
118
- i = 0
63
+ if move["comments"]
64
+ if !(result.end_with?("\n") || result.empty?)
65
+ result += "\n"
66
+ before_split = ""
67
+ j = 0
68
+ end
69
+ result += convert_comments(move["comments"])
119
70
  end
120
71
 
121
- @forks.unshift convert_forks(move['forks'], j+idx) if move['forks']
72
+ @forks.unshift convert_forks(move["forks"], i + idx) if move["forks"]
122
73
  end
123
- }
124
- result
125
- end
126
-
127
- def convert_move(move)
128
- result = move['color'] == 0 ? '▲' : '△'
129
- result += if move['to']
130
- n2zen(move['to']['x']) + n2kan(move['to']['y'])
131
- elsif move['same']
132
- '同 '
133
- else
134
- raise "error??"
135
- end
136
- result += csa2kind(move['piece'])
137
- result += '成' if move['promote']
138
- result += csa2relative(move['relative']) if move['relative']
139
- result
140
- end
141
-
142
- def convert_special(special, index)
143
- result = "まで#{index+1}手"
144
-
145
- if special == 'TORYO' || special =~ /ILLEGAL/
146
- turn = @players[index % 2]
147
- result += "で#{turn}手の"
148
- result += case special
149
- when "TORYO" then "勝ち"
150
- when "ILLEGAL_ACTION" then "反則勝ち"
151
- when "ILLEGAL_MOVE" then "反則負け"
152
- end
153
- else
154
- turn = @players[(index+1) % 2]
155
- result += case special
156
- when "TIME_UP" then "で時間切れにより#{turn}手の勝ち"
157
- when "CHUDAN" then "で中断"
158
- when "JISHOGI" then "で持将棋"
159
- when "SENNICHITE" then "で千日手"
160
- when "TSUMI" then "で詰み"
161
- when "FUZUMI" then "で不詰"
162
- end
163
74
  end
164
- result += "\n"
165
75
  result
166
76
  end
167
77
 
168
- def convert_comments(comments)
169
- comments.map { |comment| "*#{comment}\n" }.join
78
+ def convert_special_and_split(hash, index)
79
+ "\n" + convert_special(hash["special"], index)
170
80
  end
171
81
 
172
- def convert_forks(forks, index)
173
- result = "\n"
174
- result = "変化:%4d手"%[index]
175
- forks.each do |moves|
176
- result += convert_moves(moves, index)
177
- end
178
- result
82
+ def convert_move_and_split(move, num)
83
+ result = convert_move(move["move"])
84
+ split = if num % 6 == 0
85
+ "\n"
86
+ else
87
+ result.size == 4 ? " " * 4 : " " * 2
88
+ end
89
+ [result, split]
179
90
  end
180
91
 
181
- def convert_board_piece(piece)
182
- result = ''
183
-
184
- if piece == {}
185
- result = ' ・'
186
- else
187
- result += piece['color'] == 0 ? ' ' : 'v'
188
- result += csa2kind(piece['kind'])
189
- end
190
-
92
+ def convert_move(move)
93
+ result = move["color"] == 0 ? "▲" : "△"
94
+ result += convert_piece_with_pos(move)
95
+ result += csa2relative(move["relative"]) if move["relative"]
191
96
  result
192
97
  end
193
98
 
194
- def convert_motigoma(pieces)
195
- pieces.to_a.reverse.map do |(piece, num)|
196
- if num > 0
197
- str = csa2kind(piece)
198
- if num > 1
199
- str += n2kan(num/10) if num / 10 > 0
200
- num %= 10
201
- str += n2kan(num)
202
- end
203
- str
204
- else
205
- nil
206
- end
207
- end.compact.join(' ') + " \n"
208
- end
209
-
210
- protected
211
-
212
- def n2zen(n)
213
- "0123456789"[n]
214
- end
215
-
216
- def n2kan(n)
217
- "〇一二三四五六七八九"[n]
218
- end
219
-
220
- def csa2kind(csa)
221
- {
222
- "FU" => "歩",
223
- "KY" => "香",
224
- "KE" => "桂",
225
- "GI" => "銀",
226
- "KI" => "金",
227
- "KA" => "角",
228
- "HI" => "飛",
229
- "OU" => "玉",
230
- "TO" => "と",
231
- "NY" => "成香",
232
- "NK" => "成桂",
233
- "NG" => "成銀",
234
- "UM" => "馬",
235
- "RY" => "龍",
236
- }[csa]
237
- end
238
-
239
- def preset2str(preset)
240
- {
241
- "HIRATE" => "平手",
242
- "KY" => "香落ち",
243
- "KY_R" => "右香落ち",
244
- "KA" => "角落ち",
245
- "HI" => "飛車落ち",
246
- "HIKY" => "飛香落ち",
247
- "2" => "二枚落ち",
248
- "3" => "三枚落ち",
249
- "4" => "四枚落ち",
250
- "5" => "五枚落ち",
251
- "5_L" => "左五枚落ち",
252
- "6" => "六枚落ち",
253
- "8" => "八枚落ち",
254
- "10" => "十枚落ち",
255
- "OTHER" => "その他"
256
- }[preset]
257
- end
258
-
259
99
  def csa2relative(relative)
260
100
  case relative
261
- when 'L' then ''
262
- when 'C' then ''
263
- when 'R' then ''
264
- when 'U' then ''
265
- when 'M' then ''
266
- when 'D' then ''
267
- when 'H' then ''
101
+ when "L" then ""
102
+ when "C" then ""
103
+ when "R" then ""
104
+ when "U" then ""
105
+ when "M" then ""
106
+ when "D" then ""
107
+ when "H" then ""
268
108
  else
269
- ''
109
+ ""
270
110
  end
271
111
  end
272
112
  end
@@ -1,29 +1,20 @@
1
1
  module Jkf::Converter
2
- class Kif
3
- def convert(jkf)
4
- hash = if jkf.is_a?(Hash)
5
- jkf
6
- else
7
- JSON.parse(jkf)
8
- end
9
- @forks = []
2
+ class Kif < Base
3
+ protected
4
+
5
+ include Kifuable
10
6
 
11
- players_flag = :sengo
12
- hash['header'] && hash['header'].keys.find { |key| key =~ /[上下]手/ } && players_flag = :uwasimo
13
- @players = if players_flag == :uwasimo
14
- ['下', '上']
15
- else
16
- ['先', '後']
17
- end
18
- @header2 = []
7
+ def convert_root(jkf)
8
+ reset!
9
+ setup_players!(jkf)
19
10
 
20
- result = ''
21
- result += convert_header(hash['header']) if hash['header']
22
- result += convert_initial(hash['initial']) if hash['initial']
11
+ result = ""
12
+ result += convert_header(jkf["header"]) if jkf["header"]
13
+ result += convert_initial(jkf["initial"]) if jkf["initial"]
23
14
  result += @header2.join
24
15
  result += "手数----指手---------消費時間--\n"
25
- result += convert_moves(hash['moves'])
26
- if @forks.size > 0
16
+ result += convert_moves(jkf["moves"])
17
+ if !@forks.empty?
27
18
  result += "\n"
28
19
  result += @forks.join("\n")
29
20
  end
@@ -31,10 +22,8 @@ module Jkf::Converter
31
22
  result
32
23
  end
33
24
 
34
- protected
35
-
36
25
  def convert_header(header)
37
- header.map { |(key, value)|
26
+ header.map do |(key, value)|
38
27
  result = "#{key}:#{value}\n"
39
28
  if key =~ /\A[先後上下]手\Z/
40
29
  if key =~ /[先下]/
@@ -46,249 +35,83 @@ module Jkf::Converter
46
35
  else
47
36
  result
48
37
  end
49
- }.compact.join
38
+ end.compact.join
50
39
  end
51
40
 
52
- def convert_initial(initial)
53
- result = ''
54
- result += "手合割:#{preset2str(initial["preset"])}\n" if initial["preset"] != "OTHER"
55
- footer = ''
56
-
57
- data = initial["data"]
58
-
59
- if data
60
- result += "#{@players[1]}手番\n" if data['color'] == 1
61
-
62
- if data['hands']
63
- if data['hands'][1]
64
- result += "#{@players[1]}手の持駒:"
65
- result += convert_motigoma(data['hands'][1])
66
- end
67
- if data['hands'][0]
68
- footer += "#{@players[0]}手の持駒:"
69
- footer += convert_motigoma(data['hands'][0])
70
- end
71
- end
72
-
73
- footer += "#{@players[0]}手番\n" if data['color'] == 0
74
-
75
- if data['board']
76
- result += " 9 8 7 6 5 4 3 2 1\n"
77
- result += "+---------------------------+\n"
78
- 9.times { |y|
79
- line = "|"
80
- 9.times { |x|
81
- line += convert_board_piece(data['board'][8-x][y])
82
- }
83
- line += "|#{n2kan(y+1)}\n"
84
- result += line
85
- }
86
- result += "+---------------------------+\n"
41
+ def convert_moves(moves, idx = 0)
42
+ result = ""
43
+ moves.each_with_index do |move, i|
44
+ if move["special"]
45
+ result += convert_special_line(move, i + idx)
46
+ else
47
+ result += convert_move_line(move, i + idx) if move["move"]
48
+ result += convert_comments(move["comments"]) if move["comments"]
49
+ @forks.unshift convert_forks(move["forks"], i + idx) if move["forks"]
87
50
  end
88
51
  end
89
-
90
- result += footer
91
-
92
52
  result
93
53
  end
94
54
 
95
- def convert_moves(moves, idx=0)
96
- result = ''
97
- moves.each_with_index { |move, i|
98
- if move['special']
99
- result_move = "%4d "%(i+idx)
100
- result_move += ljust(special2kan(move['special']), 13)
101
- result_move += convert_time(move['time']) if move['time']
102
- result_move += "+" if move['forks']
103
- result_move += "\n"
104
- result += result_move
105
- # first_board+speical分を引く(-2)
106
- result += convert_special(move['special'], i-2+idx) if move['special']
107
- else
108
- if move['move']
109
- result_move = "%4d "%(i+idx)
110
- result_move += convert_move(move['move'])
111
- result_move += convert_time(move['time']) if move['time']
112
- result_move += "+" if move['forks']
113
- result_move += "\n"
114
- result += result_move
115
- end
116
-
117
- if move['comments']
118
- result += convert_comments(move['comments'])
119
- end
55
+ def convert_move_line(move, index)
56
+ result = "%4d " % [index]
57
+ result += convert_move(move["move"])
58
+ result += convert_time(move["time"]) if move["time"]
59
+ result += "+" if move["forks"]
60
+ result + "\n"
61
+ end
120
62
 
121
- @forks.unshift convert_forks(move['forks'], i+idx) if move['forks']
122
- end
123
- }
124
- result
63
+ def convert_special_line(move, index)
64
+ result = "%4d " % [index]
65
+ result += ljust(special2kan(move["special"]), 13)
66
+ result += convert_time(move["time"]) if move["time"]
67
+ result += "+" if move["forks"]
68
+ result += "\n"
69
+ # first_board+speical分を引く(-2)
70
+ result + convert_special(move["special"], index - 2)
125
71
  end
126
72
 
127
73
  def convert_move(move)
128
- result = if move['to']
129
- n2zen(move['to']['x']) + n2kan(move['to']['y'])
130
- elsif move['same']
131
- '同 '
132
- else
133
- raise "error??"
134
- end
135
- result += csa2kind(move['piece'])
136
- result += '成' if move['promote']
137
- result += if move['from']
138
- "(#{move['from']['x']}#{move['from']['y']})"
74
+ result = convert_piece_with_pos(move)
75
+ result += if move["from"]
76
+ "(#{pos2str(move['from'])})"
139
77
  else
140
- ''
78
+ ""
141
79
  end
142
- result = ljust(result,13)
143
- result
80
+ ljust(result, 13)
144
81
  end
145
82
 
146
83
  def convert_time(time)
147
- "(%2d:%02d/%02d:%02d:%02d)"%[
148
- time['now']['m'],
149
- time['now']['s'],
150
- time['total']['h'],
151
- time['total']['m'],
152
- time['total']['s'],
84
+ "(%2d:%02d/%02d:%02d:%02d)" % [
85
+ time["now"]["m"],
86
+ time["now"]["s"],
87
+ time["total"]["h"],
88
+ time["total"]["m"],
89
+ time["total"]["s"]
153
90
  ]
154
91
  end
155
92
 
156
- def convert_special(special, index)
157
- result = "まで#{index+1}手"
158
-
159
- if special == 'TORYO' || special =~ /ILLEGAL/
160
- turn = @players[index % 2]
161
- result += "で#{turn}手の"
162
- result += case special
163
- when "TORYO" then "勝ち"
164
- when "ILLEGAL_ACTION" then "反則勝ち"
165
- when "ILLEGAL_MOVE" then "反則負け"
166
- end
167
- else
168
- turn = @players[(index+1) % 2]
169
- result += case special
170
- when "TIME_UP" then "で時間切れにより#{turn}手の勝ち"
171
- when "CHUDAN" then "で中断"
172
- when "JISHOGI" then "で持将棋"
173
- when "SENNICHITE" then "で千日手"
174
- when "TSUMI" then "で詰み"
175
- when "FUZUMI" then "で不詰"
176
- end
177
- end
178
-
179
- result += "\n"
180
- result
181
- end
182
-
183
- def convert_comments(comments)
184
- comments.map { |comment| "*#{comment}\n" }.join
185
- end
186
-
187
- def convert_forks(forks, index)
188
- result = "\n"
189
- result = "変化:%4d手\n"%[index]
190
- forks.each do |moves|
191
- result += convert_moves(moves, index)
192
- end
193
- result
194
- end
195
-
196
- def convert_board_piece(piece)
197
- result = ''
198
-
199
- if piece == {}
200
- result = ' ・'
201
- else
202
- result += piece['color'] == 0 ? ' ' : 'v'
203
- result += csa2kind(piece['kind'])
204
- end
205
-
206
- result
207
- end
208
-
209
- def convert_motigoma(pieces)
210
- pieces.to_a.reverse.map do |piece, num|
211
- if num > 0
212
- str = csa2kind(piece)
213
- if num > 1
214
- str += n2kan(num/10) if num / 10 > 0
215
- num %= 10
216
- str += n2kan(num)
217
- end
218
- str
219
- else
220
- nil
221
- end
222
- end.compact.join(' ') + " \n"
223
- end
224
-
225
- protected
226
-
227
- def n2zen(n)
228
- "0123456789"[n]
229
- end
230
-
231
- def n2kan(n)
232
- "〇一二三四五六七八九"[n]
233
- end
234
-
235
- def csa2kind(csa)
236
- {
237
- "FU" => "歩",
238
- "KY" => "香",
239
- "KE" => "桂",
240
- "GI" => "銀",
241
- "KI" => "金",
242
- "KA" => "角",
243
- "HI" => "飛",
244
- "OU" => "玉",
245
- "TO" => "と",
246
- "NY" => "成香",
247
- "NK" => "成桂",
248
- "NG" => "成銀",
249
- "UM" => "馬",
250
- "RY" => "龍",
251
- }[csa]
252
- end
253
-
254
- def preset2str(preset)
255
- {
256
- "HIRATE" => "平手",
257
- "KY" => "香落ち",
258
- "KY_R" => "右香落ち",
259
- "KA" => "角落ち",
260
- "HI" => "飛車落ち",
261
- "HIKY" => "飛香落ち",
262
- "2" => "二枚落ち",
263
- "3" => "三枚落ち",
264
- "4" => "四枚落ち",
265
- "5" => "五枚落ち",
266
- "5_L" => "左五枚落ち",
267
- "6" => "六枚落ち",
268
- "8" => "八枚落ち",
269
- "10" => "十枚落ち",
270
- "OTHER" => "その他"
271
- }[preset]
272
- end
273
-
274
93
  def special2kan(special)
275
94
  case special
276
- when "CHUDAN" then "中断"
277
- when "TORYO" then "投了"
278
- when "JISHOGI" then "持将棋"
279
- when "SENNICHITE" then "千日手"
280
- when "TSUMI" then "詰み"
281
- when "FUZUMI" then "不詰"
282
- when "TIME_UP" then "切れ負け"
95
+ when "CHUDAN" then "中断"
96
+ when "TORYO" then "投了"
97
+ when "JISHOGI" then "持将棋"
98
+ when "SENNICHITE" then "千日手"
99
+ when "TSUMI" then "詰み"
100
+ when "FUZUMI" then "不詰"
101
+ when "TIME_UP" then "切れ負け"
283
102
  when "ILLEGAL_ACTION" then "反則勝ち"
284
- when "ILLEGAL_MOVE" then "反則負け"
103
+ when "ILLEGAL_MOVE" then "反則負け"
285
104
  end
286
105
  end
287
106
 
288
107
  def ljust(str, n)
289
108
  len = 0
290
109
  str.each_codepoint { |codepoint| len += codepoint > 255 ? 2 : 1 }
291
- str + ' '*(n-len)
110
+ str + " " * (n - len)
111
+ end
112
+
113
+ def pos2str(pos)
114
+ "%d%d" % [pos["x"], pos["y"]]
292
115
  end
293
116
  end
294
117
  end