sashite-snn 1.1.0 → 1.1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c75eb6af8fa8c0ff0a9791e0ecc0fe49b7e6c0827733e96f2e37e552ddca50b0
4
- data.tar.gz: 2ac49000ca7ff3f2ae01e0a7d240f2fb99d5cab34a915b9799a5088c7461b4f3
3
+ metadata.gz: c3327ae1106ccede78736585e812180c12d7a56852a82ae70b7745e233ef5496
4
+ data.tar.gz: ba5892640791f51341e52c883f52f9f21bac64e21001052e1fcbc17965a156a7
5
5
  SHA512:
6
- metadata.gz: 9ec03703cf421329344a597f91d4157e4b44f1d5347cb4f8eea1a5c9e79e6800ad0880f6d9a8ad003df18d48ab5afb084d6526ffcbf6df14323b21ee751fc54e
7
- data.tar.gz: e95c9a8e58fbe6254e546456a5de92a79de1eeb33688292ec1c58f58ba30b6a94357a61d1396a1a639e0051c772b888af355e421a3726b2faf3ae7179450afd6
6
+ metadata.gz: 1798b7aec7b88cc2baddcd9fa7f3518c2d97bf16343caac92ec84f9bfad3dc0ac20830d95144984ea27795d867e80c008a090f9de7fc8d284ac853f9c326b144
7
+ data.tar.gz: a6a548c819cf763b914cc1b70ce82ba86d86b7973f0231df5075931788d19fb2732d4138896b347cf6a1842c554116578e59cdfb619408acb370c2c43d469753
data/README.md CHANGED
@@ -89,6 +89,7 @@ black_shogi.to_s # => "shogi"
89
89
 
90
90
  ### Regular Expression
91
91
  ```ruby
92
+ # Pattern accessible via Sashite::Snn::Style::SNN_PATTERN
92
93
  /\A([A-Z][A-Z0-9]*|[a-z][a-z0-9]*)\z/
93
94
  ```
94
95
 
@@ -216,8 +217,12 @@ style2.to_s # => "chess" (lowercase display)
216
217
  - `#same_side?(other)` - Check if same side
217
218
  - `#==(other)` - Full equality comparison
218
219
 
219
- ### Constants
220
- - `Sashite::Snn::SNN_REGEX` - Regular expression for SNN validation
220
+ ### Style Class Constants
221
+
222
+ - `Sashite::Snn::Style::FIRST_PLAYER` - Symbol for first player (:first)
223
+ - `Sashite::Snn::Style::SECOND_PLAYER` - Symbol for second player (:second)
224
+ - `Sashite::Snn::Style::VALID_SIDES` - Array of valid sides
225
+ - `Sashite::Snn::Style::SNN_PATTERN` - Regular expression for SNN validation
221
226
 
222
227
  ## Advanced Usage
223
228
 
@@ -377,7 +382,7 @@ Following the [Game Protocol](https://sashite.dev/game-protocol/):
377
382
 
378
383
  | Protocol Attribute | SNN Encoding | Examples | Notes |
379
384
  |-------------------|--------------|----------|-------|
380
- | **Style** | Alphanumeric identifier | `CHESS`, `SHOGI`, `XIANGQI` | Name is always stored as uppercase symbol |
385
+ | **Style** | Alphanumeric identifier | `CHESS`, `SHOGI`, `XIANGQI` | Name is always stored with proper capitalization |
381
386
  | **Side** | Case encoding | `CHESS` = First player, `chess` = Second player | Case is determined by side during rendering |
382
387
 
383
388
  **Name Convention**: All style names are internally represented with proper capitalization (first letter uppercase, rest lowercase). The display case is determined by the `side` attribute: first player styles display as uppercase, second player styles as lowercase.
@@ -53,12 +53,12 @@ module Sashite
53
53
  # Parse an SNN string into a Style object
54
54
  #
55
55
  # @param snn_string [String] SNN notation string
56
- # @return [Style] new style instance
56
+ # @return [Style] parsed style object with normalized name and inferred side
57
57
  # @raise [ArgumentError] if the SNN string is invalid
58
- # @example
59
- # Snn::Style.parse("CHESS") # => #<Snn::Style name=:Chess side=:first>
60
- # Snn::Style.parse("chess") # => #<Snn::Style name=:Chess side=:second>
61
- # Snn::Style.parse("SHOGI") # => #<Snn::Style name=:Shogi side=:first>
58
+ # @example Parse SNN strings with case normalization
59
+ # Sashite::Snn::Style.parse("CHESS") # => #<Snn::Style name=:Chess side=:first>
60
+ # Sashite::Snn::Style.parse("chess") # => #<Snn::Style name=:Chess side=:second>
61
+ # Sashite::Snn::Style.parse("SHOGI") # => #<Snn::Style name=:Shogi side=:first>
62
62
  def self.parse(snn_string)
63
63
  string_value = String(snn_string)
64
64
  matches = match_pattern(string_value)
@@ -74,21 +74,36 @@ module Sashite
74
74
  new(style_name, style_side)
75
75
  end
76
76
 
77
+ # Check if a string is a valid SNN notation
78
+ #
79
+ # @param snn_string [String] the string to validate
80
+ # @return [Boolean] true if valid SNN, false otherwise
81
+ #
82
+ # @example Validate SNN strings
83
+ # Sashite::Snn::Style.valid?("CHESS") # => true
84
+ # Sashite::Snn::Style.valid?("chess") # => true
85
+ # Sashite::Snn::Style.valid?("Chess") # => false
86
+ def self.valid?(snn_string)
87
+ return false unless snn_string.is_a?(::String)
88
+
89
+ snn_string.match?(SNN_PATTERN)
90
+ end
91
+
77
92
  # Convert the style to its SNN string representation
78
93
  #
79
- # @return [String] SNN notation string
80
- # @example
81
- # style.to_s # => "CHESS"
82
- # style.to_s # => "chess"
83
- # style.to_s # => "SHOGI"
94
+ # @return [String] SNN notation string with case based on side
95
+ # @example Display different sides
96
+ # style.to_s # => "CHESS" (first player)
97
+ # style.to_s # => "chess" (second player)
98
+ # style.to_s # => "SHOGI" (first player)
84
99
  def to_s
85
100
  first_player? ? name.to_s.upcase : name.to_s.downcase
86
101
  end
87
102
 
88
103
  # Create a new style with opposite ownership (side)
89
104
  #
90
- # @return [Style] new style instance with flipped side
91
- # @example
105
+ # @return [Style] new immutable style instance with flipped side
106
+ # @example Flip player sides
92
107
  # style.flip # (:Chess, :first) => (:Chess, :second)
93
108
  def flip
94
109
  self.class.new(name, opposite_side)
@@ -97,8 +112,8 @@ module Sashite
97
112
  # Create a new style with a different name (keeping same side)
98
113
  #
99
114
  # @param new_name [Symbol] new name (with proper capitalization)
100
- # @return [Style] new style instance with different name
101
- # @example
115
+ # @return [Style] new immutable style instance with different name
116
+ # @example Change style name
102
117
  # style.with_name(:Shogi) # (:Chess, :first) => (:Shogi, :first)
103
118
  def with_name(new_name)
104
119
  self.class.validate_name(new_name)
@@ -110,8 +125,8 @@ module Sashite
110
125
  # Create a new style with a different side (keeping same name)
111
126
  #
112
127
  # @param new_side [Symbol] :first or :second
113
- # @return [Style] new style instance with different side
114
- # @example
128
+ # @return [Style] new immutable style instance with different side
129
+ # @example Change player side
115
130
  # style.with_side(:second) # (:Chess, :first) => (:Chess, :second)
116
131
  def with_side(new_side)
117
132
  self.class.validate_side(new_side)
@@ -137,8 +152,8 @@ module Sashite
137
152
  # Check if this style has the same name as another
138
153
  #
139
154
  # @param other [Style] style to compare with
140
- # @return [Boolean] true if same name
141
- # @example
155
+ # @return [Boolean] true if both styles have the same name
156
+ # @example Compare style names
142
157
  # chess1.same_name?(chess2) # (:Chess, :first) and (:Chess, :second) => true
143
158
  def same_name?(other)
144
159
  return false unless other.is_a?(self.class)
@@ -149,7 +164,7 @@ module Sashite
149
164
  # Check if this style belongs to the same side as another
150
165
  #
151
166
  # @param other [Style] style to compare with
152
- # @return [Boolean] true if same side
167
+ # @return [Boolean] true if both styles belong to the same side
153
168
  def same_side?(other)
154
169
  return false unless other.is_a?(self.class)
155
170
 
@@ -159,7 +174,7 @@ module Sashite
159
174
  # Custom equality comparison
160
175
  #
161
176
  # @param other [Object] object to compare with
162
- # @return [Boolean] true if styles are equal
177
+ # @return [Boolean] true if both objects are styles with identical name and side
163
178
  def ==(other)
164
179
  return false unless other.is_a?(self.class)
165
180
 
@@ -171,7 +186,7 @@ module Sashite
171
186
 
172
187
  # Custom hash implementation for use in collections
173
188
  #
174
- # @return [Integer] hash value
189
+ # @return [Integer] hash value based on class, name, and side
175
190
  def hash
176
191
  [self.class, name, side].hash
177
192
  end
data/lib/sashite/snn.rb CHANGED
@@ -22,35 +22,27 @@ module Sashite
22
22
  #
23
23
  # See: https://sashite.dev/specs/snn/1.0.0/
24
24
  module Snn
25
- # Regular expression for SNN validation
26
- # Matches: uppercase alphanumeric identifier OR lowercase alphanumeric identifier
27
- SNN_REGEX = /\A([A-Z][A-Z0-9]*|[a-z][a-z0-9]*)\z/
28
-
29
25
  # Check if a string is a valid SNN notation
30
26
  #
31
- # @param snn [String] The string to validate
27
+ # @param snn_string [String] the string to validate
32
28
  # @return [Boolean] true if valid SNN, false otherwise
33
29
  #
34
- # @example
35
- # Sashite::Snn.valid?("CHESS") # => true
36
- # Sashite::Snn.valid?("chess") # => true
37
- # Sashite::Snn.valid?("Chess") # => false
38
- # Sashite::Snn.valid?("123") # => false
39
- def self.valid?(snn)
40
- return false unless snn.is_a?(::String)
41
-
42
- snn.match?(SNN_REGEX)
30
+ # @example Validate various SNN formats
31
+ # Sashite::Snn.valid?("CHESS") # => true
32
+ # Sashite::Snn.valid?("Chess") # => false
33
+ def self.valid?(snn_string)
34
+ Style.valid?(snn_string)
43
35
  end
44
36
 
45
37
  # Parse an SNN string into a Style object
46
38
  #
47
39
  # @param snn_string [String] SNN notation string
48
- # @return [Snn::Style] new style instance
40
+ # @return [Snn::Style] parsed style object with name and side attributes
49
41
  # @raise [ArgumentError] if the SNN string is invalid
50
- # @example
51
- # Sashite::Snn.parse("CHESS") # => #<Snn::Style name=:Chess side=:first>
52
- # Sashite::Snn.parse("chess") # => #<Snn::Style name=:Chess side=:second>
53
- # Sashite::Snn.parse("SHOGI") # => #<Snn::Style name=:Shogi side=:first>
42
+ # @example Parse different SNN formats
43
+ # Sashite::Snn.parse("CHESS") # => #<Snn::Style name=:Chess side=:first>
44
+ # Sashite::Snn.parse("chess") # => #<Snn::Style name=:Chess side=:second>
45
+ # Sashite::Snn.parse("SHOGI") # => #<Snn::Style name=:Shogi side=:first>
54
46
  def self.parse(snn_string)
55
47
  Style.parse(snn_string)
56
48
  end
@@ -59,11 +51,11 @@ module Sashite
59
51
  #
60
52
  # @param name [Symbol] style name (with proper capitalization)
61
53
  # @param side [Symbol] player side (:first or :second)
62
- # @return [Snn::Style] new style instance
54
+ # @return [Snn::Style] new immutable style instance
63
55
  # @raise [ArgumentError] if parameters are invalid
64
- # @example
65
- # Sashite::Snn.style(:Chess, :first) # => #<Snn::Style name=:Chess side=:first>
66
- # Sashite::Snn.style(:Shogi, :second) # => #<Snn::Style name=:Shogi side=:second>
56
+ # @example Create styles directly
57
+ # Sashite::Snn.style(:Chess, :first) # => #<Snn::Style name=:Chess side=:first>
58
+ # Sashite::Snn.style(:Shogi, :second) # => #<Snn::Style name=:Shogi side=:second>
67
59
  def self.style(name, side)
68
60
  Style.new(name, side)
69
61
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sashite-snn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato