qi 10.0.0.beta10 → 10.0.0.beta11
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 +9 -11
- data/lib/qi.rb +155 -149
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79ffab5e654d14cf9f3f7dac1c50bc5b5c612452d0fdea35a00d3529337fbff2
|
4
|
+
data.tar.gz: b8fecf9ff5dd97923070809b6a906c8b44cebbee9695ea242e314d53afb9fad8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb36bd477ba3e756b116e3f2ab55bdb15ea50834461cc614865d8fdda56e271eff4675d998172bd766b8ca33e6944be3bbf567a1eba96b6215816234c485f6c9
|
7
|
+
data.tar.gz: e56b5f73bf2c0a1a3a256f813acfcf24af3bc3cdd570f2fb6ab1aa2f7ebc194ddd0b82e5ade5cbc052229377a8c768d3f49f45188d811a756ab7781481c69f08
|
data/README.md
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
Add this line to your application's Gemfile:
|
14
14
|
|
15
15
|
```ruby
|
16
|
-
gem "qi", ">= 10.0.0.
|
16
|
+
gem "qi", ">= 10.0.0.beta11"
|
17
17
|
```
|
18
18
|
|
19
19
|
And then execute:
|
@@ -38,39 +38,37 @@ north_captures = %w[r r b g g g g s n n n n p p p p p p p p p p p p p p p p p]
|
|
38
38
|
south_captures = %w[S]
|
39
39
|
squares = { 3 => "s", 4 => "k", 5 => "s", 22 => "+P", 43 => "+B" }
|
40
40
|
|
41
|
-
qi0 = Qi.new(is_north_turn, north_captures, south_captures, squares
|
41
|
+
qi0 = Qi.new(is_north_turn, north_captures, south_captures, squares)
|
42
42
|
|
43
43
|
qi0.north_captures # => ["b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"]
|
44
44
|
qi0.south_captures # => ["S"]
|
45
45
|
qi0.squares # => {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"}
|
46
46
|
qi0.north_turn? # => false
|
47
47
|
qi0.south_turn? # => true
|
48
|
-
qi0.serialize # => "South-turn===
|
49
|
-
qi0.inspect # => "<Qi South-turn===
|
50
|
-
|
48
|
+
qi0.serialize # => "South-turn===b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s,S===3:s,4:k,5:s,22:+P,43:+B"
|
49
|
+
qi0.inspect # => "<Qi South-turn===b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s,S===3:s,4:k,5:s,22:+P,43:+B>"
|
51
50
|
qi0.to_a
|
52
51
|
# [false,
|
53
52
|
# ["b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"],
|
54
53
|
# ["S"],
|
55
54
|
# {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"},
|
56
|
-
#
|
55
|
+
# {}]
|
57
56
|
|
58
|
-
qi1 = qi0.commit(
|
57
|
+
qi1 = qi0.commit(43, 13, "+B", nil)
|
59
58
|
|
60
59
|
qi1.north_captures # => ["b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"]
|
61
60
|
qi1.south_captures # => ["S"]
|
62
61
|
qi1.squares # => {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}
|
63
62
|
qi1.north_turn? # => true
|
64
63
|
qi1.south_turn? # => false
|
65
|
-
qi1.serialize # => "North-turn===
|
66
|
-
qi1.inspect # => "<Qi North-turn===
|
67
|
-
|
64
|
+
qi1.serialize # => "North-turn===b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s,S===3:s,4:k,5:s,13:+B,22:+P"
|
65
|
+
qi1.inspect # => "<Qi North-turn===b,g,g,g,g,n,n,n,n,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,p,r,r,s,S===3:s,4:k,5:s,13:+B,22:+P>"
|
68
66
|
qi1.to_a
|
69
67
|
# [true,
|
70
68
|
# ["b", "g", "g", "g", "g", "n", "n", "n", "n", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "p", "r", "r", "s"],
|
71
69
|
# ["S"],
|
72
70
|
# {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"},
|
73
|
-
#
|
71
|
+
# {}]
|
74
72
|
```
|
75
73
|
|
76
74
|
## License
|
data/lib/qi.rb
CHANGED
@@ -3,69 +3,84 @@
|
|
3
3
|
require "digest"
|
4
4
|
require_relative "qi/error/drop"
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
8
|
-
# Additionally, it maintains information about the current game turn (which player's turn it is) and whether a player is in check.
|
6
|
+
# Qi is a class for representing a state of games like Shogi. It includes
|
7
|
+
# information about the current turn, captures, game board, and other game options.
|
9
8
|
class Qi
|
10
|
-
#
|
11
|
-
North =
|
9
|
+
# Constants for representing the North and South players.
|
10
|
+
North = :North
|
11
|
+
South = :South
|
12
12
|
|
13
|
-
#
|
14
|
-
South = "South"
|
15
|
-
|
16
|
-
# @!attribute [r] north_captures
|
17
|
-
# @return [Array] The list of pieces captured by the North player.
|
13
|
+
# @return [Array] the pieces captured by the north player
|
18
14
|
attr_reader :north_captures
|
19
15
|
|
20
|
-
#
|
21
|
-
# @return [Array] The list of pieces captured by the South player.
|
16
|
+
# @return [Array] the pieces captured by the south player
|
22
17
|
attr_reader :south_captures
|
23
18
|
|
24
|
-
#
|
25
|
-
# @return [Hash] The current state of the board, represented as a hash where each key is a position and each value is the state of that position.
|
19
|
+
# @return [Hash] the current state of the game board
|
26
20
|
attr_reader :squares
|
27
21
|
|
28
|
-
#
|
29
|
-
|
30
|
-
|
31
|
-
#
|
32
|
-
#
|
33
|
-
# @
|
34
|
-
#
|
35
|
-
|
22
|
+
# @return [Hash] additional game options
|
23
|
+
attr_reader :options
|
24
|
+
|
25
|
+
# Initialize a new Qi object.
|
26
|
+
#
|
27
|
+
# @example Creating a new Qi object
|
28
|
+
# qi = Qi.new(true, ['P', 'G'], ['B', '+B'], {56 => 'P', 3 => 'g', 64 => '+B'}, fullmove_number: 42, is_in_check: false)
|
29
|
+
#
|
30
|
+
# @param [Boolean] is_north_turn true if it's the north player's turn, false otherwise
|
31
|
+
# @param [Array] north_captures the pieces captured by the north player
|
32
|
+
# @param [Array] south_captures the pieces captured by the south player
|
33
|
+
# @param [Hash] squares the current state of the game board
|
34
|
+
# @param [Hash] options additional game options
|
35
|
+
def initialize(is_north_turn, north_captures, south_captures, squares, **options)
|
36
36
|
@is_north_turn = is_north_turn
|
37
37
|
@north_captures = north_captures.sort
|
38
38
|
@south_captures = south_captures.sort
|
39
39
|
@squares = squares.compact
|
40
|
-
@
|
40
|
+
@options = options
|
41
41
|
end
|
42
42
|
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
# @param
|
49
|
-
# @param
|
50
|
-
# @
|
51
|
-
# @
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
43
|
+
# Apply a move or a drop on the board.
|
44
|
+
#
|
45
|
+
# The method creates a new instance of Qi representing the state of the game after the move.
|
46
|
+
# This includes updating the captures and the positions of the pieces on the board.
|
47
|
+
#
|
48
|
+
# @param src_square [Object, nil] the source square, or nil if dropping a piece from hand
|
49
|
+
# @param dst_square [Object] the destination square
|
50
|
+
# @param piece_name [String] the name of the piece to move
|
51
|
+
# @param in_hand [String, nil] the piece in hand, or nil if moving a piece from a square
|
52
|
+
# @param options [Hash] options to pass to the new instance
|
53
|
+
#
|
54
|
+
# @example Applying a move
|
55
|
+
# qi = Qi.new(true, ['P', 'B'], ['G', '+B'], {56 => 'P', 64 => '+B'})
|
56
|
+
# qi.commit(56, 47, 'P', nil) #=> <Qi South-turn===B,P,+B,G===47:P,64:+B>
|
57
|
+
#
|
58
|
+
# @example Applying a capture
|
59
|
+
# qi = Qi.new(true, ['P', 'B'], ['G', '+B'], {56 => 'P', 64 => '+B'})
|
60
|
+
# qi.commit(56, 47, 'P', 'G') #=> <Qi South-turn===B,G,P,+B,G===47:P,64:+B>
|
61
|
+
#
|
62
|
+
# @example Applying a drop
|
63
|
+
# qi = Qi.new(true, ['P', 'B', 'G'], ['G', '+B'], {56 => 'P', 64 => '+B'})
|
64
|
+
# qi.commit(nil, 47, 'G', 'G') #=> <Qi South-turn===B,P,+B,G===47:G,56:P,64:+B>
|
65
|
+
#
|
66
|
+
# @return [Qi] the new game state after the move
|
67
|
+
def commit(src_square, dst_square, piece_name, in_hand, **options)
|
68
|
+
raise ::ArgumentError, "Both src_square and in_hand cannot be nil" if src_square.nil? && in_hand.nil?
|
58
69
|
|
59
|
-
|
60
|
-
|
61
|
-
self.class.new(south_turn?, *modified_captures, modified_squares,
|
70
|
+
modified_captures = update_captures(src_square, in_hand)
|
71
|
+
modified_squares = squares.merge({ src_square => nil, dst_square => piece_name })
|
72
|
+
self.class.new(south_turn?, *modified_captures, modified_squares, **options)
|
62
73
|
end
|
63
74
|
|
64
|
-
#
|
65
|
-
#
|
75
|
+
# Compare this Qi object with another for equality.
|
76
|
+
#
|
77
|
+
# @example Comparing two Qi objects
|
78
|
+
# qi1 = Qi.new(...)
|
79
|
+
# qi2 = Qi.new(...)
|
80
|
+
# qi1.eql?(qi2) #=> true or false
|
66
81
|
#
|
67
|
-
# @param
|
68
|
-
# @return [Boolean]
|
82
|
+
# @param [Qi] other the other Qi object to compare with
|
83
|
+
# @return [Boolean] true if the two objects represent the same game state, false otherwise
|
69
84
|
def eql?(other)
|
70
85
|
return false unless other.respond_to?(:serialize)
|
71
86
|
|
@@ -73,171 +88,155 @@ class Qi
|
|
73
88
|
end
|
74
89
|
alias == eql?
|
75
90
|
|
76
|
-
#
|
91
|
+
# Get the captures of the current player.
|
92
|
+
#
|
93
|
+
# The method returns the north player's captures when it's their turn,
|
94
|
+
# and the south player's captures when it's their turn.
|
95
|
+
#
|
96
|
+
# @example When it's the north player's turn
|
97
|
+
# qi = Qi.new(true, ['P', 'B'], ['G', '+B'], {56 => 'P', 64 => '+B'})
|
98
|
+
# qi.current_captures #=> ['B', 'P']
|
99
|
+
#
|
100
|
+
# @example When it's the south player's turn
|
101
|
+
# qi = Qi.new(false, ['P', 'B'], ['G', '+B'], {56 => 'P', 64 => '+B'})
|
102
|
+
# qi.current_captures #=> ['+B', 'G']
|
77
103
|
#
|
78
|
-
# @return [Array]
|
104
|
+
# @return [Array] the captures of the current player
|
79
105
|
def current_captures
|
80
|
-
|
81
|
-
north_captures
|
82
|
-
else
|
83
|
-
south_captures
|
84
|
-
end
|
106
|
+
north_turn? ? north_captures : south_captures
|
85
107
|
end
|
86
108
|
|
87
|
-
#
|
109
|
+
# Get the captures of the opponent player.
|
88
110
|
#
|
89
|
-
# @return [Array]
|
111
|
+
# @return [Array] the captures of the opponent player
|
90
112
|
def opponent_captures
|
91
|
-
|
92
|
-
south_captures
|
93
|
-
else
|
94
|
-
north_captures
|
95
|
-
end
|
113
|
+
north_turn? ? south_captures : north_captures
|
96
114
|
end
|
97
115
|
|
98
|
-
#
|
116
|
+
# Get the current turn.
|
99
117
|
#
|
100
|
-
# @return [
|
118
|
+
# @return [Symbol] :North if it's the north player's turn, :South otherwise
|
101
119
|
def current_turn
|
102
|
-
|
103
|
-
North
|
104
|
-
else
|
105
|
-
South
|
106
|
-
end
|
120
|
+
north_turn? ? North : South
|
107
121
|
end
|
108
122
|
|
109
|
-
#
|
110
|
-
# If it's currently the North player's turn, this method will return "South", and vice versa.
|
123
|
+
# Get the next turn.
|
111
124
|
#
|
112
|
-
# @return [
|
125
|
+
# @return [Symbol] :South if it's the north player's turn, :North otherwise
|
113
126
|
def next_turn
|
114
|
-
|
115
|
-
South
|
116
|
-
else
|
117
|
-
North
|
118
|
-
end
|
127
|
+
north_turn? ? South : North
|
119
128
|
end
|
120
129
|
|
121
|
-
#
|
130
|
+
# Check if it's the north player's turn.
|
122
131
|
#
|
123
|
-
# @return [Boolean]
|
132
|
+
# @return [Boolean] true if it's the north player's turn, false otherwise
|
124
133
|
def north_turn?
|
125
134
|
@is_north_turn
|
126
135
|
end
|
127
136
|
|
128
|
-
#
|
137
|
+
# Check if it's the south player's turn.
|
129
138
|
#
|
130
|
-
# @return [Boolean]
|
139
|
+
# @return [Boolean] true if it's the south player's turn, false otherwise
|
131
140
|
def south_turn?
|
132
141
|
!north_turn?
|
133
142
|
end
|
134
143
|
|
135
|
-
#
|
144
|
+
# Convert the state to an array.
|
136
145
|
#
|
137
|
-
# @
|
138
|
-
|
139
|
-
@is_in_check
|
140
|
-
end
|
141
|
-
|
142
|
-
# Checks if the current player is not in check.
|
146
|
+
# @example Converting the state to an array
|
147
|
+
# qi.to_a #=> [true, ['P', 'G'], ['B', '+B'], {56 => 'P', 3 => 'g', 64 => '+B'}, {}]
|
143
148
|
#
|
144
|
-
# @return [
|
145
|
-
def not_in_check?
|
146
|
-
!in_check?
|
147
|
-
end
|
148
|
-
|
149
|
-
# Converts the current game state to an array. The resulting array includes:
|
150
|
-
# whether it's North's turn, the pieces captured by North, the pieces captured by South,
|
151
|
-
# the state of the squares, and whether the current player is in check.
|
152
|
-
# This array can be used for various purposes, such as saving the game state,
|
153
|
-
# transmitting the game state over a network, or analyzing the game state.
|
154
|
-
#
|
155
|
-
# @return [Array] The game state, represented as an array. The elements of the array are:
|
156
|
-
# - A boolean indicating whether it's North's turn,
|
157
|
-
# - An array or other iterable representing the pieces captured by North,
|
158
|
-
# - An array or other iterable representing the pieces captured by South,
|
159
|
-
# - A data structure representing the state of the squares on the board,
|
160
|
-
# - A boolean indicating whether the current player is in check.
|
149
|
+
# @return [Array] an array representing the game state
|
161
150
|
def to_a
|
162
151
|
[
|
163
152
|
north_turn?,
|
164
153
|
north_captures,
|
165
154
|
south_captures,
|
166
155
|
squares,
|
167
|
-
|
156
|
+
options
|
168
157
|
]
|
169
158
|
end
|
170
159
|
|
171
|
-
#
|
172
|
-
#
|
173
|
-
#
|
174
|
-
#
|
175
|
-
#
|
176
|
-
#
|
177
|
-
# @return [Hash] The game state, represented as a hash. The keys of the hash are:
|
178
|
-
# - :is_north_turn, a boolean indicating whether it's North's turn,
|
179
|
-
# - :north_captures, an array or other iterable representing the pieces captured by North,
|
180
|
-
# - :south_captures, an array or other iterable representing the pieces captured by South,
|
181
|
-
# - :squares, a data structure representing the state of the squares on the board,
|
182
|
-
# - :is_in_check, a boolean indicating whether the current player is in check.
|
160
|
+
# Convert the state to a hash.
|
161
|
+
#
|
162
|
+
# @example Converting the state to a hash
|
163
|
+
# qi.to_h #=> {is_north_turn: true, north_captures: ['P', 'G'], south_captures: ['B', '+B'], squares: {56 => 'P', 3 => 'g', 64 => '+B'}, options: {}}
|
164
|
+
#
|
165
|
+
# @return [Hash] a hash representing the game state
|
183
166
|
def to_h
|
184
167
|
{
|
185
168
|
is_north_turn: north_turn?,
|
186
169
|
north_captures:,
|
187
170
|
south_captures:,
|
188
171
|
squares:,
|
189
|
-
|
172
|
+
options:
|
190
173
|
}
|
191
174
|
end
|
192
175
|
|
193
|
-
#
|
176
|
+
# Generate a hash value for the game state.
|
177
|
+
#
|
178
|
+
# @example Generating a hash value
|
179
|
+
# qi.hash #=> "10dfb778f6559dd368c510a27e3b00bdb5b4ad88d4d67f38864d7e36de7c2f9c"
|
180
|
+
#
|
181
|
+
# @return [String] a SHA256 hash of the serialized game state
|
194
182
|
def hash
|
195
183
|
::Digest::SHA256.hexdigest(serialize)
|
196
184
|
end
|
197
185
|
|
198
|
-
#
|
186
|
+
# Serialize the game state.
|
199
187
|
#
|
200
|
-
# @
|
201
|
-
|
202
|
-
squares.keys.sort
|
203
|
-
end
|
204
|
-
|
205
|
-
# Serialize the current game state to a string. The serialized state includes:
|
206
|
-
# the current turn, the captured pieces, the state of the squares, and whether
|
207
|
-
# the current player is in check. The serialized state can be used to save
|
208
|
-
# the game, or to transmit the game state over a network.
|
188
|
+
# @example Serializing the game state
|
189
|
+
# qi.serialize #=> "North-turn===P,G,B,+B===3:g,56:P,64:+B"
|
209
190
|
#
|
210
|
-
# @return [String]
|
191
|
+
# @return [String] a string representation of the game state
|
211
192
|
def serialize
|
212
193
|
serialized_turn = "#{current_turn}-turn"
|
213
|
-
serialized_captures = (north_captures + south_captures).
|
214
|
-
serialized_squares =
|
215
|
-
serialized_check = (in_check? ? "in-check" : "not-in-check")
|
194
|
+
serialized_captures = (north_captures + south_captures).join(",")
|
195
|
+
serialized_squares = squares.keys.sort.map { |i| "#{i}:#{squares.fetch(i)}" }.join(",")
|
216
196
|
|
217
|
-
"#{serialized_turn}===#{serialized_captures}===#{serialized_squares}
|
197
|
+
"#{serialized_turn}===#{serialized_captures}===#{serialized_squares}"
|
218
198
|
end
|
219
199
|
|
220
|
-
#
|
200
|
+
# Provide a string representation of the game state for debugging.
|
201
|
+
#
|
202
|
+
# @example Getting a string representation of the game state
|
203
|
+
# qi.inspect #=> "<Qi North-turn===P,G,B,+B===3:g,56:P,64:+B>"
|
221
204
|
#
|
222
|
-
# @return [String]
|
205
|
+
# @return [String] a string representation of the game state
|
223
206
|
def inspect
|
224
207
|
"<#{self.class} #{serialize}>"
|
225
208
|
end
|
226
209
|
|
227
210
|
private
|
228
211
|
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
#
|
234
|
-
#
|
235
|
-
#
|
236
|
-
#
|
237
|
-
|
212
|
+
# Update captures based on the source square and the piece in hand.
|
213
|
+
#
|
214
|
+
# If the source square is not nil and in_hand is nil (i.e., we're moving a piece on the board),
|
215
|
+
# the captures remain the same. If the source square is not nil and in_hand is not nil
|
216
|
+
# (i.e., we're capturing a piece that will remain in hand), the piece is added to the
|
217
|
+
# current player's captures. If the source square is nil (i.e., we're dropping a piece from hand),
|
218
|
+
# the piece is removed from the current player's captures.
|
219
|
+
#
|
220
|
+
# @param src_square [Object, nil] the source square, or nil if dropping a piece from hand
|
221
|
+
# @param in_hand [String, nil] the piece in hand, or nil if moving a piece from a square
|
222
|
+
#
|
223
|
+
# @example When moving a piece on the board
|
224
|
+
# qi = Qi.new(true, ['P', 'B'], ['G', '+B'], {56 => 'P', 64 => '+B'})
|
225
|
+
# qi.send(:update_captures, 56, nil) #=> [['B', 'P'], ['G', '+B']]
|
226
|
+
#
|
227
|
+
# @example When capturing a piece that will remain in hand
|
228
|
+
# qi = Qi.new(true, ['P', 'B'], ['G', '+B'], {56 => 'P', 64 => '+B'})
|
229
|
+
# qi.send(:update_captures, 56, 'G') #=> [['B', 'P', 'G'], ['G', '+B']]
|
230
|
+
#
|
231
|
+
# @example When dropping a piece from hand
|
232
|
+
# qi = Qi.new(true, ['P', 'B', 'G'], ['G', '+B'], {56 => 'P', 64 => '+B'})
|
233
|
+
# qi.send(:update_captures, nil, 'G') #=> [['B', 'P'], ['G', '+B']]
|
234
|
+
#
|
235
|
+
# @return [Array] a two-element array with the updated north and south captures
|
236
|
+
def update_captures(src_square, in_hand)
|
238
237
|
return [north_captures, south_captures] if in_hand.nil?
|
239
238
|
|
240
|
-
captures = if
|
239
|
+
captures = if src_square.nil?
|
241
240
|
remove_from_captures(in_hand, *current_captures)
|
242
241
|
else
|
243
242
|
current_captures + [in_hand]
|
@@ -247,12 +246,19 @@ class Qi
|
|
247
246
|
end
|
248
247
|
|
249
248
|
# Removes a piece from the captures.
|
250
|
-
# The method raises an error if the piece is not found in the captures.
|
251
249
|
#
|
252
|
-
#
|
253
|
-
#
|
254
|
-
# @
|
255
|
-
# @
|
250
|
+
# If the piece is not found in the captures, an Error::Drop exception is raised.
|
251
|
+
#
|
252
|
+
# @param piece [String] the piece to remove from the captures
|
253
|
+
# @param captures [Array] the captures to update
|
254
|
+
#
|
255
|
+
# @example
|
256
|
+
# qi = Qi.new(true, ['P', 'B', 'G'], ['G', '+B'], {56 => 'P', 64 => '+B'})
|
257
|
+
# qi.send(:remove_from_captures, 'G', *qi.current_captures) #=> ['P', 'B']
|
258
|
+
#
|
259
|
+
# @raise [Error::Drop] if the piece is not found in the captures
|
260
|
+
#
|
261
|
+
# @return [Array] the captures after removing the piece
|
256
262
|
def remove_from_captures(piece, *captures)
|
257
263
|
index = captures.rindex(piece)
|
258
264
|
raise Error::Drop, "There are no #{piece} in hand" if index.nil?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: qi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 10.0.0.
|
4
|
+
version: 10.0.0.beta11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyril Kato
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05-
|
11
|
+
date: 2023-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: An abstraction that could help to update positions for games like Shogi.
|
14
14
|
email: contact@cyril.email
|