Class: Sashite::Pnn::Piece

Inherits:
Sashite::Pin::Piece
  • Object
show all
Defined in:
lib/sashite/pnn/piece.rb

Overview

Represents a piece in PNN (Piece Name Notation) format.

Extends PIN::Piece to add style awareness through derivation markers. A PNN piece consists of a PIN string with an optional derivation suffix:

  • No suffix: native style

  • Apostrophe suffix (‘): foreign style

All instances are immutable - style manipulation methods return new instances.

Constant Summary collapse

PNN_PATTERN =

PNN validation pattern extending PIN

/\A(?<prefix>[-+])?(?<letter>[a-zA-Z])(?<suffix>'?)\z/
FOREIGN_SUFFIX =

Derivation marker for foreign style

"'"
ERROR_INVALID_PNN =

Error messages

"Invalid PNN string: %s"
ERROR_INVALID_NATIVE =
"Native must be true or false: %s"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(letter, native: true) ⇒ Piece

Create a new piece instance with style information

Parameters:

  • letter (String)

    single ASCII letter (a-z or A-Z)

  • native (Boolean) (defaults to: true)

    whether the piece has native style

Raises:

  • (ArgumentError)

    if parameters are invalid



35
36
37
38
39
40
# File 'lib/sashite/pnn/piece.rb', line 35

def initialize(letter, native: true, **)
  raise ::ArgumentError, format(ERROR_INVALID_NATIVE, native) unless [true, false].include?(native)

  @native = native
  super(letter, **)
end

Instance Attribute Details

#nativeBoolean (readonly) Also known as: native?

Returns whether the piece has native style.

Returns:

  • (Boolean)

    whether the piece has native style



27
28
29
# File 'lib/sashite/pnn/piece.rb', line 27

def native
  @native
end

Class Method Details

.parse(pnn_string) ⇒ Piece

Parse a PNN string into a Piece object

Examples:

Pnn::Piece.parse("k")     # => #<Pnn::Piece letter="k" native=true>
Pnn::Piece.parse("k'")    # => #<Pnn::Piece letter="k" native=false>
Pnn::Piece.parse("+R'")   # => #<Pnn::Piece letter="R" enhanced=true native=false>

Parameters:

  • pnn_string (String)

    PNN notation string

Returns:

  • (Piece)

    new piece instance

Raises:

  • (ArgumentError)

    if the PNN string is invalid



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/sashite/pnn/piece.rb', line 51

def self.parse(pnn_string)
  string_value = String(pnn_string)
  matches = match_pattern(string_value)

  letter = matches[:letter]
  enhanced = matches[:prefix] == ENHANCED_PREFIX
  diminished = matches[:prefix] == DIMINISHED_PREFIX
  native = matches[:suffix] != FOREIGN_SUFFIX

  new(
    letter,
    native:     native,
    enhanced:   enhanced,
    diminished: diminished
  )
end

Instance Method Details

#==(other) ⇒ Boolean

Custom equality comparison including style

Parameters:

  • other (Object)

    object to compare with

Returns:

  • (Boolean)

    true if pieces are equal



206
207
208
209
210
# File 'lib/sashite/pnn/piece.rb', line 206

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

  super && native? == other.native?
end

#diminishObject



160
161
162
163
164
165
166
167
168
169
# File 'lib/sashite/pnn/piece.rb', line 160

def diminish
  return self if diminished?

  self.class.new(
    letter,
    native:     native?,
    enhanced:   false,
    diminished: true
  )
end

#enhanceObject

Override parent methods to maintain PNN type in return values



138
139
140
141
142
143
144
145
146
147
# File 'lib/sashite/pnn/piece.rb', line 138

def enhance
  return self if enhanced?

  self.class.new(
    letter,
    native:     native?,
    enhanced:   true,
    diminished: false
  )
end

#flipObject



191
192
193
194
195
196
197
198
199
200
# File 'lib/sashite/pnn/piece.rb', line 191

def flip
  flipped_letter = letter.swapcase

  self.class.new(
    flipped_letter,
    native:     native?,
    enhanced:   enhanced?,
    diminished: diminished?
  )
end

#foreign?Boolean

Check if the piece has foreign style

Returns:

  • (Boolean)

    true if foreign style



91
92
93
# File 'lib/sashite/pnn/piece.rb', line 91

def foreign?
  !native?
end

#foreignizePiece

Create a new piece with foreign style

Examples:

piece.foreignize  # k => k'

Returns:

  • (Piece)

    new piece instance with foreign style



116
117
118
119
120
121
122
123
124
125
# File 'lib/sashite/pnn/piece.rb', line 116

def foreignize
  return self if foreign?

  self.class.new(
    letter,
    native:     false,
    enhanced:   enhanced?,
    diminished: diminished?
  )
end

#hashInteger

Custom hash implementation including style

Returns:

  • (Integer)

    hash value



215
216
217
# File 'lib/sashite/pnn/piece.rb', line 215

def hash
  [super, @native].hash
end

#nativizePiece

Create a new piece with native style

Examples:

piece.nativize  # k' => k

Returns:

  • (Piece)

    new piece instance with native style



100
101
102
103
104
105
106
107
108
109
# File 'lib/sashite/pnn/piece.rb', line 100

def nativize
  return self if native?

  self.class.new(
    letter,
    native:     true,
    enhanced:   enhanced?,
    diminished: diminished?
  )
end

#normalizeObject



182
183
184
185
186
187
188
189
# File 'lib/sashite/pnn/piece.rb', line 182

def normalize
  return self if normal?

  self.class.new(
    letter,
    native: native?
  )
end

#to_pinString

Convert the piece to its underlying PIN representation

Returns:

  • (String)

    PIN notation string without style information



84
85
86
# File 'lib/sashite/pnn/piece.rb', line 84

def to_pin
  nativize.to_s
end

#to_sString

Convert the piece to its PNN string representation

Examples:

piece.to_s  # => "k"
piece.to_s  # => "k'"
piece.to_s  # => "+R'"

Returns:

  • (String)

    PNN notation string



75
76
77
78
79
# File 'lib/sashite/pnn/piece.rb', line 75

def to_s
  pin_string = super
  suffix = native? ? "" : FOREIGN_SUFFIX
  "#{pin_string}#{suffix}"
end

#toggle_stylePiece

Create a new piece with toggled style

Examples:

piece.toggle_style  # k => k', k' => k

Returns:

  • (Piece)

    new piece instance with opposite style



132
133
134
# File 'lib/sashite/pnn/piece.rb', line 132

def toggle_style
  native? ? foreignize : nativize
end

#undiminishObject



171
172
173
174
175
176
177
178
179
180
# File 'lib/sashite/pnn/piece.rb', line 171

def undiminish
  return self unless diminished?

  self.class.new(
    letter,
    native:     native?,
    enhanced:   enhanced?,
    diminished: false
  )
end

#unenhanceObject



149
150
151
152
153
154
155
156
157
158
# File 'lib/sashite/pnn/piece.rb', line 149

def unenhance
  return self unless enhanced?

  self.class.new(
    letter,
    native:     native?,
    enhanced:   false,
    diminished: diminished?
  )
end