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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e19666afd7c10c5196dd059f8fbd26b30051a95
4
- data.tar.gz: a7c9cd4003dbf8831220a4b80a610af89487586b
3
+ metadata.gz: 469ae5eee31baa8c42df5bf289836bbc8656ef35
4
+ data.tar.gz: 987b2fd2abe8c56684eb1039bbdf5498a8909ffe
5
5
  SHA512:
6
- metadata.gz: f51786284a2215ba437c801a2dcaae9a08b456d1d9227b1e0900b9325b74ed0bab0a6b080ae8789f6419585b015042f42f417dcf5df100048bacc96e97867cac
7
- data.tar.gz: 2f751b50e67375844d25ce241d5e819859adb7caf228d51f4c64832fe7e7a16f9da262a3350f3bbbeda6290f1ae64289bb284272e203d273e21e5e820a122b34
6
+ metadata.gz: 3c4248c0be25827324230f8cde9d3f04a08c5e1d82344cb2ad6a4508eb9da1bae16222980129e9e86b22eed971c3face6e3de28a8613209f253fd0adce003fd3
7
+ data.tar.gz: 1ddb6295dabc9ad55c97d9471060e6674cffce6d6bd2503f8954d935a840dc5c870be07fd29776846a4ccdd7bb66aa5f397a09a9acdbb016dcdf6fe998a9e975
data/README.md CHANGED
@@ -50,7 +50,6 @@ Ruby 2.0.0 or later. (and 1.9.3)
50
50
  P+
51
51
  P-
52
52
 
53
- board.move_from_csa("+7776FU")
54
53
  board.move_from_csa("-3334FU")
55
54
  board.move_from_csa("+8822UM")
56
55
  board.to_csa
data/lib/shogi/board.rb CHANGED
@@ -1,11 +1,21 @@
1
1
  module Shogi
2
2
  class Board
3
- class Error < StandardError
4
- end
5
-
6
- def initialize
7
- @position = default_position
8
- @captured = []
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 Error, "Format Error"
112
+ raise FormatError, "Wrong CSA format: #{csa}"
72
113
  end
73
114
 
74
115
  unless Piece.const_defined?(csa[5..6])
75
- raise Error, "No Defined Piece Error"
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
- return false
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
- return false if before_cell == ""
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
- return false
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
- return false
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
- return false
161
+ raise MoveError, "Your piece on after cell: #{csa}"
108
162
  end
109
163
 
110
164
  if csa[1..2] == "00"
111
- return false unless after_cell == ""
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
- return false
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 Error, "[Bug] missing piece in captured"
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
@@ -1,3 +1,3 @@
1
1
  module Shogi
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
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::Error do
77
+ assert_raise Shogi::Board::FormatError do
42
78
  @board.move_from_csa("+27FU")
43
79
  end
44
- assert_raise Shogi::Board::Error do
80
+ assert_raise Shogi::Board::UndefinedPieceError do
45
81
  @board.move_from_csa("+2726AA")
46
82
  end
47
- assert_false(@board.move_from_csa("+2726HI"))
48
- assert_false(@board.move_from_csa("+2827HI"))
49
- assert_false(@board.move_from_csa("+2625FU"))
50
- assert_false(@board.move_from_csa("+2725FU"))
51
- assert_false(@board.move_from_csa("-4131KI"))
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.1
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-13 00:00:00.000000000 Z
11
+ date: 2013-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit