Class: Sashite::Qpi::Identifier

Inherits:
Object
  • Object
show all
Defined in:
lib/sashite/qpi/identifier.rb

Overview

Represents a parsed QPI (Qualified Piece Identifier) identifier.

A QPI identifier encodes complete Piece Identity by combining:

  • A SIN (Style Identifier Notation) component for Piece Style

  • A PIN (Piece Identifier Notation) component for Piece Name, Side, State, and Terminal Status

Additionally, QPI defines a Native/Derived relationship based on case comparison between the SIN and PIN letters.

Instances are immutable (frozen after creation).

Examples:

Creating identifiers

sin = Sashite::Sin.parse("C")
pin = Sashite::Pin.parse("K^")
qpi = Identifier.new(sin, pin)

Accessing components

qpi.sin.abbr       # => :C
qpi.pin.abbr       # => :K
qpi.pin.side       # => :first
qpi.pin.state      # => :normal
qpi.pin.terminal?  # => true

Native/Derived relationship

qpi = Identifier.new(Sin.parse("C"), Pin.parse("K"))
qpi.native?   # => true (both uppercase/first)

qpi = Identifier.new(Sin.parse("C"), Pin.parse("k"))
qpi.derived?  # => true (SIN uppercase, PIN lowercase)

See Also:

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sin, pin) ⇒ Identifier

Creates a new Identifier instance.

Examples:

sin = Sashite::Sin.parse("C")
pin = Sashite::Pin.parse("K^")
Identifier.new(sin, pin)

Parameters:

  • sin (Sashite::Sin::Identifier)

    The SIN component

  • pin (Sashite::Pin::Identifier)

    The PIN component

Raises:



57
58
59
60
61
62
63
64
65
# File 'lib/sashite/qpi/identifier.rb', line 57

def initialize(sin, pin)
  validate_sin!(sin)
  validate_pin!(pin)

  @sin = sin
  @pin = pin

  freeze
end

Instance Attribute Details

#pinSashite::Pin::Identifier (readonly)

Returns The PIN component.

Returns:

  • (Sashite::Pin::Identifier)

    The PIN component



44
45
46
# File 'lib/sashite/qpi/identifier.rb', line 44

def pin
  @pin
end

#sinSashite::Sin::Identifier (readonly)

Returns The SIN component.

Returns:

  • (Sashite::Sin::Identifier)

    The SIN component



41
42
43
# File 'lib/sashite/qpi/identifier.rb', line 41

def sin
  @sin
end

Instance Method Details

#==(other) ⇒ Boolean Also known as: eql?

Checks equality with another Identifier.

Parameters:

  • other (Object)

    The object to compare

Returns:

  • (Boolean)

    true if equal



210
211
212
213
214
# File 'lib/sashite/qpi/identifier.rb', line 210

def ==(other)
  return false unless self.class === other

  sin == other.sin && pin == other.pin
end

#deriveIdentifier

Returns a new Identifier with PIN case opposite to SIN case.

If already derived, returns self.

Examples:

qpi = Identifier.new(Sin.parse("C"), Pin.parse("R"))
qpi.derive.to_s  # => "C:r"

qpi = Identifier.new(Sin.parse("C"), Pin.parse("r"))
qpi.derive.to_s  # => "C:r" (unchanged)

Returns:



147
148
149
150
151
152
# File 'lib/sashite/qpi/identifier.rb', line 147

def derive
  return self if derived?

  opposite_side = sin.side.equal?(:first) ? :second : :first
  self.class.new(sin, pin.with_side(opposite_side))
end

#derived?Boolean

Checks if the identifier is derived.

A QPI is derived when sin.side differs from pin.side (different case).

Examples:

Identifier.new(Sin.parse("C"), Pin.parse("k")).derived?  # => true
Identifier.new(Sin.parse("c"), Pin.parse("K")).derived?  # => true
Identifier.new(Sin.parse("C"), Pin.parse("K")).derived?  # => false

Returns:

  • (Boolean)

    true if derived



109
110
111
# File 'lib/sashite/qpi/identifier.rb', line 109

def derived?
  !native?
end

#flipIdentifier

Returns a new Identifier with PIN side flipped.

The SIN component remains unchanged. This reflects the QPI specification constraint that SIN (Player Style + Player Side) is stable within a Match, while PIN side (Piece Side) may change via Mutation.

Examples:

qpi = Identifier.new(Sin.parse("C"), Pin.parse("K^"))
qpi.flip.to_s  # => "C:k^"

qpi = Identifier.new(Sin.parse("c"), Pin.parse("r"))
qpi.flip.to_s  # => "c:R"

Returns:

  • (Identifier)

    A new Identifier with PIN side flipped



198
199
200
# File 'lib/sashite/qpi/identifier.rb', line 198

def flip
  self.class.new(sin, pin.flip)
end

#hashInteger

Returns a hash code for the Identifier.

Returns:

  • (Integer)

    Hash code



221
222
223
# File 'lib/sashite/qpi/identifier.rb', line 221

def hash
  [sin, pin].hash
end

#inspectString

Returns an inspect string for the Identifier.

Returns:

  • (String)

    Inspect representation



228
229
230
# File 'lib/sashite/qpi/identifier.rb', line 228

def inspect
  "#<#{self.class} #{self}>"
end

#nativeIdentifier

Returns a new Identifier with PIN case aligned to SIN case.

If already native, returns self.

Examples:

qpi = Identifier.new(Sin.parse("C"), Pin.parse("r"))
qpi.native.to_s  # => "C:R"

qpi = Identifier.new(Sin.parse("C"), Pin.parse("R"))
qpi.native.to_s  # => "C:R" (unchanged)

Returns:



129
130
131
132
133
# File 'lib/sashite/qpi/identifier.rb', line 129

def native
  return self if native?

  self.class.new(sin, pin.with_side(sin.side))
end

#native?Boolean

Checks if the identifier is native.

A QPI is native when sin.side equals pin.side (same case).

Examples:

Identifier.new(Sin.parse("C"), Pin.parse("K")).native?  # => true
Identifier.new(Sin.parse("c"), Pin.parse("k")).native?  # => true
Identifier.new(Sin.parse("C"), Pin.parse("k")).native?  # => false

Returns:

  • (Boolean)

    true if native



95
96
97
# File 'lib/sashite/qpi/identifier.rb', line 95

def native?
  sin.side.equal?(pin.side)
end

#to_sString

Returns the QPI string representation.

Examples:

qpi.to_s  # => "C:K^"

Returns:

  • (String)

    The QPI string in format “SIN:PIN”



77
78
79
# File 'lib/sashite/qpi/identifier.rb', line 77

def to_s
  "#{sin}#{Constants::SEPARATOR}#{pin}"
end

#with_pin(new_pin) ⇒ Identifier

Returns a new Identifier with a different PIN component.

Examples:

qpi = Identifier.new(Sin.parse("C"), Pin.parse("K"))
qpi.with_pin(Pin.parse("+Q^")).to_s  # => "C:+Q^"

Parameters:

  • new_pin (Sashite::Pin::Identifier)

    The new PIN component

Returns:

  • (Identifier)

    A new Identifier with the specified PIN

Raises:



180
181
182
# File 'lib/sashite/qpi/identifier.rb', line 180

def with_pin(new_pin)
  self.class.new(sin, new_pin)
end

#with_sin(new_sin) ⇒ Identifier

Returns a new Identifier with a different SIN component.

Examples:

qpi = Identifier.new(Sin.parse("C"), Pin.parse("K"))
qpi.with_sin(Sin.parse("S")).to_s  # => "S:K"

Parameters:

  • new_sin (Sashite::Sin::Identifier)

    The new SIN component

Returns:

  • (Identifier)

    A new Identifier with the specified SIN

Raises:



167
168
169
# File 'lib/sashite/qpi/identifier.rb', line 167

def with_sin(new_sin)
  self.class.new(new_sin, pin)
end