sashite-pin 2.0.2 → 3.0.0

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: 70bbc211cb1dd38efa9f0c39b2d0e1b0fd09c2dcf2d7ac3773719ce11786a5ac
4
- data.tar.gz: cd6831f22ee3e9fd8ce559f5535bbcbb1d9ca13ba9083a9d9c1fe66d41e2eef9
3
+ metadata.gz: f69bdd89484b5fc844f13c7cedbbdf2efe15f75620fe1eb695d0258120cf16d6
4
+ data.tar.gz: 38c51ef6f22d3267c26f5baa425306645e2a17f8448575da6759112a6b71f115
5
5
  SHA512:
6
- metadata.gz: d0808aac8a46423256ec3546a4eb71d5882d3535b4a74929680cd31f84294ffd406716565f53ef072ff35c5c1131bb2612ab93398001d3d80772bb34a3dc3d07
7
- data.tar.gz: ba7ecb1765c03c801f014bdbb9792fcae5dacd8d119890b0c73f0e550a345a8fc307cb39a82b803c986ef7fa50f76ad5fff39c6a7bffc5fe39e1b06bebe6b809
6
+ metadata.gz: c98b8c1e383c0414341be4ea7ea9f3f5f5864330f16f3faed608a315cd46a52e039f539c4d45f45d8b84aa6965d999560f0d0d937cf4743ec6c05655e9b6470d
7
+ data.tar.gz: 847ca5d4e6c6bd5697d665bebc103e01f876fc2a5f8c0947a27ef3589de94bd9d482bb69322817985e9dc6d23a3588801c8021ab54467b70bda49929cd62aef4
data/README.md CHANGED
@@ -11,14 +11,14 @@
11
11
 
12
12
  PIN (Piece Identifier Notation) provides an ASCII-based format for representing pieces in abstract strategy board games. PIN translates piece attributes from the [Game Protocol](https://sashite.dev/game-protocol/) into a compact, portable notation system.
13
13
 
14
- This gem implements the [PIN Specification v1.0.0](https://sashite.dev/specs/pin/1.0.0/), providing a modern Ruby interface with immutable piece objects and functional programming principles.
14
+ This gem implements the [PIN Specification v1.0.0](https://sashite.dev/specs/pin/1.0.0/), providing a modern Ruby interface with immutable identifier objects and functional programming principles.
15
15
 
16
16
  ## Installation
17
17
 
18
18
  ```ruby
19
19
  # In your Gemfile
20
20
  gem "sashite-pin"
21
- ```
21
+ ````
22
22
 
23
23
  Or install manually:
24
24
 
@@ -31,16 +31,16 @@ gem install sashite-pin
31
31
  ```ruby
32
32
  require "sashite/pin"
33
33
 
34
- # Parse PIN strings into piece objects
35
- piece = Sashite::Pin.parse("K") # => #<Pin::Piece type=:K side=:first state=:normal>
36
- piece.to_s # => "K"
37
- piece.type # => :K
38
- piece.side # => :first
39
- piece.state # => :normal
34
+ # Parse PIN strings into identifier objects
35
+ identifier = Sashite::Pin.parse("K") # => #<Pin::Identifier type=:K side=:first state=:normal>
36
+ identifier.to_s # => "K"
37
+ identifier.type # => :K
38
+ identifier.side # => :first
39
+ identifier.state # => :normal
40
40
 
41
- # Create pieces directly
42
- piece = Sashite::Pin.piece(:K, :first, :normal) # => #<Pin::Piece type=:K side=:first state=:normal>
43
- piece = Sashite::Pin::Piece.new(:R, :second, :enhanced) # => #<Pin::Piece type=:R side=:second state=:enhanced>
41
+ # Create identifiers directly
42
+ identifier = Sashite::Pin.identifier(:K, :first, :normal) # => #<Pin::Identifier type=:K side=:first state=:normal>
43
+ identifier = Sashite::Pin::Identifier.new(:R, :second, :enhanced) # => #<Pin::Identifier type=:R side=:second state=:enhanced>
44
44
 
45
45
  # Validate PIN strings
46
46
  Sashite::Pin.valid?("K") # => true
@@ -48,171 +48,104 @@ Sashite::Pin.valid?("+R") # => true
48
48
  Sashite::Pin.valid?("invalid") # => false
49
49
 
50
50
  # State manipulation (returns new immutable instances)
51
- enhanced = piece.enhance # => #<Pin::Piece type=:K side=:first state=:enhanced>
52
- enhanced.to_s # => "+K"
53
- diminished = piece.diminish # => #<Pin::Piece type=:K side=:first state=:diminished>
54
- diminished.to_s # => "-K"
51
+ enhanced = identifier.enhance # => #<Pin::Identifier type=:K side=:first state=:enhanced>
52
+ enhanced.to_s # => "+K"
53
+ diminished = identifier.diminish # => #<Pin::Identifier type=:K side=:first state=:diminished>
54
+ diminished.to_s # => "-K"
55
55
 
56
56
  # Side manipulation
57
- flipped = piece.flip # => #<Pin::Piece type=:K side=:second state=:normal>
58
- flipped.to_s # => "k"
57
+ flipped = identifier.flip # => #<Pin::Identifier type=:K side=:second state=:normal>
58
+ flipped.to_s # => "k"
59
59
 
60
60
  # Type manipulation
61
- queen = piece.with_type(:Q) # => #<Pin::Piece type=:Q side=:first state=:normal>
62
- queen.to_s # => "Q"
61
+ queen = identifier.with_type(:Q) # => #<Pin::Identifier type=:Q side=:first state=:normal>
62
+ queen.to_s # => "Q"
63
63
 
64
64
  # State queries
65
- piece.normal? # => true
66
- enhanced.enhanced? # => true
67
- diminished.diminished? # => true
65
+ identifier.normal? # => true
66
+ enhanced.enhanced? # => true
67
+ diminished.diminished? # => true
68
68
 
69
69
  # Side queries
70
- piece.first_player? # => true
71
- flipped.second_player? # => true
70
+ identifier.first_player? # => true
71
+ flipped.second_player? # => true
72
72
 
73
73
  # Attribute access
74
- piece.letter # => "K"
75
- enhanced.prefix # => "+"
76
- piece.prefix # => ""
74
+ identifier.letter # => "K"
75
+ enhanced.prefix # => "+"
76
+ identifier.prefix # => ""
77
77
 
78
78
  # Type and side comparison
79
79
  king1 = Sashite::Pin.parse("K")
80
80
  king2 = Sashite::Pin.parse("k")
81
81
  queen = Sashite::Pin.parse("Q")
82
82
 
83
- king1.same_type?(king2) # => true (both kings)
84
- king1.same_side?(queen) # => true (both first player)
85
- king1.same_type?(queen) # => false (different types)
83
+ king1.same_type?(king2) # => true (both kings)
84
+ king1.same_side?(queen) # => true (both first player)
85
+ king1.same_type?(queen) # => false (different types)
86
86
 
87
87
  # Functional transformations can be chained
88
88
  pawn = Sashite::Pin.parse("P")
89
- enemy_promoted = pawn.flip.enhance # => "+p" (second player promoted pawn)
89
+ enemy_promoted = pawn.flip.enhance # => "+p" (second player promoted pawn)
90
90
  ```
91
91
 
92
92
  ## Format Specification
93
93
 
94
94
  ### Structure
95
+
95
96
  ```
96
97
  [<state>]<letter>
97
98
  ```
98
99
 
99
100
  ### Components
100
101
 
101
- - **Letter** (`A-Z`, `a-z`): Represents piece type and side
102
- - Uppercase: First player pieces
103
- - Lowercase: Second player pieces
104
- - **State** (optional prefix):
105
- - `+`: Enhanced state (promoted, upgraded, empowered)
106
- - `-`: Diminished state (weakened, restricted, temporary)
107
- - No prefix: Normal state
108
-
109
- ### Regular Expression
110
- ```ruby
111
- /\A[-+]?[A-Za-z]\z/
112
- ```
102
+ * **Letter** (`A-Z`, `a-z`): Represents piece type and side
113
103
 
114
- ### Examples
115
- - `K` - First player king (normal state)
116
- - `k` - Second player king (normal state)
117
- - `+R` - First player rook (enhanced state)
118
- - `-p` - Second player pawn (diminished state)
104
+ * Uppercase: First player pieces
105
+ * Lowercase: Second player pieces
106
+ * **State** (optional prefix):
119
107
 
120
- ## Game Examples
108
+ * `+`: Enhanced state (promoted, upgraded, empowered)
109
+ * `-`: Diminished state (weakened, restricted, temporary)
110
+ * No prefix: Normal state
121
111
 
122
- ### Western Chess
123
- ```ruby
124
- # Standard pieces
125
- king = Sashite::Pin.piece(:K, :first, :normal) # => white king
126
- king.first_player? # => true
127
- king.type # => :K
128
-
129
- # State modifiers for special conditions
130
- castling_king = king.enhance # => castling-eligible king
131
- castling_king.to_s # => "+K"
132
-
133
- vulnerable_pawn = Sashite::Pin.piece(:P, :first, :diminished) # => en passant vulnerable
134
- vulnerable_pawn.to_s # => "-P"
135
-
136
- # All piece types
137
- piece_types = [:K, :Q, :R, :B, :N, :P]
138
- white_pieces = piece_types.map { |type| Sashite::Pin.piece(type, :first, :normal) }
139
- black_pieces = white_pieces.map(&:flip) # Convert to black pieces
140
- ```
112
+ ### Regular Expression
141
113
 
142
- ### Japanese Chess (Shōgi)
143
114
  ```ruby
144
- # Basic pieces
145
- rook = Sashite::Pin.piece(:R, :first, :normal) # => white rook
146
- bishop = Sashite::Pin.piece(:B, :first, :normal) # => white bishop
147
-
148
- # Promoted pieces (enhanced state)
149
- dragon_king = rook.enhance # => promoted rook (Dragon King)
150
- dragon_king.to_s # => "+R"
151
-
152
- dragon_horse = bishop.enhance # => promoted bishop (Dragon Horse)
153
- dragon_horse.to_s # => "+B"
154
-
155
- # Promoted pawn
156
- pawn = Sashite::Pin.piece(:P, :first, :normal)
157
- tokin = pawn.enhance # => promoted pawn (Tokin)
158
- tokin.to_s # => "+P"
159
-
160
- # All promotable pieces can use the same pattern
161
- promotable_types = [:R, :B, :S, :N, :L, :P]
162
- promotable = promotable_types.map { |type| Sashite::Pin.piece(type, :first, :normal) }
163
- promoted = promotable.map(&:enhance)
115
+ /\A[-+]?[A-Za-z]\z/
164
116
  ```
165
117
 
166
- ### Thai Chess (Makruk)
167
- ```ruby
168
- # Basic pieces
169
- met = Sashite::Pin.piece(:M, :first, :normal) # => white Met (queen)
170
- pawn = Sashite::Pin.piece(:P, :first, :normal) # => white Bia (pawn)
171
-
172
- # Promoted pawns
173
- bia_kaew = pawn.enhance # => promoted pawn (Bia Kaew)
174
- bia_kaew.to_s # => "+P"
175
-
176
- # Makruk pieces
177
- makruk_types = [:K, :M, :R, :B, :N, :P]
178
- makruk_pieces = makruk_types.map { |type| Sashite::Pin.piece(type, :first, :normal) }
179
- ```
118
+ ### Examples
180
119
 
181
- ### Chinese Chess (Xiangqi)
182
- ```ruby
183
- # Pieces with positional states
184
- general = Sashite::Pin.piece(:G, :first, :normal) # => red general
185
- flying_general = general.enhance # => flying general (special state)
186
- flying_general.to_s # => "+G"
187
-
188
- # Soldiers that crossed the river
189
- soldier = Sashite::Pin.piece(:P, :first, :normal)
190
- crossed_soldier = soldier.enhance # => soldier with enhanced movement
191
- crossed_soldier.to_s # => "+P"
192
- ```
120
+ * `K` - First player king (normal state)
121
+ * `k` - Second player king (normal state)
122
+ * `+R` - First player rook (enhanced state)
123
+ * `-p` - Second player pawn (diminished state)
193
124
 
194
125
  ## API Reference
195
126
 
196
127
  ### Main Module Methods
197
128
 
198
- - `Sashite::Pin.valid?(pin_string)` - Check if string is valid PIN notation
199
- - `Sashite::Pin.parse(pin_string)` - Parse PIN string into Piece object
200
- - `Sashite::Pin.piece(type, side, state = :normal)` - Create piece instance directly
129
+ * `Sashite::Pin.valid?(pin_string)` - Check if string is valid PIN notation
130
+ * `Sashite::Pin.parse(pin_string)` - Parse PIN string into Identifier object
131
+ * `Sashite::Pin.identifier(type, side, state = :normal)` - Create identifier instance directly
201
132
 
202
- ### Piece Class
133
+ ### Identifier Class
203
134
 
204
135
  #### Creation and Parsing
205
- - `Sashite::Pin::Piece.new(type, side, state = :normal)` - Create piece instance
206
- - `Sashite::Pin::Piece.parse(pin_string)` - Parse PIN string (same as module method)
207
- - `Sashite::Pin::Piece.valid?(pin_string)` - Validate PIN string (class method)
136
+
137
+ * `Sashite::Pin::Identifier.new(type, side, state = :normal)` - Create identifier instance
138
+ * `Sashite::Pin::Identifier.parse(pin_string)` - Parse PIN string (same as module method)
139
+ * `Sashite::Pin::Identifier.valid?(pin_string)` - Validate PIN string (class method)
208
140
 
209
141
  #### Attribute Access
210
- - `#type` - Get piece type (symbol :A to :Z, always uppercase)
211
- - `#side` - Get player side (:first or :second)
212
- - `#state` - Get state (:normal, :enhanced, or :diminished)
213
- - `#letter` - Get letter representation (string, case determined by side)
214
- - `#prefix` - Get state prefix (string: "+", "-", or "")
215
- - `#to_s` - Convert to PIN string representation
142
+
143
+ * `#type` - Get piece type (symbol \:A to \:Z, always uppercase)
144
+ * `#side` - Get player side (\:first or \:second)
145
+ * `#state` - Get state (\:normal, \:enhanced, or \:diminished)
146
+ * `#letter` - Get letter representation (string, case determined by side)
147
+ * `#prefix` - Get state prefix (string: "+", "-", or "")
148
+ * `#to_s` - Convert to PIN string representation
216
149
 
217
150
  #### Type and Case Handling
218
151
 
@@ -220,46 +153,52 @@ crossed_soldier.to_s # => "+P"
220
153
 
221
154
  ```ruby
222
155
  # Both create the same internal type representation
223
- piece1 = Sashite::Pin.parse("K") # type: :K, side: :first
224
- piece2 = Sashite::Pin.parse("k") # type: :K, side: :second
156
+ identifier1 = Sashite::Pin.parse("K") # type: :K, side: :first
157
+ identifier2 = Sashite::Pin.parse("k") # type: :K, side: :second
225
158
 
226
- piece1.type # => :K (uppercase symbol)
227
- piece2.type # => :K (same uppercase symbol)
159
+ identifier1.type # => :K (uppercase symbol)
160
+ identifier2.type # => :K (same uppercase symbol)
228
161
 
229
- piece1.letter # => "K" (uppercase display)
230
- piece2.letter # => "k" (lowercase display)
162
+ identifier1.letter # => "K" (uppercase display)
163
+ identifier2.letter # => "k" (lowercase display)
231
164
  ```
232
165
 
233
166
  #### State Queries
234
- - `#normal?` - Check if normal state (no modifiers)
235
- - `#enhanced?` - Check if enhanced state
236
- - `#diminished?` - Check if diminished state
167
+
168
+ * `#normal?` - Check if normal state (no modifiers)
169
+ * `#enhanced?` - Check if enhanced state
170
+ * `#diminished?` - Check if diminished state
237
171
 
238
172
  #### Side Queries
239
- - `#first_player?` - Check if first player piece
240
- - `#second_player?` - Check if second player piece
173
+
174
+ * `#first_player?` - Check if first player identifier
175
+ * `#second_player?` - Check if second player identifier
241
176
 
242
177
  #### State Transformations (immutable - return new instances)
243
- - `#enhance` - Create enhanced version
244
- - `#unenhance` - Remove enhanced state
245
- - `#diminish` - Create diminished version
246
- - `#undiminish` - Remove diminished state
247
- - `#normalize` - Remove all state modifiers
248
- - `#flip` - Switch player (change side)
178
+
179
+ * `#enhance` - Create enhanced version
180
+ * `#unenhance` - Remove enhanced state
181
+ * `#diminish` - Create diminished version
182
+ * `#undiminish` - Remove diminished state
183
+ * `#normalize` - Remove all state modifiers
184
+ * `#flip` - Switch player (change side)
249
185
 
250
186
  #### Attribute Transformations (immutable - return new instances)
251
- - `#with_type(new_type)` - Create piece with different type
252
- - `#with_side(new_side)` - Create piece with different side
253
- - `#with_state(new_state)` - Create piece with different state
187
+
188
+ * `#with_type(new_type)` - Create identifier with different type
189
+ * `#with_side(new_side)` - Create identifier with different side
190
+ * `#with_state(new_state)` - Create identifier with different state
254
191
 
255
192
  #### Comparison Methods
256
- - `#same_type?(other)` - Check if same piece type
257
- - `#same_side?(other)` - Check if same side
258
- - `#same_state?(other)` - Check if same state
259
- - `#==(other)` - Full equality comparison
193
+
194
+ * `#same_type?(other)` - Check if same piece type
195
+ * `#same_side?(other)` - Check if same side
196
+ * `#same_state?(other)` - Check if same state
197
+ * `#==(other)` - Full equality comparison
260
198
 
261
199
  ### Constants
262
- - `Sashite::Pin::Piece::PIN_PATTERN` - Regular expression for PIN validation (internal use)
200
+
201
+ * `Sashite::Pin::Identifier::PIN_PATTERN` - Regular expression for PIN validation (internal use)
263
202
 
264
203
  ## Advanced Usage
265
204
 
@@ -2,9 +2,9 @@
2
2
 
3
3
  module Sashite
4
4
  module Pin
5
- # Represents a piece in PIN (Piece Identifier Notation) format.
5
+ # Represents an identifier in PIN (Piece Identifier Notation) format.
6
6
  #
7
- # A piece consists of a single ASCII letter with optional state modifiers:
7
+ # An identifier consists of a single ASCII letter with optional state modifiers:
8
8
  # - Enhanced state: prefix '+'
9
9
  # - Diminished state: prefix '-'
10
10
  # - Normal state: no modifier
@@ -15,7 +15,7 @@ module Sashite
15
15
  #
16
16
  # All instances are immutable - state manipulation methods return new instances.
17
17
  # This follows the Game Protocol's piece model with Type, Side, and State attributes.
18
- class Piece
18
+ class Identifier
19
19
  # PIN validation pattern matching the specification
20
20
  PIN_PATTERN = /\A(?<prefix>[-+])?(?<letter>[a-zA-Z])\z/
21
21
 
@@ -57,7 +57,7 @@ module Sashite
57
57
  # @return [Symbol] the piece state (:normal, :enhanced, or :diminished)
58
58
  attr_reader :state
59
59
 
60
- # Create a new piece instance
60
+ # Create a new identifier instance
61
61
  #
62
62
  # @param type [Symbol] piece type (:A to :Z)
63
63
  # @param side [Symbol] player side (:first or :second)
@@ -75,15 +75,15 @@ module Sashite
75
75
  freeze
76
76
  end
77
77
 
78
- # Parse a PIN string into a Piece object
78
+ # Parse a PIN string into an Identifier object
79
79
  #
80
80
  # @param pin_string [String] PIN notation string
81
- # @return [Piece] new piece instance
81
+ # @return [Identifier] new identifier instance
82
82
  # @raise [ArgumentError] if the PIN string is invalid
83
83
  # @example
84
- # Pin::Piece.parse("k") # => #<Pin::Piece type=:K side=:second state=:normal>
85
- # Pin::Piece.parse("+R") # => #<Pin::Piece type=:R side=:first state=:enhanced>
86
- # Pin::Piece.parse("-p") # => #<Pin::Piece type=:P side=:second state=:diminished>
84
+ # Pin::Identifier.parse("k") # => #<Pin::Identifier type=:K side=:second state=:normal>
85
+ # Pin::Identifier.parse("+R") # => #<Pin::Identifier type=:R side=:first state=:enhanced>
86
+ # Pin::Identifier.parse("-p") # => #<Pin::Identifier type=:P side=:second state=:diminished>
87
87
  def self.parse(pin_string)
88
88
  string_value = String(pin_string)
89
89
  matches = match_pattern(string_value)
@@ -92,18 +92,17 @@ module Sashite
92
92
  enhanced = matches[:prefix] == ENHANCED_PREFIX
93
93
  diminished = matches[:prefix] == DIMINISHED_PREFIX
94
94
 
95
- # Extract type and side from letter
96
- piece_type = letter.upcase.to_sym
97
- piece_side = letter == letter.upcase ? FIRST_PLAYER : SECOND_PLAYER
98
- piece_state = if enhanced
99
- ENHANCED_STATE
100
- elsif diminished
101
- DIMINISHED_STATE
102
- else
103
- NORMAL_STATE
104
- end
105
-
106
- new(piece_type, piece_side, piece_state)
95
+ type = letter.upcase.to_sym
96
+ side = letter == letter.upcase ? FIRST_PLAYER : SECOND_PLAYER
97
+ state = if enhanced
98
+ ENHANCED_STATE
99
+ elsif diminished
100
+ DIMINISHED_STATE
101
+ else
102
+ NORMAL_STATE
103
+ end
104
+
105
+ new(type, side, state)
107
106
  end
108
107
 
109
108
  # Check if a string is a valid PIN notation
@@ -112,24 +111,22 @@ module Sashite
112
111
  # @return [Boolean] true if valid PIN, false otherwise
113
112
  #
114
113
  # @example
115
- # Sashite::Pin::Piece.valid?("K") # => true
116
- # Sashite::Pin::Piece.valid?("+R") # => true
117
- # Sashite::Pin::Piece.valid?("-p") # => true
118
- # Sashite::Pin::Piece.valid?("KK") # => false
119
- # Sashite::Pin::Piece.valid?("++K") # => false
114
+ # Sashite::Pin::Identifier.valid?("K") # => true
115
+ # Sashite::Pin::Identifier.valid?("+R") # => true
116
+ # Sashite::Pin::Identifier.valid?("-p") # => true
117
+ # Sashite::Pin::Identifier.valid?("KK") # => false
118
+ # Sashite::Pin::Identifier.valid?("++K") # => false
120
119
  def self.valid?(pin_string)
121
120
  return false unless pin_string.is_a?(::String)
122
121
 
123
122
  pin_string.match?(PIN_PATTERN)
124
123
  end
125
124
 
126
- # Convert the piece to its PIN string representation
125
+ # Convert the identifier to its PIN string representation
127
126
  #
128
127
  # @return [String] PIN notation string
129
128
  # @example
130
- # piece.to_s # => "+R"
131
- # piece.to_s # => "-p"
132
- # piece.to_s # => "K"
129
+ # identifier.to_s # => "+R"
133
130
  def to_s
134
131
  "#{prefix}#{letter}"
135
132
  end
@@ -152,76 +149,62 @@ module Sashite
152
149
  end
153
150
  end
154
151
 
155
- # Create a new piece with enhanced state
152
+ # Create a new identifier with enhanced state
156
153
  #
157
- # @return [Piece] new piece instance with enhanced state
158
- # @example
159
- # piece.enhance # (:K, :first, :normal) => (:K, :first, :enhanced)
154
+ # @return [Identifier] new identifier instance with enhanced state
160
155
  def enhance
161
156
  return self if enhanced?
162
157
 
163
158
  self.class.new(type, side, ENHANCED_STATE)
164
159
  end
165
160
 
166
- # Create a new piece without enhanced state
161
+ # Create a new identifier without enhanced state
167
162
  #
168
- # @return [Piece] new piece instance without enhanced state
169
- # @example
170
- # piece.unenhance # (:K, :first, :enhanced) => (:K, :first, :normal)
163
+ # @return [Identifier] new identifier instance with normal state
171
164
  def unenhance
172
165
  return self unless enhanced?
173
166
 
174
167
  self.class.new(type, side, NORMAL_STATE)
175
168
  end
176
169
 
177
- # Create a new piece with diminished state
170
+ # Create a new identifier with diminished state
178
171
  #
179
- # @return [Piece] new piece instance with diminished state
180
- # @example
181
- # piece.diminish # (:K, :first, :normal) => (:K, :first, :diminished)
172
+ # @return [Identifier] new identifier instance with diminished state
182
173
  def diminish
183
174
  return self if diminished?
184
175
 
185
176
  self.class.new(type, side, DIMINISHED_STATE)
186
177
  end
187
178
 
188
- # Create a new piece without diminished state
179
+ # Create a new identifier without diminished state
189
180
  #
190
- # @return [Piece] new piece instance without diminished state
191
- # @example
192
- # piece.undiminish # (:K, :first, :diminished) => (:K, :first, :normal)
181
+ # @return [Identifier] new identifier instance with normal state
193
182
  def undiminish
194
183
  return self unless diminished?
195
184
 
196
185
  self.class.new(type, side, NORMAL_STATE)
197
186
  end
198
187
 
199
- # Create a new piece with normal state (no modifiers)
188
+ # Create a new identifier with normal state (no modifiers)
200
189
  #
201
- # @return [Piece] new piece instance with normal state
202
- # @example
203
- # piece.normalize # (:K, :first, :enhanced) => (:K, :first, :normal)
190
+ # @return [Identifier] new identifier instance with normal state
204
191
  def normalize
205
192
  return self if normal?
206
193
 
207
194
  self.class.new(type, side, NORMAL_STATE)
208
195
  end
209
196
 
210
- # Create a new piece with opposite side
197
+ # Create a new identifier with opposite side
211
198
  #
212
- # @return [Piece] new piece instance with opposite side
213
- # @example
214
- # piece.flip # (:K, :first, :normal) => (:K, :second, :normal)
199
+ # @return [Identifier] new identifier instance with opposite side
215
200
  def flip
216
201
  self.class.new(type, opposite_side, state)
217
202
  end
218
203
 
219
- # Create a new piece with a different type (keeping same side and state)
204
+ # Create a new identifier with a different type
220
205
  #
221
206
  # @param new_type [Symbol] new type (:A to :Z)
222
- # @return [Piece] new piece instance with different type
223
- # @example
224
- # piece.with_type(:Q) # (:K, :first, :normal) => (:Q, :first, :normal)
207
+ # @return [Identifier] new identifier instance with new type
225
208
  def with_type(new_type)
226
209
  self.class.validate_type(new_type)
227
210
  return self if type == new_type
@@ -229,12 +212,10 @@ module Sashite
229
212
  self.class.new(new_type, side, state)
230
213
  end
231
214
 
232
- # Create a new piece with a different side (keeping same type and state)
215
+ # Create a new identifier with a different side
233
216
  #
234
- # @param new_side [Symbol] :first or :second
235
- # @return [Piece] new piece instance with different side
236
- # @example
237
- # piece.with_side(:second) # (:K, :first, :normal) => (:K, :second, :normal)
217
+ # @param new_side [Symbol] new side (:first or :second)
218
+ # @return [Identifier] new identifier instance with new side
238
219
  def with_side(new_side)
239
220
  self.class.validate_side(new_side)
240
221
  return self if side == new_side
@@ -242,12 +223,10 @@ module Sashite
242
223
  self.class.new(type, new_side, state)
243
224
  end
244
225
 
245
- # Create a new piece with a different state (keeping same type and side)
226
+ # Create a new identifier with a different state
246
227
  #
247
- # @param new_state [Symbol] :normal, :enhanced, or :diminished
248
- # @return [Piece] new piece instance with different state
249
- # @example
250
- # piece.with_state(:enhanced) # (:K, :first, :normal) => (:K, :first, :enhanced)
228
+ # @param new_state [Symbol] new state (:normal, :enhanced, or :diminished)
229
+ # @return [Identifier] new identifier instance with new state
251
230
  def with_state(new_state)
252
231
  self.class.validate_state(new_state)
253
232
  return self if state == new_state
@@ -255,56 +234,54 @@ module Sashite
255
234
  self.class.new(type, side, new_state)
256
235
  end
257
236
 
258
- # Check if the piece has enhanced state
237
+ # Check if the identifier has enhanced state
259
238
  #
260
239
  # @return [Boolean] true if enhanced
261
240
  def enhanced?
262
241
  state == ENHANCED_STATE
263
242
  end
264
243
 
265
- # Check if the piece has diminished state
244
+ # Check if the identifier has diminished state
266
245
  #
267
246
  # @return [Boolean] true if diminished
268
247
  def diminished?
269
248
  state == DIMINISHED_STATE
270
249
  end
271
250
 
272
- # Check if the piece has normal state (no modifiers)
251
+ # Check if the identifier has normal state
273
252
  #
274
- # @return [Boolean] true if no modifiers are present
253
+ # @return [Boolean] true if normal
275
254
  def normal?
276
255
  state == NORMAL_STATE
277
256
  end
278
257
 
279
- # Check if the piece belongs to the first player
258
+ # Check if the identifier belongs to the first player
280
259
  #
281
260
  # @return [Boolean] true if first player
282
261
  def first_player?
283
262
  side == FIRST_PLAYER
284
263
  end
285
264
 
286
- # Check if the piece belongs to the second player
265
+ # Check if the identifier belongs to the second player
287
266
  #
288
267
  # @return [Boolean] true if second player
289
268
  def second_player?
290
269
  side == SECOND_PLAYER
291
270
  end
292
271
 
293
- # Check if this piece is the same type as another (ignoring side and state)
272
+ # Check if this identifier is the same type as another
294
273
  #
295
- # @param other [Piece] piece to compare with
274
+ # @param other [Identifier] identifier to compare with
296
275
  # @return [Boolean] true if same type
297
- # @example
298
- # king1.same_type?(king2) # (:K, :first, :normal) and (:K, :second, :enhanced) => true
299
276
  def same_type?(other)
300
277
  return false unless other.is_a?(self.class)
301
278
 
302
279
  type == other.type
303
280
  end
304
281
 
305
- # Check if this piece belongs to the same side as another
282
+ # Check if this identifier has the same side as another
306
283
  #
307
- # @param other [Piece] piece to compare with
284
+ # @param other [Identifier] identifier to compare with
308
285
  # @return [Boolean] true if same side
309
286
  def same_side?(other)
310
287
  return false unless other.is_a?(self.class)
@@ -312,9 +289,9 @@ module Sashite
312
289
  side == other.side
313
290
  end
314
291
 
315
- # Check if this piece has the same state as another
292
+ # Check if this identifier has the same state as another
316
293
  #
317
- # @param other [Piece] piece to compare with
294
+ # @param other [Identifier] identifier to compare with
318
295
  # @return [Boolean] true if same state
319
296
  def same_state?(other)
320
297
  return false unless other.is_a?(self.class)
@@ -325,7 +302,7 @@ module Sashite
325
302
  # Custom equality comparison
326
303
  #
327
304
  # @param other [Object] object to compare with
328
- # @return [Boolean] true if pieces are equal
305
+ # @return [Boolean] true if identifiers are equal
329
306
  def ==(other)
330
307
  return false unless other.is_a?(self.class)
331
308
 
@@ -388,7 +365,7 @@ module Sashite
388
365
 
389
366
  private
390
367
 
391
- # Get the opposite side of the current piece
368
+ # Get the opposite side of the current identifier
392
369
  #
393
370
  # @return [Symbol] :first if current side is :second, :second if current side is :first
394
371
  def opposite_side
data/lib/sashite/pin.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "pin/piece"
3
+ require_relative "pin/identifier"
4
4
 
5
5
  module Sashite
6
6
  # PIN (Piece Identifier Notation) implementation for Ruby
@@ -32,35 +32,35 @@ module Sashite
32
32
  # Sashite::Pin.valid?("KK") # => false
33
33
  # Sashite::Pin.valid?("++K") # => false
34
34
  def self.valid?(pin_string)
35
- Piece.valid?(pin_string)
35
+ Identifier.valid?(pin_string)
36
36
  end
37
37
 
38
- # Parse a PIN string into a Piece object
38
+ # Parse a PIN string into an Identifier object
39
39
  #
40
40
  # @param pin_string [String] PIN notation string
41
- # @return [Pin::Piece] new piece instance
41
+ # @return [Pin::Identifier] new identifier instance
42
42
  # @raise [ArgumentError] if the PIN string is invalid
43
43
  # @example
44
- # Sashite::Pin.parse("K") # => #<Pin::Piece type=:K side=:first state=:normal>
45
- # Sashite::Pin.parse("+R") # => #<Pin::Piece type=:R side=:first state=:enhanced>
46
- # Sashite::Pin.parse("-p") # => #<Pin::Piece type=:P side=:second state=:diminished>
44
+ # Sashite::Pin.parse("K") # => #<Pin::Identifier type=:K side=:first state=:normal>
45
+ # Sashite::Pin.parse("+R") # => #<Pin::Identifier type=:R side=:first state=:enhanced>
46
+ # Sashite::Pin.parse("-p") # => #<Pin::Identifier type=:P side=:second state=:diminished>
47
47
  def self.parse(pin_string)
48
- Piece.parse(pin_string)
48
+ Identifier.parse(pin_string)
49
49
  end
50
50
 
51
- # Create a new piece instance
51
+ # Create a new identifier instance
52
52
  #
53
53
  # @param type [Symbol] piece type (:A to :Z)
54
54
  # @param side [Symbol] player side (:first or :second)
55
55
  # @param state [Symbol] piece state (:normal, :enhanced, or :diminished)
56
- # @return [Pin::Piece] new piece instance
56
+ # @return [Pin::Identifier] new identifier instance
57
57
  # @raise [ArgumentError] if parameters are invalid
58
58
  # @example
59
- # Sashite::Pin.piece(:K, :first, :normal) # => #<Pin::Piece type=:K side=:first state=:normal>
60
- # Sashite::Pin.piece(:R, :first, :enhanced) # => #<Pin::Piece type=:R side=:first state=:enhanced>
61
- # Sashite::Pin.piece(:P, :second, :diminished) # => #<Pin::Piece type=:P side=:second state=:diminished>
62
- def self.piece(type, side, state = :normal)
63
- Piece.new(type, side, state)
59
+ # Sashite::Pin.identifier(:K, :first, :normal) # => #<Pin::Identifier type=:K side=:first state=:normal>
60
+ # Sashite::Pin.identifier(:R, :first, :enhanced) # => #<Pin::Identifier type=:R side=:first state=:enhanced>
61
+ # Sashite::Pin.identifier(:P, :second, :diminished) # => #<Pin::Identifier type=:P side=:second state=:diminished>
62
+ def self.identifier(type, side, state = :normal)
63
+ Identifier.new(type, side, state)
64
64
  end
65
65
  end
66
66
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sashite-pin
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cyril Kato
@@ -10,13 +10,13 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: |
13
- PIN (Piece Identifier Notation) provides an ASCII-based format for representing pieces
13
+ PIN (Piece Identifier Notation) provides a rule-agnostic format for identifying pieces
14
14
  in abstract strategy board games. This gem implements the PIN Specification v1.0.0 with
15
- a modern Ruby interface featuring immutable piece objects and functional programming
16
- principles. PIN translates piece attributes from the Game Protocol into a compact,
17
- portable notation system using ASCII letters with optional state modifiers and
18
- case-based side encoding. Perfect for game engines, board game notation systems,
19
- and multi-game environments.
15
+ a modern Ruby interface featuring immutable identifier objects and functional programming
16
+ principles. PIN uses single ASCII letters with optional state modifiers and case-based
17
+ side encoding (A-Z for first player, a-z for second player), enabling precise and portable
18
+ identification of pieces across multiple games. Perfect for game engines, board game notation
19
+ systems, and hybrid gaming platforms requiring compact, stateful piece representation.
20
20
  email: contact@cyril.email
21
21
  executables: []
22
22
  extensions: []
@@ -26,7 +26,7 @@ files:
26
26
  - README.md
27
27
  - lib/sashite-pin.rb
28
28
  - lib/sashite/pin.rb
29
- - lib/sashite/pin/piece.rb
29
+ - lib/sashite/pin/identifier.rb
30
30
  homepage: https://github.com/sashite/pin.rb
31
31
  licenses:
32
32
  - MIT
@@ -53,6 +53,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
53
  requirements: []
54
54
  rubygems_version: 3.6.9
55
55
  specification_version: 4
56
- summary: PIN (Piece Identifier Notation) implementation for Ruby with immutable piece
56
+ summary: PIN (Piece Identifier Notation) implementation for Ruby with immutable identifier
57
57
  objects
58
58
  test_files: []