sashite-pin 2.0.0 → 2.0.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 +82 -7
- data/lib/sashite/pin/piece.rb +10 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0335d119541a7fa271689c6235a9c785a4c46f6c70e9577d4cddcc597d520dd5
|
4
|
+
data.tar.gz: 7d95e04c803457156561bfe0fd8e270db5df1929b58721b9ed8266646f60e7e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6904c80bee041595400f4074ed48a975ad6337c3c5a8c66f9d18ad7864f19e23d04e34b30c725d37ce9c4bfde58667328a82bbd1c38208c123cb44a9da00b283
|
7
|
+
data.tar.gz: 32289d6453d81ff2e1920aeb7d69eedfac6bc61f9acdd1929e7ca4bc09c6988bb2a64bc3620130cfb63024977e0508b7c5ffce695590382eac3420d85454c67a
|
data/README.md
CHANGED
@@ -206,13 +206,29 @@ crossed_soldier.to_s # => "+P"
|
|
206
206
|
- `Sashite::Pin::Piece.parse(pin_string)` - Parse PIN string (same as module method)
|
207
207
|
|
208
208
|
#### Attribute Access
|
209
|
-
- `#type` - Get piece type (symbol :A to :Z)
|
209
|
+
- `#type` - Get piece type (symbol :A to :Z, always uppercase)
|
210
210
|
- `#side` - Get player side (:first or :second)
|
211
211
|
- `#state` - Get state (:normal, :enhanced, or :diminished)
|
212
|
-
- `#letter` - Get letter representation (string)
|
212
|
+
- `#letter` - Get letter representation (string, case determined by side)
|
213
213
|
- `#prefix` - Get state prefix (string: "+", "-", or "")
|
214
214
|
- `#to_s` - Convert to PIN string representation
|
215
215
|
|
216
|
+
#### Type and Case Handling
|
217
|
+
|
218
|
+
**Important**: The `type` attribute is always stored as an uppercase symbol (`:A` to `:Z`), regardless of the input case when parsing. The display case in `#letter` and `#to_s` is determined by the `side` attribute:
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
# Both create the same internal type representation
|
222
|
+
piece1 = Sashite::Pin.parse("K") # type: :K, side: :first
|
223
|
+
piece2 = Sashite::Pin.parse("k") # type: :K, side: :second
|
224
|
+
|
225
|
+
piece1.type # => :K (uppercase symbol)
|
226
|
+
piece2.type # => :K (same uppercase symbol)
|
227
|
+
|
228
|
+
piece1.letter # => "K" (uppercase display)
|
229
|
+
piece2.letter # => "k" (lowercase display)
|
230
|
+
```
|
231
|
+
|
216
232
|
#### State Queries
|
217
233
|
- `#normal?` - Check if normal state (no modifiers)
|
218
234
|
- `#enhanced?` - Check if enhanced state
|
@@ -246,6 +262,30 @@ crossed_soldier.to_s # => "+P"
|
|
246
262
|
|
247
263
|
## Advanced Usage
|
248
264
|
|
265
|
+
### Type Normalization Examples
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
# Parsing different cases results in same type
|
269
|
+
white_king = Sashite::Pin.parse("K")
|
270
|
+
black_king = Sashite::Pin.parse("k")
|
271
|
+
|
272
|
+
# Types are normalized to uppercase
|
273
|
+
white_king.type # => :K
|
274
|
+
black_king.type # => :K (same type!)
|
275
|
+
|
276
|
+
# Sides are different
|
277
|
+
white_king.side # => :first
|
278
|
+
black_king.side # => :second
|
279
|
+
|
280
|
+
# Display follows side convention
|
281
|
+
white_king.letter # => "K"
|
282
|
+
black_king.letter # => "k"
|
283
|
+
|
284
|
+
# Same type, different sides
|
285
|
+
white_king.same_type?(black_king) # => true
|
286
|
+
white_king.same_side?(black_king) # => false
|
287
|
+
```
|
288
|
+
|
249
289
|
### Immutable Transformations
|
250
290
|
```ruby
|
251
291
|
# All transformations return new instances
|
@@ -356,11 +396,15 @@ puts can_promote?(promoted_pawn, 8) # => false (already promoted)
|
|
356
396
|
|
357
397
|
Following the [Game Protocol](https://sashite.dev/game-protocol/):
|
358
398
|
|
359
|
-
| Protocol Attribute | PIN Encoding | Examples |
|
360
|
-
|
361
|
-
| **Type** |
|
362
|
-
| **Side** |
|
363
|
-
| **State** |
|
399
|
+
| Protocol Attribute | PIN Encoding | Examples | Notes |
|
400
|
+
|-------------------|--------------|----------|-------|
|
401
|
+
| **Type** | ASCII letter choice | `K`/`k` = King, `P`/`p` = Pawn | Type is always stored as uppercase symbol (`:K`, `:P`) |
|
402
|
+
| **Side** | Letter case in display | `K` = First player, `k` = Second player | Case is determined by side during rendering |
|
403
|
+
| **State** | Optional prefix | `+K` = Enhanced, `-K` = Diminished, `K` = Normal | |
|
404
|
+
|
405
|
+
**Type Convention**: All piece types are internally represented as uppercase symbols (`:A` to `:Z`). The display case is determined by the `side` attribute: first player pieces display as uppercase, second player pieces as lowercase.
|
406
|
+
|
407
|
+
**Canonical principle**: Identical pieces must have identical PIN representations.
|
364
408
|
|
365
409
|
**Note**: PIN does not represent the **Style** attribute from the Game Protocol. For style-aware piece notation, see [Piece Name Notation (PNN)](https://sashite.dev/specs/pnn/).
|
366
410
|
|
@@ -370,10 +414,41 @@ Following the [Game Protocol](https://sashite.dev/game-protocol/):
|
|
370
414
|
* **Rule-Agnostic**: Independent of specific game mechanics
|
371
415
|
* **Compact Format**: 1-2 characters per piece
|
372
416
|
* **Visual Distinction**: Clear player differentiation through case
|
417
|
+
* **Type Normalization**: Consistent uppercase type representation internally
|
373
418
|
* **Protocol Compliant**: Direct implementation of Sashité piece attributes
|
374
419
|
* **Immutable**: All piece instances are frozen and transformations return new objects
|
375
420
|
* **Functional**: Pure functions with no side effects
|
376
421
|
|
422
|
+
## Implementation Notes
|
423
|
+
|
424
|
+
### Type Normalization Convention
|
425
|
+
|
426
|
+
PIN follows a strict type normalization convention:
|
427
|
+
|
428
|
+
1. **Internal Storage**: All piece types are stored as uppercase symbols (`:A` to `:Z`)
|
429
|
+
2. **Input Flexibility**: Both `"K"` and `"k"` are valid input during parsing
|
430
|
+
3. **Case Semantics**: Input case determines the `side` attribute, not the `type`
|
431
|
+
4. **Display Logic**: Output case is computed from `side` during rendering
|
432
|
+
|
433
|
+
This design ensures:
|
434
|
+
- Consistent internal representation regardless of input format
|
435
|
+
- Clear separation between piece identity (type) and ownership (side)
|
436
|
+
- Predictable behavior when comparing pieces of the same type
|
437
|
+
|
438
|
+
### Example Flow
|
439
|
+
|
440
|
+
```ruby
|
441
|
+
# Input: "k" (lowercase)
|
442
|
+
# ↓ Parsing
|
443
|
+
# type: :K (normalized to uppercase)
|
444
|
+
# side: :second (inferred from lowercase input)
|
445
|
+
# ↓ Display
|
446
|
+
# letter: "k" (computed from type + side)
|
447
|
+
# PIN: "k" (final representation)
|
448
|
+
```
|
449
|
+
|
450
|
+
This ensures that `parse(pin).to_s == pin` for all valid PIN strings while maintaining internal consistency.
|
451
|
+
|
377
452
|
## System Constraints
|
378
453
|
|
379
454
|
- **Maximum 26 piece types** per game system (one per ASCII letter)
|
data/lib/sashite/pin/piece.rb
CHANGED
@@ -196,8 +196,7 @@ module Sashite
|
|
196
196
|
# @example
|
197
197
|
# piece.flip # (:K, :first, :normal) => (:K, :second, :normal)
|
198
198
|
def flip
|
199
|
-
|
200
|
-
self.class.new(type, new_side, state)
|
199
|
+
self.class.new(type, opposite_side, state)
|
201
200
|
end
|
202
201
|
|
203
202
|
# Create a new piece with a different type (keeping same side and state)
|
@@ -369,6 +368,15 @@ module Sashite
|
|
369
368
|
end
|
370
369
|
|
371
370
|
private_class_method :match_pattern
|
371
|
+
|
372
|
+
private
|
373
|
+
|
374
|
+
# Get the opposite side of the current piece
|
375
|
+
#
|
376
|
+
# @return [Symbol] :first if current side is :second, :second if current side is :first
|
377
|
+
def opposite_side
|
378
|
+
first_player? ? SECOND_PLAYER : FIRST_PLAYER
|
379
|
+
end
|
372
380
|
end
|
373
381
|
end
|
374
382
|
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.
|
4
|
+
version: 2.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cyril Kato
|
@@ -15,7 +15,8 @@ description: |
|
|
15
15
|
a modern Ruby interface featuring immutable piece objects and functional programming
|
16
16
|
principles. PIN translates piece attributes from the Game Protocol into a compact,
|
17
17
|
portable notation system using ASCII letters with optional state modifiers and
|
18
|
-
case-based
|
18
|
+
case-based side encoding. Perfect for game engines, board game notation systems,
|
19
|
+
and multi-game environments.
|
19
20
|
email: contact@cyril.email
|
20
21
|
executables: []
|
21
22
|
extensions: []
|