jkf 0.4.0 → 0.4.1

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