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 +4 -4
- data/README.md +8 -3
- data/lib/sashite/snn/style.rb +36 -21
- data/lib/sashite/snn.rb +15 -23
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3327ae1106ccede78736585e812180c12d7a56852a82ae70b7745e233ef5496
|
4
|
+
data.tar.gz: ba5892640791f51341e52c883f52f9f21bac64e21001052e1fcbc17965a156a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
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.
|
data/lib/sashite/snn/style.rb
CHANGED
@@ -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]
|
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")
|
60
|
-
# Snn::Style.parse("chess")
|
61
|
-
# Snn::Style.parse("SHOGI")
|
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
|
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
|
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")
|
36
|
-
# Sashite::Snn.valid?("
|
37
|
-
|
38
|
-
|
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]
|
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")
|
52
|
-
# Sashite::Snn.parse("chess")
|
53
|
-
# Sashite::Snn.parse("SHOGI")
|
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)
|
66
|
-
# Sashite::Snn.style(:Shogi, :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
|