shogi-ruby 0.0.1 → 0.0.2
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/README.md +0 -1
- data/lib/shogi/board.rb +85 -16
- data/lib/shogi/version.rb +1 -1
- data/test/test-board.rb +106 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 469ae5eee31baa8c42df5bf289836bbc8656ef35
|
4
|
+
data.tar.gz: 987b2fd2abe8c56684eb1039bbdf5498a8909ffe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3c4248c0be25827324230f8cde9d3f04a08c5e1d82344cb2ad6a4508eb9da1bae16222980129e9e86b22eed971c3face6e3de28a8613209f253fd0adce003fd3
|
7
|
+
data.tar.gz: 1ddb6295dabc9ad55c97d9471060e6674cffce6d6bd2503f8954d935a840dc5c870be07fd29776846a4ccdd7bb66aa5f397a09a9acdbb016dcdf6fe998a9e975
|
data/README.md
CHANGED
data/lib/shogi/board.rb
CHANGED
@@ -1,11 +1,21 @@
|
|
1
1
|
module Shogi
|
2
2
|
class Board
|
3
|
-
class Error
|
4
|
-
end
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
3
|
+
class Error < StandardError; end
|
4
|
+
class CodingError < Error; end
|
5
|
+
class FormatError < Error; end
|
6
|
+
class UndefinedPieceError < Error; end
|
7
|
+
class MoveError < Error; end
|
8
|
+
class MovementError < Error; end
|
9
|
+
|
10
|
+
attr_accessor :validate_movement
|
11
|
+
def initialize(csa=nil)
|
12
|
+
if csa
|
13
|
+
set_from_csa(csa)
|
14
|
+
else
|
15
|
+
@position = default_position
|
16
|
+
@captured = []
|
17
|
+
end
|
18
|
+
@validate_movement = true
|
9
19
|
end
|
10
20
|
|
11
21
|
def to_csa
|
@@ -38,6 +48,37 @@ module Shogi
|
|
38
48
|
csa_rows
|
39
49
|
end
|
40
50
|
|
51
|
+
def set_from_csa(csa)
|
52
|
+
position = []
|
53
|
+
cell_pattern = '[+-][A-Z]{2}| \* '
|
54
|
+
csa_lines = csa.each_line.to_a
|
55
|
+
csa_lines.slice(0, 9).to_enum.with_index do |row, i|
|
56
|
+
position_row = []
|
57
|
+
row.chomp!
|
58
|
+
unless /\AP#{i + 1}(#{cell_pattern}){9}\z/ =~ row
|
59
|
+
raise FormatError, "Format Error: line #{i + 1}"
|
60
|
+
end
|
61
|
+
row[2..28].scan(/#{cell_pattern}/) do |cell|
|
62
|
+
position_row << cell
|
63
|
+
end
|
64
|
+
position << position_row
|
65
|
+
end
|
66
|
+
@position = position
|
67
|
+
|
68
|
+
captured = []
|
69
|
+
csa_lines.slice(9, 2).each do |captured_line|
|
70
|
+
captured_line.chomp!
|
71
|
+
unless /\AP[+-](00[A-Z]{2})*\z/ =~ captured_line
|
72
|
+
raise FormatError, "Format Error: captured line"
|
73
|
+
end
|
74
|
+
turn = captured_line[1]
|
75
|
+
captured_line[2..-1].scan(/00([A-Z]{2})/) do |cell|
|
76
|
+
captured << turn + cell[0]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
@captured = captured
|
80
|
+
end
|
81
|
+
|
41
82
|
def to_usi
|
42
83
|
@position.map {|row|
|
43
84
|
usi_row = ""
|
@@ -68,17 +109,17 @@ module Shogi
|
|
68
109
|
|
69
110
|
def move_from_csa(csa)
|
70
111
|
unless /\A[+-](00|[1-9]{2})[1-9]{2}[A-Z]{2}\z/ =~ csa
|
71
|
-
raise
|
112
|
+
raise FormatError, "Wrong CSA format: #{csa}"
|
72
113
|
end
|
73
114
|
|
74
115
|
unless Piece.const_defined?(csa[5..6])
|
75
|
-
raise
|
116
|
+
raise UndefinedPieceError, "Undefined piece: #{csa[5..6]}"
|
76
117
|
end
|
77
118
|
|
78
119
|
if csa[1..2] == "00"
|
79
120
|
before_piece = csa[0] + csa[5..6]
|
80
121
|
unless @captured.include?(before_piece)
|
81
|
-
|
122
|
+
raise MoveError, "Not captured piece: #{csa}"
|
82
123
|
end
|
83
124
|
before_cell = before_piece
|
84
125
|
before_piece = eval("Piece::#{before_cell[1..2]}").new
|
@@ -86,16 +127,29 @@ module Shogi
|
|
86
127
|
before_x = 9 - csa[1].to_i
|
87
128
|
before_y = csa[2].to_i - 1
|
88
129
|
before_cell = @position[before_y][before_x]
|
89
|
-
|
130
|
+
if before_cell == ""
|
131
|
+
raise MoveError, "Before cell is blank"
|
132
|
+
end
|
90
133
|
before_piece = eval("Piece::#{before_cell[1..2]}").new
|
91
134
|
|
92
135
|
unless csa[0] == before_cell[0]
|
93
|
-
|
136
|
+
raise MoveError, "Don't your piece: #{before_cell}"
|
94
137
|
end
|
95
138
|
unless csa[5..6] == before_cell[1..2]
|
96
139
|
after_piece = eval("Piece::#{csa[5..6]}").new
|
97
140
|
unless before_piece.promoter == after_piece.class
|
98
|
-
|
141
|
+
raise MoveError, "Don't promote: #{before_cell[1..2]} -> #{csa[5..6]}"
|
142
|
+
end
|
143
|
+
|
144
|
+
after_y = csa[4].to_i - 1
|
145
|
+
if csa[0] == "+"
|
146
|
+
unless after_y < 3 || before_y < 3
|
147
|
+
raise_movement_error("Don't promote line: #{csa}")
|
148
|
+
end
|
149
|
+
else
|
150
|
+
unless after_y > 6 || before_y > 6
|
151
|
+
raise_movement_error("Don't promote line: #{csa}")
|
152
|
+
end
|
99
153
|
end
|
100
154
|
end
|
101
155
|
end
|
@@ -104,11 +158,13 @@ module Shogi
|
|
104
158
|
after_y = csa[4].to_i - 1
|
105
159
|
after_cell = @position[after_y][after_x]
|
106
160
|
if csa[0] == after_cell[0]
|
107
|
-
|
161
|
+
raise MoveError, "Your piece on after cell: #{csa}"
|
108
162
|
end
|
109
163
|
|
110
164
|
if csa[1..2] == "00"
|
111
|
-
|
165
|
+
unless after_cell == ""
|
166
|
+
raise MoveError, "Exist piece on after cell"
|
167
|
+
end
|
112
168
|
else
|
113
169
|
if csa[0] == "+"
|
114
170
|
movement_x = after_x - before_x
|
@@ -119,7 +175,7 @@ module Shogi
|
|
119
175
|
end
|
120
176
|
|
121
177
|
unless before_piece.move?(movement_x, movement_y)
|
122
|
-
|
178
|
+
raise_movement_error("Invalid movement")
|
123
179
|
end
|
124
180
|
end
|
125
181
|
|
@@ -144,7 +200,7 @@ module Shogi
|
|
144
200
|
end
|
145
201
|
|
146
202
|
unless used == before_cell
|
147
|
-
raise
|
203
|
+
raise CodingError, "[Bug] missing piece in captured"
|
148
204
|
end
|
149
205
|
else
|
150
206
|
@position[before_y][before_x] = ""
|
@@ -153,6 +209,13 @@ module Shogi
|
|
153
209
|
true
|
154
210
|
end
|
155
211
|
|
212
|
+
def move_from_csa_lines(csa_lines)
|
213
|
+
csa_lines.each_line do |csa|
|
214
|
+
csa.chomp!
|
215
|
+
move_from_csa(csa)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
156
219
|
private
|
157
220
|
def default_position
|
158
221
|
[["-KY", "-KE", "-GI", "-KI", "-OU", "-KI", "-GI", "-KE", "-KY"],
|
@@ -165,5 +228,11 @@ module Shogi
|
|
165
228
|
[ "", "+KA", "", "", "", "", "", "+HI", ""],
|
166
229
|
["+KY", "+KE", "+GI", "+KI", "+OU", "+KI", "+GI", "+KE", "+KY"]]
|
167
230
|
end
|
231
|
+
|
232
|
+
def raise_movement_error(message)
|
233
|
+
if @validate_movement
|
234
|
+
raise MovementError, message
|
235
|
+
end
|
236
|
+
end
|
168
237
|
end
|
169
238
|
end
|
data/lib/shogi/version.rb
CHANGED
data/test/test-board.rb
CHANGED
@@ -11,6 +11,24 @@ class BoardTest < Test::Unit::TestCase
|
|
11
11
|
assert_true(rows.all? {|row| row.size == 9 })
|
12
12
|
end
|
13
13
|
|
14
|
+
def test_initialize_csa
|
15
|
+
csa = <<-EOT
|
16
|
+
P1 * * * * +HI * * -KE *
|
17
|
+
P2 * * * * * +KA-OU * -KY
|
18
|
+
P3 * * * * * * -FU-FU-FU
|
19
|
+
P4 * * * * +KY * * -GI *
|
20
|
+
P5 * * * * * * * * *
|
21
|
+
P6 * * * * * * * * *
|
22
|
+
P7 * * * * * * * * *
|
23
|
+
P8 * * * * * * * * *
|
24
|
+
P9 * * * * * * * * *
|
25
|
+
P+00HI00GI00KE
|
26
|
+
P-
|
27
|
+
EOT
|
28
|
+
@board = Shogi::Board.new(csa)
|
29
|
+
assert_equal(csa, @board.to_csa)
|
30
|
+
end
|
31
|
+
|
14
32
|
def test_to_csa
|
15
33
|
before_state = @board.instance_variable_get(:@position).dup
|
16
34
|
assert_equal(<<-EOT, @board.to_csa)
|
@@ -29,6 +47,24 @@ P-
|
|
29
47
|
assert_equal(before_state, @board.instance_variable_get(:@position))
|
30
48
|
end
|
31
49
|
|
50
|
+
def test_set_from_csa
|
51
|
+
csa = <<-EOT
|
52
|
+
P1 * * * * +HI * * -KE *
|
53
|
+
P2 * * * * * +KA-OU * -KY
|
54
|
+
P3 * * * * * * -FU-FU-FU
|
55
|
+
P4 * * * * +KY * * -GI *
|
56
|
+
P5 * * * * * * * * *
|
57
|
+
P6 * * * * * * * * *
|
58
|
+
P7 * * * * * * * * *
|
59
|
+
P8 * * * * * * * * *
|
60
|
+
P9 * * * * * * * * *
|
61
|
+
P+00HI00GI00KE
|
62
|
+
P-
|
63
|
+
EOT
|
64
|
+
@board.set_from_csa(csa)
|
65
|
+
assert_equal(csa, @board.to_csa)
|
66
|
+
end
|
67
|
+
|
32
68
|
def test_to_usi
|
33
69
|
before_state = @board.instance_variable_get(:@position).dup
|
34
70
|
assert_equal(<<-EOT, @board.to_usi)
|
@@ -38,17 +74,27 @@ lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL
|
|
38
74
|
end
|
39
75
|
|
40
76
|
def test_move_from_csa
|
41
|
-
assert_raise Shogi::Board::
|
77
|
+
assert_raise Shogi::Board::FormatError do
|
42
78
|
@board.move_from_csa("+27FU")
|
43
79
|
end
|
44
|
-
assert_raise Shogi::Board::
|
80
|
+
assert_raise Shogi::Board::UndefinedPieceError do
|
45
81
|
@board.move_from_csa("+2726AA")
|
46
82
|
end
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
83
|
+
assert_raise Shogi::Board::MoveError do
|
84
|
+
assert_false(@board.move_from_csa("+2726HI"))
|
85
|
+
end
|
86
|
+
assert_raise Shogi::Board::MoveError do
|
87
|
+
assert_false(@board.move_from_csa("+2827HI"))
|
88
|
+
end
|
89
|
+
assert_raise Shogi::Board::MoveError do
|
90
|
+
assert_false(@board.move_from_csa("+2625FU"))
|
91
|
+
end
|
92
|
+
assert_raise Shogi::Board::MovementError do
|
93
|
+
assert_false(@board.move_from_csa("+2725FU"))
|
94
|
+
end
|
95
|
+
assert_raise Shogi::Board::MoveError do
|
96
|
+
assert_false(@board.move_from_csa("-4131KI"))
|
97
|
+
end
|
52
98
|
assert_true(@board.move_from_csa("+7776FU"))
|
53
99
|
assert_true(@board.move_from_csa("-4132KI"))
|
54
100
|
assert_true(@board.move_from_csa("+2868HI"))
|
@@ -104,6 +150,9 @@ P-00KA
|
|
104
150
|
def test_move_from_csa_promote
|
105
151
|
@board.move_from_csa("+7776FU")
|
106
152
|
@board.move_from_csa("-3334FU")
|
153
|
+
assert_raise Shogi::Board::MovementError do
|
154
|
+
assert_false(@board.move_from_csa("+2726TO"))
|
155
|
+
end
|
107
156
|
assert_true(@board.move_from_csa("+8822UM"))
|
108
157
|
assert_equal(<<-EOT, @board.to_csa)
|
109
158
|
P1-KY-KE-GI-KI-OU-KI-GI-KE-KY
|
@@ -132,5 +181,55 @@ P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
|
|
132
181
|
P+00KA
|
133
182
|
P-00KA
|
134
183
|
EOT
|
184
|
+
assert_true(@board.move_from_csa("+0033KA"))
|
185
|
+
assert_true(@board.move_from_csa("-0078KA"))
|
186
|
+
assert_true(@board.move_from_csa("+3366UM"))
|
187
|
+
assert_true(@board.move_from_csa("-7867UM"))
|
188
|
+
assert_equal(<<-EOT, @board.to_csa)
|
189
|
+
P1-KY-KE-GI-KI-OU-KI * -KE-KY
|
190
|
+
P2 * -HI * * * * * -GI *
|
191
|
+
P3-FU-FU-FU-FU-FU-FU * -FU-FU
|
192
|
+
P4 * * * * * * -FU * *
|
193
|
+
P5 * * * * * * * * *
|
194
|
+
P6 * * +FU+UM * * * * *
|
195
|
+
P7+FU+FU * -UM+FU+FU+FU+FU+FU
|
196
|
+
P8 * * * * * * * +HI *
|
197
|
+
P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
|
198
|
+
P+
|
199
|
+
P-00FU
|
200
|
+
EOT
|
201
|
+
end
|
202
|
+
|
203
|
+
def test_move_from_csa_lines
|
204
|
+
csa_lines = <<-EOT
|
205
|
+
+7776FU
|
206
|
+
-3334FU
|
207
|
+
+8822KA
|
208
|
+
-3122GI
|
209
|
+
+0055KA
|
210
|
+
EOT
|
211
|
+
|
212
|
+
@board.move_from_csa_lines(csa_lines)
|
213
|
+
|
214
|
+
assert_equal(<<-EOT, @board.to_csa)
|
215
|
+
P1-KY-KE-GI-KI-OU-KI * -KE-KY
|
216
|
+
P2 * -HI * * * * * -GI *
|
217
|
+
P3-FU-FU-FU-FU-FU-FU * -FU-FU
|
218
|
+
P4 * * * * * * -FU * *
|
219
|
+
P5 * * * * +KA * * * *
|
220
|
+
P6 * * +FU * * * * * *
|
221
|
+
P7+FU+FU * +FU+FU+FU+FU+FU+FU
|
222
|
+
P8 * * * * * * * +HI *
|
223
|
+
P9+KY+KE+GI+KI+OU+KI+GI+KE+KY
|
224
|
+
P+
|
225
|
+
P-00KA
|
226
|
+
EOT
|
227
|
+
end
|
228
|
+
|
229
|
+
def test_validate_movement_false
|
230
|
+
assert_true(@board.validate_movement)
|
231
|
+
@board.validate_movement = false
|
232
|
+
assert_false(@board.validate_movement)
|
233
|
+
assert_true(@board.move_from_csa("+2755FU"))
|
135
234
|
end
|
136
235
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shogi-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masafumi Yokoyama
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-unit
|