qi 7.0.0 → 9.0.0
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 +20 -23
- data/lib/qi/action.rb +61 -0
- data/lib/qi.rb +26 -57
- metadata +50 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52024f72e11787560aa6fc8bed990c359e49d3e995f2d3cfea875de5febaeba5
|
4
|
+
data.tar.gz: d04a6301684f284f29aa1b67c811ca596006a6aa0f33e22d1c67790da55418ef
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e9afd43466c2ea7b6608d0f94996bffd40622fa2ff98bc008098c78375074c4ae8c6e12235520053a35619fca22b3588ccc120d06910f9b8af10cf349273af6c
|
7
|
+
data.tar.gz: 4264fd4ff0e12bc86b1451b1a411bea1e700cb58581f87e0216a0b601bd26c2443e144c44ddb765e8e6428ae0bdc2f406342248851a5c36c9f9c00494c8c1253
|
data/LICENSE.md
CHANGED
data/README.md
CHANGED
@@ -1,9 +1,10 @@
|
|
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
9
|
> `Qi` (棋) is an abstraction for updating positions of chess variants (including Chess, Janggi, Markruk, Shogi, Xiangqi), with a move.
|
9
10
|
|
@@ -17,33 +18,33 @@ gem "qi"
|
|
17
18
|
|
18
19
|
And then execute:
|
19
20
|
|
20
|
-
|
21
|
+
```sh
|
22
|
+
bundle
|
23
|
+
```
|
21
24
|
|
22
25
|
Or install it yourself as:
|
23
26
|
|
24
|
-
|
27
|
+
```sh
|
28
|
+
gem install qi
|
29
|
+
```
|
25
30
|
|
26
|
-
##
|
31
|
+
## Example
|
27
32
|
|
28
33
|
```ruby
|
29
34
|
require "qi"
|
30
35
|
|
31
36
|
Qi.call(
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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",
|
38
43
|
22 => "+P",
|
39
44
|
43 => "+B"
|
40
|
-
}
|
41
|
-
"hands": [
|
42
|
-
%w[S],
|
43
|
-
%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]
|
44
|
-
]
|
45
|
+
}
|
45
46
|
)
|
46
|
-
# => {:
|
47
|
+
# => {: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"}}
|
47
48
|
```
|
48
49
|
|
49
50
|
## License
|
@@ -55,7 +56,3 @@ The code is available as open source under the terms of the [MIT License](https:
|
|
55
56
|
This [gem](https://rubygems.org/gems/qi) is maintained by [Sashite](https://sashite.com/).
|
56
57
|
|
57
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!
|
58
|
-
|
59
|
-
[gem]: https://rubygems.org/gems/qi
|
60
|
-
[inchpages]: https://inch-ci.org/github/sashite/qi.rb
|
61
|
-
[rubydoc]: https://rubydoc.info/gems/qi/frames
|
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.rb
CHANGED
@@ -1,84 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative File.join("qi", "action")
|
4
|
+
|
3
5
|
# The Qi abstraction.
|
4
6
|
#
|
5
|
-
# @example
|
7
|
+
# @example Apply a move to a classic Shogi problem
|
6
8
|
# Qi.call(
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
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: {
|
10
12
|
# 3 => "s",
|
11
13
|
# 4 => "k",
|
12
14
|
# 5 => "s",
|
13
15
|
# 22 => "+P",
|
14
16
|
# 43 => "+B"
|
15
|
-
# }
|
16
|
-
# "hands": [
|
17
|
-
# %w[S],
|
18
|
-
# %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]
|
19
|
-
# ]
|
17
|
+
# }
|
20
18
|
# )
|
21
|
-
# # => {:
|
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"}}
|
22
20
|
module Qi
|
23
|
-
# Apply
|
21
|
+
# Apply an action to the position.
|
24
22
|
#
|
25
|
-
# @param
|
26
|
-
# @param
|
27
|
-
# @param
|
28
|
-
# @param
|
23
|
+
# @param src_square_id [Integer] A source square index.
|
24
|
+
# @param dst_square_id [Integer] A target square index.
|
25
|
+
# @param moved_piece_name [String] A piece name.
|
26
|
+
# @param captured_piece_name [String] A captured piece name.
|
27
|
+
# @param in_hand [Array] The list of pieces in hand.
|
28
|
+
# @param square [Hash] The index of each piece on the board.
|
29
29
|
#
|
30
30
|
# @see https://developer.sashite.com/specs/portable-chess-notation
|
31
31
|
# @see https://developer.sashite.com/specs/portable-move-notation
|
32
32
|
#
|
33
|
-
# @example
|
33
|
+
# @example Apply a move to a classic Shogi problem
|
34
34
|
# call(
|
35
|
-
#
|
36
|
-
#
|
37
|
-
# "
|
35
|
+
# 43,
|
36
|
+
# 13,
|
37
|
+
# "+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: {
|
38
40
|
# 3 => "s",
|
39
41
|
# 4 => "k",
|
40
42
|
# 5 => "s",
|
41
43
|
# 22 => "+P",
|
42
44
|
# 43 => "+B"
|
43
|
-
# }
|
44
|
-
# "hands": [
|
45
|
-
# %w[S],
|
46
|
-
# %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]
|
47
|
-
# ]
|
45
|
+
# }
|
48
46
|
# )
|
49
|
-
# # => {:
|
47
|
+
# # => {: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"}}
|
50
48
|
#
|
51
|
-
# @return [Hash] The next position.
|
52
|
-
def self.call(
|
53
|
-
|
54
|
-
updated_in_hand_pieces = hands.fetch(side_id).dup
|
55
|
-
|
56
|
-
actions = move.each_slice(4)
|
57
|
-
|
58
|
-
actions.each do |action|
|
59
|
-
src_square_id = action.fetch(0)
|
60
|
-
dst_square_id = action.fetch(1)
|
61
|
-
moved_piece_name = action.fetch(2)
|
62
|
-
captured_piece_name = action.fetch(3, nil)
|
63
|
-
|
64
|
-
if src_square_id.nil?
|
65
|
-
piece_in_hand_id = updated_in_hand_pieces.index(moved_piece_name)
|
66
|
-
updated_in_hand_pieces.delete_at(piece_in_hand_id) unless piece_in_hand_id.nil?
|
67
|
-
else
|
68
|
-
updated_board.delete(src_square_id)
|
69
|
-
end
|
70
|
-
|
71
|
-
updated_board[dst_square_id] = moved_piece_name
|
72
|
-
updated_in_hand_pieces.push(captured_piece_name) unless captured_piece_name.nil?
|
73
|
-
end
|
74
|
-
|
75
|
-
updated_hands = hands.dup
|
76
|
-
updated_hands[side_id] = updated_in_hand_pieces
|
77
|
-
|
78
|
-
{
|
79
|
-
side_id: side_id.succ % hands.length,
|
80
|
-
board: updated_board,
|
81
|
-
hands: updated_hands
|
82
|
-
}
|
49
|
+
# @return [Hash] The piece set of the next position.
|
50
|
+
def self.call(src_square_id, dst_square_id, moved_piece_name, captured_piece_name = nil, in_hand:, square:)
|
51
|
+
Action.new(src_square_id, dst_square_id, moved_piece_name, captured_piece_name).call(in_hand: in_hand, square: square)
|
83
52
|
end
|
84
53
|
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
|
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-09-26 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,6 +159,7 @@ files:
|
|
117
159
|
- LICENSE.md
|
118
160
|
- README.md
|
119
161
|
- lib/qi.rb
|
162
|
+
- lib/qi/action.rb
|
120
163
|
homepage: https://developer.sashite.com/specs/
|
121
164
|
licenses:
|
122
165
|
- MIT
|
@@ -124,7 +167,7 @@ metadata:
|
|
124
167
|
bug_tracker_uri: https://github.com/sashite/qi.rb/issues
|
125
168
|
documentation_uri: https://rubydoc.info/gems/qi/index
|
126
169
|
source_code_uri: https://github.com/sashite/qi.rb
|
127
|
-
post_install_message:
|
170
|
+
post_install_message:
|
128
171
|
rdoc_options: []
|
129
172
|
require_paths:
|
130
173
|
- lib
|
@@ -132,15 +175,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
175
|
requirements:
|
133
176
|
- - ">="
|
134
177
|
- !ruby/object:Gem::Version
|
135
|
-
version:
|
178
|
+
version: 3.0.0
|
136
179
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
137
180
|
requirements:
|
138
181
|
- - ">="
|
139
182
|
- !ruby/object:Gem::Version
|
140
183
|
version: '0'
|
141
184
|
requirements: []
|
142
|
-
rubygems_version: 3.
|
143
|
-
signing_key:
|
185
|
+
rubygems_version: 3.2.22
|
186
|
+
signing_key:
|
144
187
|
specification_version: 4
|
145
188
|
summary: Update positions with a move.
|
146
189
|
test_files: []
|