Class: Sashite::Epin
- Inherits:
-
Object
- Object
- Sashite::Epin
- Defined in:
- lib/sashite/epin.rb
Overview
EPIN (Extended Piece Identifier Notation) implementation for Ruby.
EPIN extends PIN by adding a **derivation marker** to track piece style in cross-style games.
**EPIN is simply: PIN + optional style derivation marker (‘’‘)**
Format
<pin-token>[<derivation-marker>]
Where <pin-token> is a valid PIN token and <derivation-marker> is an optional trailing apostrophe (').
Five Fundamental Attributes
EPIN exposes all five attributes from the Sashité Game Protocol:
-
*Piece Name* ↑
epin.pin.type -
*Piece Side* ↑
epin.pin.side -
*Piece State* ↑
epin.pin.state -
*Terminal Status* ↑
epin.pin.terminal -
*Piece Style* ↑
epin.derived(native vs derived)
Examples
epin = Sashite::Epin.parse("K^'")
epin.pin.type # => :K
epin.pin.terminal # => true
epin.derived # => true
pin = Sashite::Pin.parse("K^")
epin = Sashite::Epin.new(pin, derived: true)
epin.to_s # => "K^'"
Sashite::Epin.valid?("K^'") # => true
Sashite::Epin.valid?("K'^") # => false
See the EPIN Specification (sashite.dev/specs/epin/1.0.0/) for details.
Constant Summary collapse
- EPIN_PATTERN =
Pattern for validating EPIN strings
/\A(?<pin>[-+]?[A-Za-z]\^?)(?<derived>')?\z/
Instance Attribute Summary collapse
-
#derived ⇒ Boolean
readonly
Derivation status (true = derived, false = native).
-
#pin ⇒ Sashite::Pin
readonly
The underlying PIN component.
Class Method Summary collapse
-
.parse(epin_string) ⇒ Epin
Parses an EPIN string into an Epin instance.
-
.valid?(epin_string) ⇒ Boolean
Checks if a string is a valid EPIN notation.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
(also: #eql?)
Checks equality with another Epin.
-
#derived? ⇒ Boolean
Checks if the Epin is derived (uses opponent’s style).
-
#hash ⇒ Integer
Returns a hash code for the Epin.
-
#initialize(pin, derived: false) ⇒ Epin
constructor
Creates a new EPIN instance from a PIN component.
-
#inspect ⇒ String
Returns an inspect string for the Epin.
-
#mark_derived ⇒ Epin
Returns a new Epin marked as derived.
-
#native? ⇒ Boolean
Checks if the Epin is native (uses own side’s style).
-
#same_derived?(other) ⇒ Boolean
Checks if two Epins have the same derivation status.
-
#to_s ⇒ String
Converts the Epin to its string representation.
-
#unmark_derived ⇒ Epin
Returns a new Epin marked as native (not derived).
-
#with_derived(new_derived) ⇒ Epin
Returns a new Epin with a different derivation status.
-
#with_pin(new_pin) ⇒ Epin
Returns a new Epin with a different PIN component.
Constructor Details
#initialize(pin, derived: false) ⇒ Epin
Creates a new EPIN instance from a PIN component.
72 73 74 75 76 77 78 79 |
# File 'lib/sashite/epin.rb', line 72 def initialize(pin, derived: false) raise ArgumentError, "Expected a Sashite::Pin instance, got: #{pin.inspect}" unless pin.is_a?(Pin) @pin = pin @derived = !!derived freeze end |
Instance Attribute Details
#derived ⇒ Boolean (readonly)
Returns Derivation status (true = derived, false = native).
53 54 55 |
# File 'lib/sashite/epin.rb', line 53 def derived @derived end |
#pin ⇒ Sashite::Pin (readonly)
Returns The underlying PIN component.
50 51 52 |
# File 'lib/sashite/epin.rb', line 50 def pin @pin end |
Class Method Details
.parse(epin_string) ⇒ Epin
Parses an EPIN string into an Epin instance.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/sashite/epin.rb', line 99 def self.parse(epin_string) raise ArgumentError, "Invalid EPIN string: #{epin_string.inspect}" unless epin_string.is_a?(String) match = EPIN_PATTERN.match(epin_string) raise ArgumentError, "Invalid EPIN string: #{epin_string}" unless match pin_string = match[:pin] derived_marker = match[:derived] pin = Pin.parse(pin_string) derived = derived_marker == "'" new(pin, derived: derived) end |
.valid?(epin_string) ⇒ Boolean
Checks if a string is a valid EPIN notation.
126 127 128 129 130 |
# File 'lib/sashite/epin.rb', line 126 def self.valid?(epin_string) return false unless epin_string.is_a?(String) EPIN_PATTERN.match?(epin_string) end |
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
Checks equality with another Epin.
270 271 272 273 274 |
# File 'lib/sashite/epin.rb', line 270 def ==(other) return false unless other.is_a?(self.class) pin == other.pin && derived == other.derived end |
#derived? ⇒ Boolean
Checks if the Epin is derived (uses opponent’s style).
229 230 231 |
# File 'lib/sashite/epin.rb', line 229 def derived? derived end |
#hash ⇒ Integer
Returns a hash code for the Epin.
281 282 283 |
# File 'lib/sashite/epin.rb', line 281 def hash [pin, derived].hash end |
#inspect ⇒ String
Returns an inspect string for the Epin.
288 289 290 |
# File 'lib/sashite/epin.rb', line 288 def inspect "#<#{self.class} #{self}>" end |
#mark_derived ⇒ Epin
Returns a new Epin marked as derived.
198 199 200 201 202 |
# File 'lib/sashite/epin.rb', line 198 def mark_derived return self if derived self.class.new(pin, derived: true) end |
#native? ⇒ Boolean
Checks if the Epin is native (uses own side’s style).
240 241 242 |
# File 'lib/sashite/epin.rb', line 240 def native? !derived end |
#same_derived?(other) ⇒ Boolean
Checks if two Epins have the same derivation status.
258 259 260 |
# File 'lib/sashite/epin.rb', line 258 def same_derived?(other) derived == other.derived end |
#to_s ⇒ String
Converts the Epin to its string representation.
147 148 149 |
# File 'lib/sashite/epin.rb', line 147 def to_s "#{pin}#{derivation_suffix}" end |
#unmark_derived ⇒ Epin
Returns a new Epin marked as native (not derived).
212 213 214 215 216 |
# File 'lib/sashite/epin.rb', line 212 def unmark_derived return self unless derived self.class.new(pin, derived: false) end |
#with_derived(new_derived) ⇒ Epin
Returns a new Epin with a different derivation status.
184 185 186 187 188 |
# File 'lib/sashite/epin.rb', line 184 def with_derived(new_derived) return self if derived == !!new_derived self.class.new(pin, derived: !!new_derived) end |
#with_pin(new_pin) ⇒ Epin
Returns a new Epin with a different PIN component.
165 166 167 168 169 |
# File 'lib/sashite/epin.rb', line 165 def with_pin(new_pin) return self if pin == new_pin self.class.new(new_pin, derived: derived) end |