qi 10.0.0.beta4 → 10.0.0.beta5
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 +63 -8
- data/lib/qi.rb +122 -3
- metadata +2 -4
- data/lib/kernel.rb +0 -18
- data/lib/qi/action.rb +0 -34
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73eb059b5776d83c165ffe3a37592221e2c28a449cc271b74be2644c9e8e1ed3
|
4
|
+
data.tar.gz: 37f4b7fe311e4ed0ce178031b17dd45e19281a9778b16785a0e829580c52d93b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9feb0ac434f46f4b1d0c6c201ae0d64c084bc4b5b76b82eff8002eb1109580f018d2df65906a0c098129a28d1a2da06744252bcbb04ef1934b926c50ec4cd89
|
7
|
+
data.tar.gz: 89cbfe6706285b7f482161c2b7188afcc6b94c69aa002bb9f42218b7d246c2066876dc73506a83fcd63ea84430302c4f92feda6f4685749ef9200dba9f8ad2cf
|
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.beta5"
|
17
17
|
```
|
18
18
|
|
19
19
|
And then execute:
|
@@ -33,13 +33,68 @@ gem install qi --pre
|
|
33
33
|
```ruby
|
34
34
|
require "qi"
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
is_north_turn = false
|
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
|
+
south_captures = %w[S]
|
39
|
+
squares = { 3 => "s", 4 => "k", 5 => "s", 22 => "+P", 43 => "+B" }
|
40
|
+
|
41
|
+
qi0 = Qi.new(is_north_turn, north_captures, south_captures, squares)
|
42
|
+
|
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
|
+
qi0.south_captures # => ["S"]
|
45
|
+
qi0.squares # => {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"}
|
46
|
+
qi0.north_turn? # => false
|
47
|
+
qi0.south_turn? # => true
|
48
|
+
qi0.inspect # => "<Qi south-turn 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 3:s,4:k,5:s,22:+P,43:+B>"
|
49
|
+
|
50
|
+
qi0.to_a
|
51
|
+
# [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"],
|
54
|
+
# {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"}]
|
55
|
+
|
56
|
+
qi0.display(81, 9)
|
57
|
+
# [["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"],
|
58
|
+
# [[". ", ". ", ". ", "s ", "k ", "s ", ". ", ". ", ". "],
|
59
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
60
|
+
# [". ", ". ", ". ", ". ", "+P", ". ", ". ", ". ", ". "],
|
61
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
62
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", "+B", ". "],
|
63
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
64
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
65
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
66
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "]],
|
67
|
+
# ["S"],
|
68
|
+
# "Turn to south"]
|
69
|
+
|
70
|
+
qi1 = qi0.commit({ 43 => nil, 13 => "+B" })
|
71
|
+
|
72
|
+
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"]
|
73
|
+
qi1.south_captures # => ["S"]
|
74
|
+
qi1.squares # => {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}
|
75
|
+
qi1.north_turn? # => true
|
76
|
+
qi1.south_turn? # => false
|
77
|
+
qi1.inspect # => "<Qi north-turn 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 3:s,4:k,5:s,22:+P,13:+B>"
|
78
|
+
|
79
|
+
qi1.to_a
|
80
|
+
# [true,
|
81
|
+
# ["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"],
|
82
|
+
# ["S"],
|
83
|
+
# {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}]
|
84
|
+
|
85
|
+
qi1.display(81, 9)
|
86
|
+
# [["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"],
|
87
|
+
# [[". ", ". ", ". ", "s ", "k ", "s ", ". ", ". ", ". "],
|
88
|
+
# [". ", ". ", ". ", ". ", "+B", ". ", ". ", ". ", ". "],
|
89
|
+
# [". ", ". ", ". ", ". ", "+P", ". ", ". ", ". ", ". "],
|
90
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
91
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
92
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
93
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
94
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "],
|
95
|
+
# [". ", ". ", ". ", ". ", ". ", ". ", ". ", ". ", ". "]],
|
96
|
+
# ["S"],
|
97
|
+
# "Turn to north"]
|
43
98
|
```
|
44
99
|
|
45
100
|
## License
|
data/lib/qi.rb
CHANGED
@@ -1,7 +1,126 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
# A class that represents the state of a game.
|
4
|
+
class Qi
|
5
|
+
# @!attribute [r] north_captures
|
6
|
+
# @return [Array] an array of pieces captured by the north player
|
7
|
+
# @!attribute [r] south_captures
|
8
|
+
# @return [Array] an array of pieces captured by the south player
|
9
|
+
# @!attribute [r] squares
|
10
|
+
# @return [Hash] a hash of pieces on the board
|
11
|
+
attr_reader :north_captures, :south_captures, :squares
|
4
12
|
|
5
|
-
#
|
6
|
-
|
13
|
+
# Initializes a new Qi object with the given parameters.
|
14
|
+
# @param is_north_turn [Boolean] a boolean value indicating whose turn it is
|
15
|
+
# @param north_captures [Array] an array of pieces captured by the north player
|
16
|
+
# @param south_captures [Array] an array of pieces captured by the south player
|
17
|
+
# @param squares [Hash] a hash of pieces on the board
|
18
|
+
def initialize(is_north_turn, north_captures, south_captures, squares)
|
19
|
+
# Assign the parameters to instance variables.
|
20
|
+
@is_north_turn = is_north_turn
|
21
|
+
@north_captures = north_captures.sort
|
22
|
+
@south_captures = south_captures.sort
|
23
|
+
@squares = squares.compact
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns a new Qi object that represents the state after applying the given changes.
|
27
|
+
# @param diffs [Hash] a hash of changes to apply to the squares hash
|
28
|
+
# @param in_hand [Object, nil] the piece that is in hand or nil if none
|
29
|
+
# @param is_drop [Boolean] a boolean value indicating whether the in hand piece is dropped or not
|
30
|
+
# @return [Qi] a new Qi object with modified attributes
|
31
|
+
def commit(diffs = {}, in_hand = nil, is_drop = false)
|
32
|
+
modified_squares = squares.merge(diffs)
|
33
|
+
|
34
|
+
if in_hand.nil?
|
35
|
+
self.class.new(south_turn?, north_captures, south_captures, modified_squares)
|
36
|
+
elsif north_turn?
|
37
|
+
modified_captures = if is_drop
|
38
|
+
remove_from_captures(in_hand, *north_captures)
|
39
|
+
else
|
40
|
+
north_captures + [in_hand]
|
41
|
+
end
|
42
|
+
|
43
|
+
self.class.new(false, modified_captures, south_captures, modified_squares)
|
44
|
+
else
|
45
|
+
modified_captures = if is_drop
|
46
|
+
remove_from_captures(in_hand, *south_captures)
|
47
|
+
else
|
48
|
+
south_captures + [in_hand]
|
49
|
+
end
|
50
|
+
|
51
|
+
self.class.new(true, north_captures, modified_captures, modified_squares)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Checks if it is the north turn or not.
|
56
|
+
# @return [Boolean] true if it is the north turn and false otherwise
|
57
|
+
def north_turn?
|
58
|
+
@is_north_turn
|
59
|
+
end
|
60
|
+
|
61
|
+
# Checks if it is not the north turn or not.
|
62
|
+
# @return [Boolean] true if it is not the north turn and false otherwise
|
63
|
+
def south_turn?
|
64
|
+
!north_turn?
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns an array representation of the Qi object's attributes.
|
68
|
+
# @return [Array] an array containing four elements:
|
69
|
+
# - a boolean value indicating whose turn it is
|
70
|
+
# - an array of pieces captured by the north player
|
71
|
+
# - an array of pieces captured by the south player
|
72
|
+
# - a hash of squares on the board
|
73
|
+
def to_a
|
74
|
+
[
|
75
|
+
north_turn?,
|
76
|
+
north_captures,
|
77
|
+
south_captures,
|
78
|
+
squares
|
79
|
+
]
|
80
|
+
end
|
81
|
+
|
82
|
+
# Returns an array representation of the Qi object's attributes for display purposes.
|
83
|
+
# @param size [Integer] the number of squares on the board
|
84
|
+
# @param cols [Integer] the number of columns on the board
|
85
|
+
# @return [Array] an array containing four elements:
|
86
|
+
# - an array of pieces captured by the north player
|
87
|
+
# - a nested array of strings representing the squares on the board
|
88
|
+
# - an array of pieces captured by the south player
|
89
|
+
# - a string indicating whose turn it is
|
90
|
+
def display(size, cols)
|
91
|
+
square_size = squares.values.max_by(&:length).length
|
92
|
+
board = (0...size).to_a.map { |i| squares.fetch(i, ".") }.map { |square| square.center(square_size) }.each_slice(cols).to_a
|
93
|
+
turn = (north_turn? ? "Turn to north" : "Turn to south")
|
94
|
+
|
95
|
+
[
|
96
|
+
north_captures,
|
97
|
+
board,
|
98
|
+
south_captures,
|
99
|
+
turn
|
100
|
+
]
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns a string representation of the Qi object's attributes.
|
104
|
+
# @return [String] a string containing the turn, the captures and the squares in a formatted way.
|
105
|
+
def inspect
|
106
|
+
serialized_turn = (north_turn? ? "north-turn" : "south-turn")
|
107
|
+
serialized_captures = captures.join(",")
|
108
|
+
serialized_squares = squares.keys.map { |i| "#{i}:#{squares.fetch(i)}" }.join(",")
|
109
|
+
|
110
|
+
"<Qi #{serialized_turn} #{serialized_captures} #{serialized_squares}>"
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
def captures
|
116
|
+
south_captures + north_captures
|
117
|
+
end
|
118
|
+
|
119
|
+
def remove_from_captures(captured_piece, *captured_pieces)
|
120
|
+
capture_id = captured_pieces.rindex(captured_piece)
|
121
|
+
raise ::IndexError, "#{captured_piece} not found!" if capture_id.nil?
|
122
|
+
|
123
|
+
captured_pieces.delete_at(capture_id)
|
124
|
+
captured_pieces
|
125
|
+
end
|
7
126
|
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: 10.0.0.
|
4
|
+
version: 10.0.0.beta5
|
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-04-
|
11
|
+
date: 2023-04-22 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
|
@@ -18,9 +18,7 @@ extra_rdoc_files: []
|
|
18
18
|
files:
|
19
19
|
- LICENSE.md
|
20
20
|
- README.md
|
21
|
-
- lib/kernel.rb
|
22
21
|
- lib/qi.rb
|
23
|
-
- lib/qi/action.rb
|
24
22
|
homepage: https://github.com/sashite/qi.rb
|
25
23
|
licenses:
|
26
24
|
- MIT
|
data/lib/kernel.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
# shareable_constant_value: none
|
3
|
-
|
4
|
-
# warn_indent: true
|
5
|
-
|
6
|
-
require_relative File.join("qi", "action")
|
7
|
-
|
8
|
-
# The Kernel module.
|
9
|
-
module Kernel
|
10
|
-
# Abstraction to build positions.
|
11
|
-
#
|
12
|
-
# @return [Array] An action to change the position.
|
13
|
-
#
|
14
|
-
# @api public
|
15
|
-
def Qi(*captures, **squares)
|
16
|
-
::Qi::Action.new(*captures, **squares)
|
17
|
-
end
|
18
|
-
end
|
data/lib/qi/action.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Qi
|
4
|
-
# The Action abstraction.
|
5
|
-
class Action
|
6
|
-
CAPTURE_CHAR = "&"
|
7
|
-
DROP_CHAR = "*"
|
8
|
-
|
9
|
-
# Action initializer.
|
10
|
-
def initialize(*captures, **squares)
|
11
|
-
@captures = captures
|
12
|
-
@squares = squares
|
13
|
-
end
|
14
|
-
|
15
|
-
# Commit an action to the position.
|
16
|
-
#
|
17
|
-
# @return [Array] An action to change the position.
|
18
|
-
def call(**diffs)
|
19
|
-
captures = @captures + Array(diffs.delete(CAPTURE_CHAR))
|
20
|
-
drop = diffs.delete(DROP_CHAR)
|
21
|
-
|
22
|
-
unless drop.nil?
|
23
|
-
index = captures.rindex(drop)
|
24
|
-
raise ::IndexError, "Piece #{drop.inspect} not captured!" if index.nil?
|
25
|
-
|
26
|
-
captures.delete_at(index)
|
27
|
-
end
|
28
|
-
|
29
|
-
squares = @squares.merge(diffs).compact
|
30
|
-
|
31
|
-
[captures.sort, squares]
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|