qi 10.0.0.beta11 → 10.0.0.beta12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +38 -27
- data/lib/qi.rb +74 -211
- metadata +20 -6
- data/lib/qi/error/drop.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f3a609bb51c87ae5486c9244b948899f4e6ae46747ac80bf3be5f83ae76826a
|
4
|
+
data.tar.gz: 1843fa6cc35f2dcaaab08a7772abeb9f56fa3e7d0dc5dc69f9a742ec47e81169
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f79f7dc430f3e84b5cf816492c4f31c7776db329fffd18e161df929ccf18cb85b37cdd69e35c2b93da0e983e976d765bf69e8a33f1e946ec62d61c7b5583d164
|
7
|
+
data.tar.gz: '059b84b8c426af80188f0b6885ff921ab86f7015756d5309d75fd0ab621f1d93322be5f83f603a02535850645da432219af815871c480b56dec0e8f67db738bb'
|
data/README.md
CHANGED
@@ -6,14 +6,25 @@
|
|
6
6
|
[![RuboCop](https://github.com/sashite/qi.rb/workflows/RuboCop/badge.svg?branch=main)](https://github.com/sashite/qi.rb/actions?query=workflow%3Arubocop+branch%3Amain)
|
7
7
|
[![License](https://img.shields.io/github/license/sashite/qi.rb?label=License&logo=github)](https://github.com/sashite/qi.rb/raw/main/LICENSE.md)
|
8
8
|
|
9
|
-
|
9
|
+
Welcome to `Qi` (Chinese: 棋; pinyin: _qí_), a flexible and customizable library designed to represent and manipulate board game positions. `Qi` is ideal for a variety of board games, including chess, shogi, xiangqi, makruk, and more.
|
10
|
+
|
11
|
+
With `Qi`, you can easily track the game state, including which pieces are on the board and where, as well as any captured pieces. The library allows for the application of game moves, updating the state of the game and generating a new position, all while preserving the original state.
|
12
|
+
|
13
|
+
## Features:
|
14
|
+
|
15
|
+
- **Flexible representation of game states:** `Qi`'s design allows it to adapt to different games with varying rules and pieces.
|
16
|
+
- **Immutable positions:** Every move generates a new position, preserving the original one. This is particularly useful for scenarios like undoing moves or exploring potential future states in the game.
|
17
|
+
- **Compact serialization:** `Qi` provides a compact string serialization method for game states, which is useful for saving game progress or transmitting game states over the network.
|
18
|
+
- **Check state tracking:** In addition to the positions and captured pieces, `Qi` also allows tracking of specific game states such as check in chess.
|
19
|
+
|
20
|
+
While `Qi` does not generate game moves itself, it serves as a solid foundation upon which game engines can be built. Its design is focused on providing a robust and adaptable representation of game states, paving the way for the development of diverse board game applications.
|
10
21
|
|
11
22
|
## Installation
|
12
23
|
|
13
24
|
Add this line to your application's Gemfile:
|
14
25
|
|
15
26
|
```ruby
|
16
|
-
gem "qi", ">= 10.0.0.
|
27
|
+
gem "qi", ">= 10.0.0.beta12"
|
17
28
|
```
|
18
29
|
|
19
30
|
And then execute:
|
@@ -33,42 +44,42 @@ gem install qi --pre
|
|
33
44
|
```ruby
|
34
45
|
require "qi"
|
35
46
|
|
36
|
-
is_north_turn = false
|
37
47
|
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
48
|
south_captures = %w[S]
|
49
|
+
captures = north_captures + south_captures
|
39
50
|
squares = { 3 => "s", 4 => "k", 5 => "s", 22 => "+P", 43 => "+B" }
|
40
51
|
|
41
|
-
qi0 = Qi.new(
|
52
|
+
qi0 = Qi.new(*captures, **squares)
|
42
53
|
|
43
|
-
qi0.
|
44
|
-
qi0.
|
45
|
-
qi0.
|
46
|
-
qi0.
|
47
|
-
qi0.
|
48
|
-
qi0.
|
49
|
-
qi0.
|
54
|
+
qi0.captures # => ["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"]
|
55
|
+
qi0.squares # => {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"}
|
56
|
+
qi0.in_check? # => false
|
57
|
+
qi0.not_in_check? # => true
|
58
|
+
qi0.north_turn? # => false
|
59
|
+
qi0.south_turn? # => true
|
60
|
+
qi0.serialize # => "{ 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 s@3;k@4;s@5;+P@22;+B@43 ."
|
61
|
+
qi0.inspect # => "<Qi { 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 s@3;k@4;s@5;+P@22;+B@43 .>"
|
50
62
|
qi0.to_a
|
51
63
|
# [false,
|
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"],
|
53
|
-
# ["S"],
|
64
|
+
# ["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"],
|
54
65
|
# {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"},
|
55
|
-
#
|
56
|
-
|
57
|
-
qi1 = qi0.commit(43, 13
|
58
|
-
|
59
|
-
qi1.
|
60
|
-
qi1.
|
61
|
-
qi1.
|
62
|
-
qi1.
|
63
|
-
qi1.
|
64
|
-
qi1.
|
65
|
-
qi1.
|
66
|
+
# false]
|
67
|
+
|
68
|
+
qi1 = qi0.commit(is_in_check: true, 43 => nil, 13 => "+B")
|
69
|
+
|
70
|
+
qi1.captures # => ["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"]
|
71
|
+
qi1.squares # => {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}
|
72
|
+
qi1.in_check? # => true
|
73
|
+
qi1.not_in_check? # => false
|
74
|
+
qi1.north_turn? # => true
|
75
|
+
qi1.south_turn? # => false
|
76
|
+
qi1.serialize # => "} 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 s@3;k@4;s@5;+B@13;+P@22 +"
|
77
|
+
qi1.inspect # => "<Qi } 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 s@3;k@4;s@5;+B@13;+P@22 +>"
|
66
78
|
qi1.to_a
|
67
79
|
# [true,
|
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"],
|
69
|
-
# ["S"],
|
80
|
+
# ["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"],
|
70
81
|
# {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"},
|
71
|
-
#
|
82
|
+
# true]
|
72
83
|
```
|
73
84
|
|
74
85
|
## License
|
data/lib/qi.rb
CHANGED
@@ -1,269 +1,132 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "digest"
|
4
|
-
|
4
|
+
require "kernel/boolean"
|
5
5
|
|
6
|
-
# Qi
|
7
|
-
# information about the current turn, captures, game board, and other game options.
|
6
|
+
# The Qi class represents a state of games such as Shogi.
|
8
7
|
class Qi
|
9
|
-
#
|
10
|
-
|
11
|
-
South = :South
|
8
|
+
# @return [Array] the pieces captured by the current player.
|
9
|
+
attr_reader :captures
|
12
10
|
|
13
|
-
# @return [
|
14
|
-
attr_reader :north_captures
|
15
|
-
|
16
|
-
# @return [Array] the pieces captured by the south player
|
17
|
-
attr_reader :south_captures
|
18
|
-
|
19
|
-
# @return [Hash] the current state of the game board
|
11
|
+
# @return [Hash] the current state of the board.
|
20
12
|
attr_reader :squares
|
21
13
|
|
22
|
-
#
|
23
|
-
|
24
|
-
|
25
|
-
#
|
26
|
-
#
|
27
|
-
# @
|
28
|
-
#
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
@is_north_turn = is_north_turn
|
37
|
-
@north_captures = north_captures.sort
|
38
|
-
@south_captures = south_captures.sort
|
14
|
+
# Initializes a new game state.
|
15
|
+
#
|
16
|
+
# @param capture [String, nil] the piece to be captured.
|
17
|
+
# @param captures [Array] the pieces already captured.
|
18
|
+
# @param drop [String, nil] the piece to be dropped.
|
19
|
+
# @param is_in_check [Boolean] whether the current player is in check.
|
20
|
+
# @param is_north_turn [Boolean] whether it's North's turn.
|
21
|
+
# @param squares [Hash] the current state of the board.
|
22
|
+
def initialize(capture = nil, *captures, drop: nil, is_in_check: false, is_north_turn: false, **squares)
|
23
|
+
captures << capture unless capture.nil?
|
24
|
+
captures.delete_at(captures.rindex(drop)) unless drop.nil?
|
25
|
+
|
26
|
+
@captures = captures.sort
|
27
|
+
@is_in_check = Boolean(is_in_check)
|
28
|
+
@is_north_turn = Boolean(is_north_turn)
|
39
29
|
@squares = squares.compact
|
40
|
-
@options = options
|
41
30
|
end
|
42
31
|
|
43
|
-
#
|
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>
|
32
|
+
# Commits a move and returns a new game state.
|
61
33
|
#
|
62
|
-
# @
|
63
|
-
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
# @return [Qi] the new game state
|
67
|
-
def commit(
|
68
|
-
|
69
|
-
|
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)
|
34
|
+
# @param capture [String, nil] the piece to be captured.
|
35
|
+
# @param drop [String, nil] the piece to be dropped.
|
36
|
+
# @param is_in_check [Boolean] whether the current player is in check.
|
37
|
+
# @param diffs [Hash] the differences in the state of the board.
|
38
|
+
# @return [Qi] the new game state.
|
39
|
+
def commit(capture: nil, drop: nil, is_in_check: false, **diffs)
|
40
|
+
self.class.new(capture, *captures, drop:, is_in_check:, is_north_turn: south_turn?, **squares.merge(diffs))
|
73
41
|
end
|
74
42
|
|
75
|
-
#
|
76
|
-
|
77
|
-
|
78
|
-
# qi1 = Qi.new(...)
|
79
|
-
# qi2 = Qi.new(...)
|
80
|
-
# qi1.eql?(qi2) #=> true or false
|
81
|
-
#
|
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
|
84
|
-
def eql?(other)
|
85
|
-
return false unless other.respond_to?(:serialize)
|
86
|
-
|
87
|
-
other.serialize == serialize
|
88
|
-
end
|
89
|
-
alias == eql?
|
90
|
-
|
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']
|
103
|
-
#
|
104
|
-
# @return [Array] the captures of the current player
|
105
|
-
def current_captures
|
106
|
-
north_turn? ? north_captures : south_captures
|
107
|
-
end
|
108
|
-
|
109
|
-
# Get the captures of the opponent player.
|
110
|
-
#
|
111
|
-
# @return [Array] the captures of the opponent player
|
112
|
-
def opponent_captures
|
113
|
-
north_turn? ? south_captures : north_captures
|
114
|
-
end
|
115
|
-
|
116
|
-
# Get the current turn.
|
117
|
-
#
|
118
|
-
# @return [Symbol] :North if it's the north player's turn, :South otherwise
|
119
|
-
def current_turn
|
120
|
-
north_turn? ? North : South
|
43
|
+
# @return [Boolean] whether the current player is in check.
|
44
|
+
def in_check?
|
45
|
+
@is_in_check
|
121
46
|
end
|
122
47
|
|
123
|
-
#
|
124
|
-
|
125
|
-
|
126
|
-
def next_turn
|
127
|
-
north_turn? ? South : North
|
48
|
+
# @return [Boolean] whether the current player is not in check.
|
49
|
+
def not_in_check?
|
50
|
+
!in_check?
|
128
51
|
end
|
129
52
|
|
130
|
-
#
|
131
|
-
#
|
132
|
-
# @return [Boolean] true if it's the north player's turn, false otherwise
|
53
|
+
# @return [Boolean] whether it's North's turn.
|
133
54
|
def north_turn?
|
134
55
|
@is_north_turn
|
135
56
|
end
|
136
57
|
|
137
|
-
#
|
138
|
-
#
|
139
|
-
# @return [Boolean] true if it's the south player's turn, false otherwise
|
58
|
+
# @return [Boolean] whether it's South's turn.
|
140
59
|
def south_turn?
|
141
60
|
!north_turn?
|
142
61
|
end
|
143
62
|
|
144
|
-
#
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
63
|
+
# @return [Boolean] whether the other game state is equal to this one.
|
64
|
+
def eql?(other)
|
65
|
+
return false unless other.respond_to?(:serialize)
|
66
|
+
|
67
|
+
other.serialize == serialize
|
68
|
+
end
|
69
|
+
alias == eql?
|
70
|
+
|
71
|
+
# @return [Array] the array representation of the game state.
|
150
72
|
def to_a
|
151
73
|
[
|
152
74
|
north_turn?,
|
153
|
-
|
154
|
-
south_captures,
|
75
|
+
captures,
|
155
76
|
squares,
|
156
|
-
|
77
|
+
in_check?
|
157
78
|
]
|
158
79
|
end
|
159
80
|
|
160
|
-
#
|
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
|
81
|
+
# @return [Hash] the hash representation of the game state.
|
166
82
|
def to_h
|
167
83
|
{
|
168
|
-
is_north_turn:
|
169
|
-
|
170
|
-
south_captures:,
|
84
|
+
is_north_turn: north_turn?,
|
85
|
+
captures:,
|
171
86
|
squares:,
|
172
|
-
|
87
|
+
is_in_check: in_check?
|
173
88
|
}
|
174
89
|
end
|
175
90
|
|
176
|
-
#
|
177
|
-
#
|
178
|
-
# @example Generating a hash value
|
179
|
-
# qi.hash #=> "10dfb778f6559dd368c510a27e3b00bdb5b4ad88d4d67f38864d7e36de7c2f9c"
|
180
|
-
#
|
181
|
-
# @return [String] a SHA256 hash of the serialized game state
|
91
|
+
# @return [String] the SHA-256 hash of the serialized game state.
|
182
92
|
def hash
|
183
93
|
::Digest::SHA256.hexdigest(serialize)
|
184
94
|
end
|
185
95
|
|
186
|
-
#
|
187
|
-
#
|
188
|
-
# @example Serializing the game state
|
189
|
-
# qi.serialize #=> "North-turn===P,G,B,+B===3:g,56:P,64:+B"
|
190
|
-
#
|
191
|
-
# @return [String] a string representation of the game state
|
96
|
+
# @return [String] the string representation of the game state.
|
192
97
|
def serialize
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
98
|
+
[
|
99
|
+
serialized_turn,
|
100
|
+
serialized_captures,
|
101
|
+
serialized_squares,
|
102
|
+
serialized_in_check
|
103
|
+
].join(" ")
|
198
104
|
end
|
199
105
|
|
200
|
-
#
|
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>"
|
204
|
-
#
|
205
|
-
# @return [String] a string representation of the game state
|
106
|
+
# @return [String] the string representation of the object.
|
206
107
|
def inspect
|
207
108
|
"<#{self.class} #{serialize}>"
|
208
109
|
end
|
209
110
|
|
210
111
|
private
|
211
112
|
|
212
|
-
#
|
213
|
-
|
214
|
-
|
215
|
-
|
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)
|
237
|
-
return [north_captures, south_captures] if in_hand.nil?
|
238
|
-
|
239
|
-
captures = if src_square.nil?
|
240
|
-
remove_from_captures(in_hand, *current_captures)
|
241
|
-
else
|
242
|
-
current_captures + [in_hand]
|
243
|
-
end
|
113
|
+
# @return [String] the serialized turn.
|
114
|
+
def serialized_turn
|
115
|
+
north_turn? ? "}" : "{"
|
116
|
+
end
|
244
117
|
|
245
|
-
|
118
|
+
# @return [String] the serialized captures.
|
119
|
+
def serialized_captures
|
120
|
+
captures.join(";")
|
246
121
|
end
|
247
122
|
|
248
|
-
#
|
249
|
-
|
250
|
-
|
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
|
262
|
-
def remove_from_captures(piece, *captures)
|
263
|
-
index = captures.rindex(piece)
|
264
|
-
raise Error::Drop, "There are no #{piece} in hand" if index.nil?
|
123
|
+
# @return [String] the serialized board state.
|
124
|
+
def serialized_squares
|
125
|
+
squares.keys.sort.map { |i| "#{squares.fetch(i)}@#{i}" }.join(";")
|
126
|
+
end
|
265
127
|
|
266
|
-
|
267
|
-
|
128
|
+
# @return [String] the serialized check state.
|
129
|
+
def serialized_in_check
|
130
|
+
in_check? ? "+" : "."
|
268
131
|
end
|
269
132
|
end
|
metadata
CHANGED
@@ -1,16 +1,31 @@
|
|
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.beta12
|
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-
|
12
|
-
dependencies:
|
13
|
-
|
11
|
+
date: 2023-05-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: kernel-boolean
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: A flexible and customizable library for representing and manipulating
|
28
|
+
game states, ideal for developing board games like chess, shogi, or xiangqi.
|
14
29
|
email: contact@cyril.email
|
15
30
|
executables: []
|
16
31
|
extensions: []
|
@@ -19,7 +34,6 @@ files:
|
|
19
34
|
- LICENSE.md
|
20
35
|
- README.md
|
21
36
|
- lib/qi.rb
|
22
|
-
- lib/qi/error/drop.rb
|
23
37
|
homepage: https://github.com/sashite/qi.rb
|
24
38
|
licenses:
|
25
39
|
- MIT
|
@@ -43,5 +57,5 @@ requirements: []
|
|
43
57
|
rubygems_version: 3.4.10
|
44
58
|
signing_key:
|
45
59
|
specification_version: 4
|
46
|
-
summary:
|
60
|
+
summary: Versatile Board Game Position Representation
|
47
61
|
test_files: []
|
data/lib/qi/error/drop.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Qi
|
4
|
-
# The Error module contains custom error classes for the Qi game.
|
5
|
-
module Error
|
6
|
-
# The Drop class is a custom error class that inherits from IndexError.
|
7
|
-
# It is raised when a drop operation in the game of Qi is invalid.
|
8
|
-
#
|
9
|
-
# @see IndexError
|
10
|
-
class Drop < ::IndexError
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|