qi 6.3.1 → 9.0.0.beta2
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/LICENSE.md +1 -1
- data/README.md +24 -319
- data/lib/qi.rb +44 -3
- data/lib/qi/action.rb +61 -0
- data/lib/qi/move.rb +46 -0
- metadata +54 -11
- data/lib/qi/position.rb +0 -182
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f66c9affa38d8e5dadfc596d5df81b47839187830d834600d624558d3643077e
|
4
|
+
data.tar.gz: fd345a4baeacbf22a0a898731dc26b19063727190a497a6d4cf779ca6275bf96
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f5ef7c30f20b03fb3a6712c8b14824b1878a0f706159973b9d5c0c6270092042e12a4ecc50254e99f8d6107466367f58d530d77489370b3a54437e8f31bf42bb
|
7
|
+
data.tar.gz: 9364870e925d1769e5c9d233bcc8acb626a0a9d70d62725eafda311a926bd6ed398cb5e0efbff71a09ca659bcfc5e67037126ee4c4cffaa7b79e2687dcc1f470
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,341 +1,50 @@
|
|
1
1
|
# Qi.rb
|
2
2
|
|
3
|
-
[](https://github.com/sashite/qi.rb/releases)
|
4
|
+
[](https://rubydoc.info/github/sashite/qi.rb/main)
|
5
|
+
[](https://github.com/sashite/qi.rb/actions?query=workflow%3Aci+branch%3Amain)
|
6
|
+
[](https://github.com/sashite/qi.rb/actions?query=workflow%3Arubocop+branch%3Amain)
|
7
|
+
[](https://github.com/sashite/qi.rb/raw/main/LICENSE.md)
|
7
8
|
|
8
|
-
> `Qi` (棋) is an abstraction for
|
9
|
+
> `Qi` (棋) is an abstraction for updating positions of chess variants (including Chess, Janggi, Markruk, Shogi, Xiangqi), with a move.
|
9
10
|
|
10
11
|
## Installation
|
11
12
|
|
12
13
|
Add this line to your application's Gemfile:
|
13
14
|
|
14
15
|
```ruby
|
15
|
-
gem "qi"
|
16
|
+
gem "qi", ">= 9.0.0.beta2"
|
16
17
|
```
|
17
18
|
|
18
19
|
And then execute:
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
Or install it yourself as:
|
23
|
-
|
24
|
-
$ gem install qi
|
25
|
-
|
26
|
-
## Examples
|
27
|
-
|
28
|
-
Let's replay [The Shortest Possible Game](https://userpages.monmouth.com/~colonel/shortshogi.html) of [Shogi](https://en.wikipedia.org/wiki/Shogi):
|
29
|
-
|
30
|
-
```ruby
|
31
|
-
require "qi"
|
32
|
-
|
33
|
-
starting_position = Qi::Position.new(
|
34
|
-
"l", "n", "s", "g", "k", "g", "s", "n", "l",
|
35
|
-
nil, "r", nil, nil, nil, nil, nil, "b", nil,
|
36
|
-
"p", "p", "p", "p", "p", "p", "p", "p", "p",
|
37
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
38
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
39
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
40
|
-
"P", "P", "P", "P", "P", "P", "P", "P", "P",
|
41
|
-
nil, "B", nil, nil, nil, nil, nil, "R", nil,
|
42
|
-
"L", "N", "S", "G", "K", "G", "S", "N", "L"
|
43
|
-
)
|
44
|
-
|
45
|
-
starting_position.in_hand_pieces
|
46
|
-
# => []
|
47
|
-
|
48
|
-
starting_position.squares
|
49
|
-
# => ["l", "n", "s", "g", "k", "g", "s", "n", "l",
|
50
|
-
# nil, "r", nil, nil, nil, nil, nil, "b", nil,
|
51
|
-
# "p", "p", "p", "p", "p", "p", "p", "p", "p",
|
52
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
53
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
54
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
55
|
-
# "P", "P", "P", "P", "P", "P", "P", "P", "P",
|
56
|
-
# nil, "B", nil, nil, nil, nil, nil, "R", nil,
|
57
|
-
# "L", "N", "S", "G", "K", "G", "S", "N", "L"]
|
58
|
-
|
59
|
-
starting_position.pieces_in_hand_grouped_by_sides
|
60
|
-
# => [[], []]
|
61
|
-
|
62
|
-
starting_position.active_side_id
|
63
|
-
# => 0
|
64
|
-
|
65
|
-
# List of moves (see https://github.com/sashite/pmn.rb)
|
66
|
-
moves = [
|
67
|
-
[ 56, 47, "P" ],
|
68
|
-
[ 3, 11, "g" ],
|
69
|
-
[ 64, 24, "+B", "P" ],
|
70
|
-
[ 5, 14, "g" ],
|
71
|
-
[ 24, 14, "+B", "G" ],
|
72
|
-
[ 4, 3, "k" ],
|
73
|
-
[ nil, 13, "G" ]
|
74
|
-
]
|
75
|
-
|
76
|
-
last_position = moves.reduce(starting_position) do |position, move|
|
77
|
-
position.call(move)
|
78
|
-
end
|
79
|
-
|
80
|
-
last_position.in_hand_pieces
|
81
|
-
# => []
|
82
|
-
|
83
|
-
last_position.squares
|
84
|
-
# => ["l", "n", "s", "k", nil, nil, "s", "n", "l",
|
85
|
-
# nil, "r", "g", nil, "G", "+B", nil, "b", nil,
|
86
|
-
# "p", "p", "p", "p", "p", "p", nil, "p", "p",
|
87
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
88
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
89
|
-
# nil, nil, "P", nil, nil, nil, nil, nil, nil,
|
90
|
-
# "P", "P", nil, "P", "P", "P", "P", "P", "P",
|
91
|
-
# nil, nil, nil, nil, nil, nil, nil, "R", nil,
|
92
|
-
# "L", "N", "S", "G", "K", "G", "S", "N", "L"]
|
93
|
-
|
94
|
-
last_position.pieces_in_hand_grouped_by_sides
|
95
|
-
# => [["P"], []]
|
96
|
-
|
97
|
-
last_position.active_side_id
|
98
|
-
# => 1
|
21
|
+
```sh
|
22
|
+
bundle
|
99
23
|
```
|
100
24
|
|
101
|
-
|
102
|
-
|
103
|
-
```ruby
|
104
|
-
require "qi"
|
105
|
-
|
106
|
-
starting_position = Qi::Position.new(
|
107
|
-
nil, nil, nil, "s", "k", "s", nil, nil, nil,
|
108
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
109
|
-
nil, nil, nil, nil, "+P", nil, nil, nil, nil,
|
110
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
111
|
-
nil, nil, nil, nil, nil, nil, nil, "+B", nil,
|
112
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
113
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
114
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
115
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
116
|
-
pieces_in_hand_grouped_by_sides: [
|
117
|
-
["S"],
|
118
|
-
["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"]
|
119
|
-
]
|
120
|
-
)
|
121
|
-
|
122
|
-
starting_position.in_hand_pieces
|
123
|
-
# => ["S"]
|
124
|
-
|
125
|
-
starting_position.squares
|
126
|
-
# => [nil, nil, nil, "s", "k", "s", nil, nil, nil,
|
127
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
128
|
-
# nil, nil, nil, nil, "+P", nil, nil, nil, nil,
|
129
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
130
|
-
# nil, nil, nil, nil, nil, nil, nil, "+B", nil,
|
131
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
132
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
133
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
134
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil]
|
135
|
-
|
136
|
-
starting_position.pieces_in_hand_grouped_by_sides
|
137
|
-
# => [["S"], ["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"]]
|
138
|
-
|
139
|
-
starting_position.active_side_id
|
140
|
-
# => 0
|
141
|
-
|
142
|
-
# List of moves (see https://github.com/sashite/pmn.rb)
|
143
|
-
moves = [
|
144
|
-
[ 43, 13, "+B" ], [ 5, 13, "s", "b" ],
|
145
|
-
[ nil, 14, "S" ]
|
146
|
-
]
|
147
|
-
|
148
|
-
last_position = moves.reduce(starting_position) do |position, move|
|
149
|
-
position.call(move)
|
150
|
-
end
|
151
|
-
|
152
|
-
last_position.in_hand_pieces
|
153
|
-
# => ["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", "b"]
|
154
|
-
|
155
|
-
last_position.squares
|
156
|
-
# => [nil, nil, nil, "s", "k", nil, nil, nil, nil,
|
157
|
-
# nil, nil, nil, nil, "s", "S", nil, nil, nil,
|
158
|
-
# nil, nil, nil, nil, "+P", nil, nil, nil, nil,
|
159
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
160
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
161
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
162
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
163
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
164
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil]
|
165
|
-
|
166
|
-
last_position.pieces_in_hand_grouped_by_sides
|
167
|
-
# => [[], ["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", "b"]]
|
168
|
-
|
169
|
-
last_position.active_side_id
|
170
|
-
# => 1
|
171
|
-
```
|
172
|
-
|
173
|
-
Another example with [Xiangqi](https://en.wikipedia.org/wiki/Xiangqi)'s Short Double Cannons Checkmate:
|
174
|
-
|
175
|
-
```ruby
|
176
|
-
require "qi"
|
177
|
-
|
178
|
-
starting_position = Qi::Position.new(
|
179
|
-
"車", "馬", "象", "士", "將", "士", "象", "馬", "車",
|
180
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
181
|
-
nil, "砲", nil, nil, nil, nil, nil, "砲", nil,
|
182
|
-
"卒", nil, "卒", nil, "卒", nil, "卒", nil, "卒",
|
183
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
184
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
185
|
-
"兵", nil, "兵", nil, "兵", nil, "兵", nil, "兵",
|
186
|
-
nil, "炮", nil, nil, nil, nil, nil, "炮", nil,
|
187
|
-
nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
188
|
-
"俥", "傌", "相", "仕", "帥", "仕", "相", "傌", "俥"
|
189
|
-
)
|
190
|
-
|
191
|
-
starting_position.in_hand_pieces
|
192
|
-
# => []
|
193
|
-
|
194
|
-
starting_position.squares
|
195
|
-
# => ["車", "馬", "象", "士", "將", "士", "象", "馬", "車",
|
196
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
197
|
-
# nil, "砲", nil, nil, nil, nil, nil, "砲", nil,
|
198
|
-
# "卒", nil, "卒", nil, "卒", nil, "卒", nil, "卒",
|
199
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
200
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
201
|
-
# "兵", nil, "兵", nil, "兵", nil, "兵", nil, "兵",
|
202
|
-
# nil, "炮", nil, nil, nil, nil, nil, "炮", nil,
|
203
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
204
|
-
# "俥", "傌", "相", "仕", "帥", "仕", "相", "傌", "俥"]
|
205
|
-
|
206
|
-
starting_position.pieces_in_hand_grouped_by_sides
|
207
|
-
# => [[], []]
|
208
|
-
|
209
|
-
starting_position.active_side_id
|
210
|
-
# => 0
|
211
|
-
|
212
|
-
# List of moves (see https://github.com/sashite/pmn.rb)
|
213
|
-
moves = [
|
214
|
-
[ 64, 67, "炮" ],
|
215
|
-
[ 25, 22, "砲" ],
|
216
|
-
[ 70, 52, "炮" ],
|
217
|
-
[ 19, 55, "砲" ],
|
218
|
-
[ 67, 31, "炮" ],
|
219
|
-
[ 22, 58, "砲" ],
|
220
|
-
[ 52, 49, "炮" ]
|
221
|
-
]
|
222
|
-
|
223
|
-
last_position = moves.reduce(starting_position) do |position, move|
|
224
|
-
position.call(move)
|
225
|
-
end
|
226
|
-
|
227
|
-
last_position.in_hand_pieces
|
228
|
-
# => []
|
229
|
-
|
230
|
-
last_position.squares
|
231
|
-
# => ["車", "馬", "象", "士", "將", "士", "象", "馬", "車",
|
232
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
233
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
234
|
-
# "卒", nil, "卒", nil, "炮", nil, "卒", nil, "卒",
|
235
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
236
|
-
# nil, nil, nil, nil, "炮", nil, nil, nil, nil,
|
237
|
-
# "兵", "砲", "兵", nil, "砲", nil, "兵", nil, "兵",
|
238
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
239
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
240
|
-
# "俥", "傌", "相", "仕", "帥", "仕", "相", "傌", "俥"]
|
241
|
-
|
242
|
-
last_position.pieces_in_hand_grouped_by_sides
|
243
|
-
# => [[], []]
|
25
|
+
Or install it yourself as:
|
244
26
|
|
245
|
-
|
246
|
-
|
27
|
+
```sh
|
28
|
+
gem install qi --pre
|
247
29
|
```
|
248
30
|
|
249
|
-
|
31
|
+
## Examples
|
250
32
|
|
251
33
|
```ruby
|
252
34
|
require "qi"
|
253
35
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
"bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
|
265
|
-
"bR", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gR",
|
266
|
-
nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
|
267
|
-
nil , nil , nil , "rP", "rP", "rP", "rP", "rP", "rP", "rP", "rP", nil , nil , nil ,
|
268
|
-
nil , nil , nil , "rR", "rN", "rB", "rQ", "rK", "rB", "rN", "rR", nil , nil , nil ,
|
269
|
-
pieces_in_hand_grouped_by_sides: [
|
270
|
-
[],
|
271
|
-
[],
|
272
|
-
[],
|
273
|
-
[]
|
274
|
-
]
|
36
|
+
Qi.call(
|
37
|
+
[43, 13, "+B"],
|
38
|
+
in_hand: %w[S 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],
|
39
|
+
square: {
|
40
|
+
3 => "s",
|
41
|
+
4 => "k",
|
42
|
+
5 => "s",
|
43
|
+
22 => "+P",
|
44
|
+
43 => "+B"
|
45
|
+
}
|
275
46
|
)
|
276
|
-
|
277
|
-
starting_position.in_hand_pieces
|
278
|
-
# => []
|
279
|
-
|
280
|
-
starting_position.squares
|
281
|
-
# => [nil , nil , nil , "yR", "yN", "yB", "yK", "yQ", "yB", "yN", "yR", nil , nil , nil ,
|
282
|
-
# nil , nil , nil , "yP", "yP", "yP", "yP", "yP", "yP", "yP", "yP", nil , nil , nil ,
|
283
|
-
# nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
|
284
|
-
# "bR", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gR",
|
285
|
-
# "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
|
286
|
-
# "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
|
287
|
-
# "bK", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gQ",
|
288
|
-
# "bQ", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gK",
|
289
|
-
# "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
|
290
|
-
# "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
|
291
|
-
# "bR", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gR",
|
292
|
-
# nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
|
293
|
-
# nil , nil , nil , "rP", "rP", "rP", "rP", "rP", "rP", "rP", "rP", nil , nil , nil ,
|
294
|
-
# nil , nil , nil , "rR", "rN", "rB", "rQ", "rK", "rB", "rN", "rR", nil , nil , nil]
|
295
|
-
|
296
|
-
starting_position.pieces_in_hand_grouped_by_sides
|
297
|
-
# => [[], [], [], []]
|
298
|
-
|
299
|
-
starting_position.active_side_id
|
300
|
-
# => 0
|
301
|
-
|
302
|
-
# List of moves (see https://github.com/sashite/pmn.rb)
|
303
|
-
moves = [
|
304
|
-
[ 175, 147, "rP" ],
|
305
|
-
[ 85, 87, "bP" ],
|
306
|
-
[ 20, 48, "yP" ],
|
307
|
-
[ 110, 108, "gP" ],
|
308
|
-
[ 191, 162, "rN" ]
|
309
|
-
]
|
310
|
-
|
311
|
-
last_position = moves.reduce(starting_position) do |position, move|
|
312
|
-
position.call(move)
|
313
|
-
end
|
314
|
-
|
315
|
-
last_position.in_hand_pieces
|
316
|
-
# => []
|
317
|
-
|
318
|
-
last_position.squares
|
319
|
-
# => [nil , nil , nil , "yR", "yN", "yB", "yK", "yQ", "yB", "yN", "yR", nil , nil , nil ,
|
320
|
-
# nil , nil , nil , "yP", "yP", "yP", nil , "yP", "yP", "yP", "yP", nil , nil , nil ,
|
321
|
-
# nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
|
322
|
-
# "bR", "bP", nil , nil , nil , nil , "yP", nil , nil , nil , nil , nil , "gP", "gR",
|
323
|
-
# "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
|
324
|
-
# "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
|
325
|
-
# "bK", nil , nil , "bP", nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gQ",
|
326
|
-
# "bQ", "bP", nil , nil , nil , nil , nil , nil , nil , nil , "gP", nil , nil , "gK",
|
327
|
-
# "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
|
328
|
-
# "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
|
329
|
-
# "bR", "bP", nil , nil , nil , nil , nil , "rP", nil , nil , nil , nil , "gP", "gR",
|
330
|
-
# nil , nil , nil , nil , nil , nil , nil , nil , "rN", nil , nil , nil , nil , nil ,
|
331
|
-
# nil , nil , nil , "rP", "rP", "rP", "rP", nil , "rP", "rP", "rP", nil , nil , nil ,
|
332
|
-
# nil , nil , nil , "rR", "rN", "rB", "rQ", "rK", "rB", nil , "rR", nil , nil , nil]
|
333
|
-
|
334
|
-
last_position.pieces_in_hand_grouped_by_sides
|
335
|
-
# => [[], [], [], []]
|
336
|
-
|
337
|
-
last_position.active_side_id
|
338
|
-
# => 1
|
47
|
+
# => {:square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}, :in_hand=>["S", "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"]}
|
339
48
|
```
|
340
49
|
|
341
50
|
## License
|
@@ -347,7 +56,3 @@ The code is available as open source under the terms of the [MIT License](https:
|
|
347
56
|
This [gem](https://rubygems.org/gems/qi) is maintained by [Sashite](https://sashite.com/).
|
348
57
|
|
349
58
|
With some [lines of code](https://github.com/sashite/), let's share the beauty of Chinese, Japanese and Western cultures through the game of chess!
|
350
|
-
|
351
|
-
[gem]: https://rubygems.org/gems/qi
|
352
|
-
[inchpages]: https://inch-ci.org/github/sashite/qi.rb
|
353
|
-
[rubydoc]: https://rubydoc.info/gems/qi/frames
|
data/lib/qi.rb
CHANGED
@@ -1,7 +1,48 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative File.join("qi", "move")
|
4
|
+
|
5
|
+
# The Qi abstraction.
|
6
|
+
#
|
7
|
+
# @example Apply a move to a classic Shogi problem
|
8
|
+
# Qi.call(
|
9
|
+
# [43, 13, "+B"],
|
10
|
+
# in_hand: %w[S 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],
|
11
|
+
# square: {
|
12
|
+
# 3 => "s",
|
13
|
+
# 4 => "k",
|
14
|
+
# 5 => "s",
|
15
|
+
# 22 => "+P",
|
16
|
+
# 43 => "+B"
|
17
|
+
# }
|
18
|
+
# )
|
19
|
+
# # => {:in_hand=>["S", "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"], :square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}}
|
4
20
|
module Qi
|
21
|
+
# Apply a move to the position.
|
22
|
+
#
|
23
|
+
# @param move [Array] The move to play.
|
24
|
+
# @param in_hand [Array] The list of pieces in hand.
|
25
|
+
# @param square [Hash] The index of each piece on the board.
|
26
|
+
#
|
27
|
+
# @see https://developer.sashite.com/specs/portable-chess-notation
|
28
|
+
# @see https://developer.sashite.com/specs/portable-move-notation
|
29
|
+
#
|
30
|
+
# @example Apply a move to a classic Shogi problem
|
31
|
+
# call(
|
32
|
+
# [43, 13, "+B"],
|
33
|
+
# in_hand: %w[S 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],
|
34
|
+
# square: {
|
35
|
+
# 3 => "s",
|
36
|
+
# 4 => "k",
|
37
|
+
# 5 => "s",
|
38
|
+
# 22 => "+P",
|
39
|
+
# 43 => "+B"
|
40
|
+
# }
|
41
|
+
# )
|
42
|
+
# # => {:in_hand=>["S", "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"], :square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}}
|
43
|
+
#
|
44
|
+
# @return [Hash] The piece set of the next position.
|
45
|
+
def self.call(move, in_hand:, square:)
|
46
|
+
Move.new(move).call(in_hand: in_hand, square: square)
|
47
|
+
end
|
5
48
|
end
|
6
|
-
|
7
|
-
require_relative "qi/position"
|
data/lib/qi/action.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Qi
|
4
|
+
# The Action abstraction.
|
5
|
+
class Action
|
6
|
+
# Initialize an action instance.
|
7
|
+
#
|
8
|
+
# @param src_square_id [Integer, nil] The source square ID.
|
9
|
+
# @param dst_square_id [Integer] The target square ID.
|
10
|
+
# @param moved_piece_name [String] The moved piece name.
|
11
|
+
# @param captured_piece_name [String, nil] The captured piece name.
|
12
|
+
#
|
13
|
+
# @example Initialize a promoted bishop action from 43 to 13
|
14
|
+
# new(43, 13, "+B", nil)
|
15
|
+
#
|
16
|
+
# @see https://developer.sashite.com/specs/portable-action-notation
|
17
|
+
def initialize(src_square_id, dst_square_id, moved_piece_name, captured_piece_name = nil)
|
18
|
+
@src_square_id = src_square_id
|
19
|
+
@dst_square_id = dst_square_id
|
20
|
+
@moved_piece_name = moved_piece_name
|
21
|
+
@captured_piece_name = captured_piece_name
|
22
|
+
end
|
23
|
+
|
24
|
+
# Commit an action to the position.
|
25
|
+
#
|
26
|
+
# @param in_hand [Array] The list of pieces in hand.
|
27
|
+
# @param square [Hash] The index of each piece on the board.
|
28
|
+
#
|
29
|
+
# @example Commit a Shogi action to the piece set of a position
|
30
|
+
# call(
|
31
|
+
# 43, 13, "+B", nil,
|
32
|
+
# in_hand: %w[S 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],
|
33
|
+
# square: {
|
34
|
+
# 3 => "s",
|
35
|
+
# 4 => "k",
|
36
|
+
# 5 => "s",
|
37
|
+
# 22 => "+P",
|
38
|
+
# 43 => "+B"
|
39
|
+
# }
|
40
|
+
# )
|
41
|
+
# # => {:in_hand=>["S", "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"], :square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}}
|
42
|
+
#
|
43
|
+
# @return [Hash] The next piece set.
|
44
|
+
def call(in_hand:, square:)
|
45
|
+
in_hand = in_hand.dup
|
46
|
+
square = square.dup
|
47
|
+
|
48
|
+
if @src_square_id.nil?
|
49
|
+
piece_in_hand_id = in_hand.index(@moved_piece_name)
|
50
|
+
in_hand.delete_at(piece_in_hand_id) unless piece_in_hand_id.nil?
|
51
|
+
else
|
52
|
+
square.delete(@src_square_id)
|
53
|
+
end
|
54
|
+
|
55
|
+
square[@dst_square_id] = @moved_piece_name
|
56
|
+
in_hand.push(@captured_piece_name) unless @captured_piece_name.nil?
|
57
|
+
|
58
|
+
{ in_hand: in_hand, square: square }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/qi/move.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "action"
|
4
|
+
|
5
|
+
module Qi
|
6
|
+
# The Move abstraction.
|
7
|
+
class Move
|
8
|
+
# Initialize a move instance.
|
9
|
+
#
|
10
|
+
# @param move [Array] The move to apply.
|
11
|
+
#
|
12
|
+
# @example Initialize a promoted bishop move from 43 to 13
|
13
|
+
# new([43, 13, "+B"])
|
14
|
+
#
|
15
|
+
# @see https://developer.sashite.com/specs/portable-move-notation
|
16
|
+
def initialize(move)
|
17
|
+
@actions = move.each_slice(4)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Apply a move to the piece set of a position.
|
21
|
+
#
|
22
|
+
# @param in_hand [Array] The list of pieces in hand.
|
23
|
+
# @param square [Hash] The index of each piece on the board.
|
24
|
+
#
|
25
|
+
# @example Apply a move to a classic Shogi problem
|
26
|
+
# call(
|
27
|
+
# [43, 13, "+B"],
|
28
|
+
# in_hand: %w[S 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],
|
29
|
+
# square: {
|
30
|
+
# 3 => "s",
|
31
|
+
# 4 => "k",
|
32
|
+
# 5 => "s",
|
33
|
+
# 22 => "+P",
|
34
|
+
# 43 => "+B"
|
35
|
+
# }
|
36
|
+
# )
|
37
|
+
# # => {:in_hand=>["S", "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"], :square=>{3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}}
|
38
|
+
#
|
39
|
+
# @return [Hash] The piece set of the next position.
|
40
|
+
def call(in_hand:, square:)
|
41
|
+
@actions.inject(in_hand: in_hand, square: square) do |piece_set, attrs|
|
42
|
+
Action.new(*attrs).call(**piece_set)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
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:
|
4
|
+
version: 9.0.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyril Kato
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: brutal
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: byebug
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: rake
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,6 +66,20 @@ dependencies:
|
|
52
66
|
- - ">="
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rubocop-md
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
55
83
|
- !ruby/object:Gem::Dependency
|
56
84
|
name: rubocop-performance
|
57
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +94,20 @@ dependencies:
|
|
66
94
|
- - ">="
|
67
95
|
- !ruby/object:Gem::Version
|
68
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rubocop-rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
69
111
|
- !ruby/object:Gem::Dependency
|
70
112
|
name: rubocop-thread_safety
|
71
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -117,7 +159,8 @@ files:
|
|
117
159
|
- LICENSE.md
|
118
160
|
- README.md
|
119
161
|
- lib/qi.rb
|
120
|
-
- lib/qi/
|
162
|
+
- lib/qi/action.rb
|
163
|
+
- lib/qi/move.rb
|
121
164
|
homepage: https://developer.sashite.com/specs/
|
122
165
|
licenses:
|
123
166
|
- MIT
|
@@ -125,7 +168,7 @@ metadata:
|
|
125
168
|
bug_tracker_uri: https://github.com/sashite/qi.rb/issues
|
126
169
|
documentation_uri: https://rubydoc.info/gems/qi/index
|
127
170
|
source_code_uri: https://github.com/sashite/qi.rb
|
128
|
-
post_install_message:
|
171
|
+
post_install_message:
|
129
172
|
rdoc_options: []
|
130
173
|
require_paths:
|
131
174
|
- lib
|
@@ -133,15 +176,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
176
|
requirements:
|
134
177
|
- - ">="
|
135
178
|
- !ruby/object:Gem::Version
|
136
|
-
version:
|
179
|
+
version: 3.0.0
|
137
180
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
181
|
requirements:
|
139
|
-
- - "
|
182
|
+
- - ">"
|
140
183
|
- !ruby/object:Gem::Version
|
141
|
-
version:
|
184
|
+
version: 1.3.1
|
142
185
|
requirements: []
|
143
|
-
rubygems_version: 3.
|
144
|
-
signing_key:
|
186
|
+
rubygems_version: 3.2.22
|
187
|
+
signing_key:
|
145
188
|
specification_version: 4
|
146
|
-
summary:
|
189
|
+
summary: Update positions with a move.
|
147
190
|
test_files: []
|
data/lib/qi/position.rb
DELETED
@@ -1,182 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Qi
|
4
|
-
# The position class.
|
5
|
-
#
|
6
|
-
# @see https://developer.sashite.com/specs/portable-chess-notation
|
7
|
-
class Position
|
8
|
-
# Players are identified by a number according to the order in which they
|
9
|
-
# traditionally play from the starting position.
|
10
|
-
#
|
11
|
-
# @!attribute [r] active_side_id
|
12
|
-
# @return [Integer] The identifier of the player who must play.
|
13
|
-
attr_reader :active_side_id
|
14
|
-
|
15
|
-
# The list of pieces in hand owned by players.
|
16
|
-
#
|
17
|
-
# @!attribute [r] pieces_in_hand_grouped_by_sides
|
18
|
-
# @return [Array] The list of pieces in hand for each side.
|
19
|
-
attr_reader :pieces_in_hand_grouped_by_sides
|
20
|
-
|
21
|
-
# The list of squares on the board.
|
22
|
-
#
|
23
|
-
# @!attribute [r] squares
|
24
|
-
# @return [Array] The list of squares on the board.
|
25
|
-
attr_reader :squares
|
26
|
-
|
27
|
-
# Initialize a position.
|
28
|
-
#
|
29
|
-
# @param squares [Array] The list of squares on the board.
|
30
|
-
# @param active_side_id [Integer] The identifier of the player who must play.
|
31
|
-
# @param pieces_in_hand_grouped_by_sides [Array] The list of pieces in hand
|
32
|
-
# grouped by players.
|
33
|
-
#
|
34
|
-
# @example Chess's starting position
|
35
|
-
# Position.new(
|
36
|
-
# "♜", "♞", "♝", "♛", "♚", "♝", "♞", "♜",
|
37
|
-
# "♟", "♟", "♟", "♟", "♟", "♟", "♟", "♟",
|
38
|
-
# nil, nil, nil, nil, nil, nil, nil, nil,
|
39
|
-
# nil, nil, nil, nil, nil, nil, nil, nil,
|
40
|
-
# nil, nil, nil, nil, nil, nil, nil, nil,
|
41
|
-
# nil, nil, nil, nil, nil, nil, nil, nil,
|
42
|
-
# "♙", "♙", "♙", "♙", "♙", "♙", "♙", "♙",
|
43
|
-
# "♖", "♘", "♗", "♕", "♔", "♗", "♘", "♖"
|
44
|
-
# )
|
45
|
-
#
|
46
|
-
# @example Four-player chess's starting position
|
47
|
-
# Position.new(
|
48
|
-
# nil , nil , nil , "yR", "yN", "yB", "yK", "yQ", "yB", "yN", "yR", nil , nil , nil ,
|
49
|
-
# nil , nil , nil , "yP", "yP", "yP", "yP", "yP", "yP", "yP", "yP", nil , nil , nil ,
|
50
|
-
# nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
|
51
|
-
# "bR", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gR",
|
52
|
-
# "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
|
53
|
-
# "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
|
54
|
-
# "bK", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gQ",
|
55
|
-
# "bQ", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gK",
|
56
|
-
# "bB", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gB",
|
57
|
-
# "bN", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gN",
|
58
|
-
# "bR", "bP", nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , "gP", "gR",
|
59
|
-
# nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil , nil ,
|
60
|
-
# nil , nil , nil , "rP", "rP", "rP", "rP", "rP", "rP", "rP", "rP", nil , nil , nil ,
|
61
|
-
# nil , nil , nil , "rR", "rN", "rB", "rQ", "rK", "rB", "rN", "rR", nil , nil , nil ,
|
62
|
-
# pieces_in_hand_grouped_by_sides: [
|
63
|
-
# [],
|
64
|
-
# [],
|
65
|
-
# [],
|
66
|
-
# []
|
67
|
-
# ]
|
68
|
-
# )
|
69
|
-
#
|
70
|
-
# @example Makruk's starting position
|
71
|
-
# Position.new(
|
72
|
-
# "♜", "♞", "♝", "♛", "♚", "♝", "♞", "♜",
|
73
|
-
# nil, nil, nil, nil, nil, nil, nil, nil,
|
74
|
-
# "♟", "♟", "♟", "♟", "♟", "♟", "♟", "♟",
|
75
|
-
# nil, nil, nil, nil, nil, nil, nil, nil,
|
76
|
-
# nil, nil, nil, nil, nil, nil, nil, nil,
|
77
|
-
# "♙", "♙", "♙", "♙", "♙", "♙", "♙", "♙",
|
78
|
-
# nil, nil, nil, nil, nil, nil, nil, nil,
|
79
|
-
# "♖", "♘", "♗", "♔", "♕", "♗", "♘", "♖"
|
80
|
-
# )
|
81
|
-
#
|
82
|
-
# @example Shogi's starting position
|
83
|
-
# Position.new(
|
84
|
-
# "l", "n", "s", "g", "k", "g", "s", "n", "l",
|
85
|
-
# nil, "r", nil, nil, nil, nil, nil, "b", nil,
|
86
|
-
# "p", "p", "p", "p", "p", "p", "p", "p", "p",
|
87
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
88
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
89
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
90
|
-
# "P", "P", "P", "P", "P", "P", "P", "P", "P",
|
91
|
-
# nil, "B", nil, nil, nil, nil, nil, "R", nil,
|
92
|
-
# "L", "N", "S", "G", "K", "G", "S", "N", "L"
|
93
|
-
# )
|
94
|
-
#
|
95
|
-
# @example A classic Tsume Shogi problem
|
96
|
-
# Position.new(
|
97
|
-
# nil, nil, nil, "s", "k", "s", nil, nil, nil,
|
98
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
99
|
-
# nil, nil, nil, nil, "+P", nil, nil, nil, nil,
|
100
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
101
|
-
# nil, nil, nil, nil, nil, nil, nil, "+B", nil,
|
102
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
103
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
104
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
105
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
106
|
-
# pieces_in_hand_grouped_by_sides: [
|
107
|
-
# ["S"],
|
108
|
-
# ["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"]
|
109
|
-
# ]
|
110
|
-
# )
|
111
|
-
#
|
112
|
-
# @example Xiangqi's starting position
|
113
|
-
# Position.new(
|
114
|
-
# "車", "馬", "象", "士", "將", "士", "象", "馬", "車",
|
115
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
116
|
-
# nil, "砲", nil, nil, nil, nil, nil, "砲", nil,
|
117
|
-
# "卒", nil, "卒", nil, "卒", nil, "卒", nil, "卒",
|
118
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
119
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
120
|
-
# "兵", nil, "兵", nil, "兵", nil, "兵", nil, "兵",
|
121
|
-
# nil, "炮", nil, nil, nil, nil, nil, "炮", nil,
|
122
|
-
# nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
123
|
-
# "俥", "傌", "相", "仕", "帥", "仕", "相", "傌", "俥"
|
124
|
-
# )
|
125
|
-
def initialize(*squares, active_side_id: 0, pieces_in_hand_grouped_by_sides: [[], []])
|
126
|
-
@squares = squares
|
127
|
-
@active_side_id = active_side_id % pieces_in_hand_grouped_by_sides.size
|
128
|
-
@pieces_in_hand_grouped_by_sides = pieces_in_hand_grouped_by_sides
|
129
|
-
|
130
|
-
freeze
|
131
|
-
end
|
132
|
-
|
133
|
-
# Apply a move to the position.
|
134
|
-
#
|
135
|
-
# @param move [Array] The move to play.
|
136
|
-
# @see https://developer.sashite.com/specs/portable-move-notation
|
137
|
-
# @see https://github.com/sashite/pmn.rb
|
138
|
-
#
|
139
|
-
# @return [Position] The new position.
|
140
|
-
def call(move)
|
141
|
-
updated_squares = squares.dup
|
142
|
-
updated_in_hand_pieces = in_hand_pieces.dup
|
143
|
-
|
144
|
-
actions = move.each_slice(4)
|
145
|
-
|
146
|
-
actions.each do |action|
|
147
|
-
src_square_id = action.fetch(0)
|
148
|
-
dst_square_id = action.fetch(1)
|
149
|
-
moved_piece_name = action.fetch(2)
|
150
|
-
captured_piece_name = action.fetch(3, nil)
|
151
|
-
|
152
|
-
if src_square_id.nil?
|
153
|
-
piece_in_hand_id = updated_in_hand_pieces.index(moved_piece_name)
|
154
|
-
updated_in_hand_pieces.delete_at(piece_in_hand_id) unless piece_in_hand_id.nil?
|
155
|
-
else
|
156
|
-
updated_squares[src_square_id] = nil
|
157
|
-
end
|
158
|
-
|
159
|
-
updated_squares[dst_square_id] = moved_piece_name
|
160
|
-
|
161
|
-
unless captured_piece_name.nil?
|
162
|
-
updated_in_hand_pieces.push(captured_piece_name)
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
updated_pieces_in_hand_grouped_by_sides = pieces_in_hand_grouped_by_sides.dup
|
167
|
-
updated_pieces_in_hand_grouped_by_sides[active_side_id] = updated_in_hand_pieces
|
168
|
-
|
169
|
-
self.class.new(*updated_squares,
|
170
|
-
active_side_id: active_side_id.succ,
|
171
|
-
pieces_in_hand_grouped_by_sides: updated_pieces_in_hand_grouped_by_sides
|
172
|
-
)
|
173
|
-
end
|
174
|
-
|
175
|
-
# The list of pieces in hand owned by the current player.
|
176
|
-
#
|
177
|
-
# @return [Array] The list of pieces in hand of the active side.
|
178
|
-
def in_hand_pieces
|
179
|
-
pieces_in_hand_grouped_by_sides.fetch(active_side_id)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|