qi 10.0.0.beta5 → 10.0.0.beta6

Sign up to get free protection for your applications and to get access to all the features.
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