qi 10.0.0.beta5 → 10.0.0.beta6

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.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +4 -30
  3. data/lib/qi.rb +63 -61
  4. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73eb059b5776d83c165ffe3a37592221e2c28a449cc271b74be2644c9e8e1ed3
4
- data.tar.gz: 37f4b7fe311e4ed0ce178031b17dd45e19281a9778b16785a0e829580c52d93b
3
+ metadata.gz: 638a4dafc9645e200d72d7799afb3f28cca3a81f7cd887e5f29c64974e5776e0
4
+ data.tar.gz: 5e74a8a31f894187b404a3c41ed1a1434916880925934f2fe627e19472f99084
5
5
  SHA512:
6
- metadata.gz: c9feb0ac434f46f4b1d0c6c201ae0d64c084bc4b5b76b82eff8002eb1109580f018d2df65906a0c098129a28d1a2da06744252bcbb04ef1934b926c50ec4cd89
7
- data.tar.gz: 89cbfe6706285b7f482161c2b7188afcc6b94c69aa002bb9f42218b7d246c2066876dc73506a83fcd63ea84430302c4f92feda6f4685749ef9200dba9f8ad2cf
6
+ metadata.gz: 41a6e8c87db922ca87d992b62909c6cf5d87d8900d12c9bc0b43d94d1882040d168678ee9d3f6be85904b7f275a0eaa9c42e32364b0d7c5e4766ec84953fdb10
7
+ data.tar.gz: 14323df90b7e942fbae1a1db4f3e23f071c4fdd62bd969797a39909c710e599534c5eaa2fd4b6a01ffbe91f48d25122a28c32b599fc5731f9b3c14b72c2f8a74
data/README.md CHANGED
@@ -45,7 +45,8 @@ 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.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>"
48
+ qi0.serialize # => "SouthTurn===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
+ qi0.inspect # => "<Qi SouthTurn===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
 
50
51
  qi0.to_a
51
52
  # [false,
@@ -53,20 +54,6 @@ qi0.to_a
53
54
  # ["S"],
54
55
  # {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 43=>"+B"}]
55
56
 
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
57
  qi1 = qi0.commit({ 43 => nil, 13 => "+B" })
71
58
 
72
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"]
@@ -74,27 +61,14 @@ qi1.south_captures # => ["S"]
74
61
  qi1.squares # => {3=>"s", 4=>"k", 5=>"s", 22=>"+P", 13=>"+B"}
75
62
  qi1.north_turn? # => true
76
63
  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>"
64
+ qi1.serialize # => "NorthTurn===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"
65
+ qi1.inspect # => "<Qi NorthTurn===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
66
 
79
67
  qi1.to_a
80
68
  # [true,
81
69
  # ["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
70
  # ["S"],
83
71
  # {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"]
98
72
  ```
99
73
 
100
74
  ## License
data/lib/qi.rb CHANGED
@@ -10,11 +10,12 @@ class Qi
10
10
  # @return [Hash] a hash of pieces on the board
11
11
  attr_reader :north_captures, :south_captures, :squares
12
12
 
13
- # Initializes a new Qi object with the given parameters.
13
+ # Initializes a new Qi object with the given attributes.
14
+ #
14
15
  # @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
16
+ # @param north_captures [Array<Object>] an array of pieces captured by the north player
17
+ # @param south_captures [Array<Object>] an array of pieces captured by the south player
18
+ # @param squares [Hash<Object, Object>] a hash of squares on the board
18
19
  def initialize(is_north_turn, north_captures, south_captures, squares)
19
20
  # Assign the parameters to instance variables.
20
21
  @is_north_turn = is_north_turn
@@ -24,48 +25,37 @@ class Qi
24
25
  end
25
26
 
26
27
  # 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
+ #
29
+ # @param diffs [Hash<Object, Object>] a hash of changes to apply to the squares hash
28
30
  # @param in_hand [Object, nil] the piece that is in hand or nil if none
29
31
  # @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
+ # @return [Qi] a new Qi object with modified attributes, where:
33
+ # - the turn is switched
34
+ # - the captures are updated according to the in hand piece and the drop flag
35
+ # - the squares are merged with the diffs hash
36
+ def commit(diffs = {}, in_hand = nil, is_drop: false)
32
37
  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
38
+ modified_captures = update_captures(in_hand, is_drop:)
39
+ self.class.new(!north_turn?, *modified_captures, modified_squares)
53
40
  end
54
41
 
55
42
  # Checks if it is the north turn or not.
43
+ #
56
44
  # @return [Boolean] true if it is the north turn and false otherwise
57
45
  def north_turn?
58
46
  @is_north_turn
59
47
  end
60
48
 
61
49
  # Checks if it is not the north turn or not.
50
+ #
62
51
  # @return [Boolean] true if it is not the north turn and false otherwise
63
52
  def south_turn?
64
53
  !north_turn?
65
54
  end
66
55
 
67
56
  # Returns an array representation of the Qi object's attributes.
68
- # @return [Array] an array containing four elements:
57
+ #
58
+ # @return [Array(Boolean, Array<Object>, Array<Object>, Hash<Object, Object>)] an array containing four elements:
69
59
  # - a boolean value indicating whose turn it is
70
60
  # - an array of pieces captured by the north player
71
61
  # - an array of pieces captured by the south player
@@ -79,48 +69,60 @@ class Qi
79
69
  ]
80
70
  end
81
71
 
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")
72
+ # Returns a string representation of the Qi object's attributes.
73
+ #
74
+ # @return [String] a string containing three parts separated by "===":
75
+ # - the current turn, either "NorthTurn" or "SouthTurn"
76
+ # - the captures, sorted and joined by ","
77
+ # - the squares, mapped to "coordinate:piece" pairs and joined by ","
78
+ def serialize
79
+ serialized_turn = (north_turn? ? "NorthTurn" : "SouthTurn")
80
+ serialized_captures = (north_captures + south_captures).sort.join(",")
81
+ serialized_squares = squares.keys.map { |i| "#{i}:#{squares.fetch(i)}" }.join(",")
94
82
 
95
- [
96
- north_captures,
97
- board,
98
- south_captures,
99
- turn
100
- ]
83
+ "#{serialized_turn}===#{serialized_captures}===#{serialized_squares}"
101
84
  end
102
85
 
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.
86
+ # Returns a human-readable representation of the Qi object.
87
+ #
88
+ # @return [String] a string containing the class name and the serialized attributes
105
89
  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}>"
90
+ "<#{self.class} #{serialize}>"
111
91
  end
112
92
 
113
93
  private
114
94
 
115
- def captures
116
- south_captures + north_captures
117
- end
95
+ # Updates the captures arrays based on the piece in hand and whether it is dropped or not.
96
+ #
97
+ # @param in_hand [Object, nil] the piece that is in hand or nil if none
98
+ # @param is_drop [Boolean] a boolean value indicating whether the in hand piece is dropped or not
99
+ # @return [Array] an array containing the updated north and south captures arrays
100
+ def update_captures(in_hand, is_drop:)
101
+ return [north_captures, south_captures] if in_hand.nil?
102
+
103
+ captures = north_turn? ? north_captures : south_captures
104
+ other_captures = north_turn? ? south_captures : north_captures
105
+
106
+ if is_drop
107
+ captures = remove_from_captures(in_hand, *captures)
108
+ else
109
+ captures += [in_hand]
110
+ end
118
111
 
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?
112
+ north_turn? ? [captures, other_captures] : [other_captures, captures]
113
+ end
122
114
 
123
- captured_pieces.delete_at(capture_id)
124
- captured_pieces
115
+ # Removes the last occurrence of a piece from an array of captures and returns the modified array.
116
+ #
117
+ # @param piece [Object] the piece to be removed
118
+ # @param captures [Array<Object>] the array of captures
119
+ # @return [Array<Object>] the modified array of captures
120
+ # @raise [IndexError] if the piece is not found in the array
121
+ def remove_from_captures(piece, *captures)
122
+ index = captures.rindex(piece)
123
+ raise ::IndexError, "#{piece} not found!" if index.nil?
124
+
125
+ captures.delete_at(index)
126
+ captures
125
127
  end
126
128
  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.beta5
4
+ version: 10.0.0.beta6
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-22 00:00:00.000000000 Z
11
+ date: 2023-04-23 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