Module: Sashite::Pan::Action

Defined in:
lib/sashite/pan/action.rb,
lib/sashite/pan/action/drop.rb,
lib/sashite/pan/action/move.rb,
lib/sashite/pan/action/pass.rb,
lib/sashite/pan/action/modify.rb,
lib/sashite/pan/action/capture.rb,
lib/sashite/pan/action/special.rb,
lib/sashite/pan/action/drop_capture.rb,
lib/sashite/pan/action/static_capture.rb

Overview

Action module

Orchestrates all action types in PAN (Portable Action Notation) format. Each action type is implemented as a separate, autonomous class.

This module provides a unified interface for validation, parsing, and factory methods that delegate to the appropriate action class.

Defined Under Namespace

Classes: Capture, Drop, DropCapture, Modify, Move, Pass, Special, StaticCapture

Constant Summary collapse

ERROR_INVALID_PAN =

Error messages

"Invalid PAN string: %s"

Class Method Summary collapse

Class Method Details

.capture(source, destination, transformation: nil) ⇒ Capture

Create a capture action at destination

Examples:

Action.capture("d1", "f3")                      # => #<Capture ...>
Action.capture("b7", "a8", transformation: "R") # => #<Capture ...>

Parameters:

  • source (String)

    source CELL coordinate

  • destination (String)

    destination CELL coordinate

  • transformation (String, nil) (defaults to: nil)

    optional EPIN transformation

Returns:

  • (Capture)

    capture action instance



110
111
112
# File 'lib/sashite/pan/action.rb', line 110

def self.capture(source, destination, transformation: nil)
  Capture.new(source, destination, transformation: transformation)
end

.drop(destination, piece: nil, transformation: nil) ⇒ Drop

Create a drop action to empty square

Examples:

Action.drop("e5", piece: "P")                           # => #<Drop ...>
Action.drop("d4")                                       # => #<Drop ...>
Action.drop("c3", piece: "S", transformation: "+S")     # => #<Drop ...>

Parameters:

  • destination (String)

    destination CELL coordinate

  • piece (String, nil) (defaults to: nil)

    optional EPIN piece identifier

  • transformation (String, nil) (defaults to: nil)

    optional EPIN transformation

Returns:

  • (Drop)

    drop action instance



149
150
151
# File 'lib/sashite/pan/action.rb', line 149

def self.drop(destination, piece: nil, transformation: nil)
  Drop.new(destination, piece: piece, transformation: transformation)
end

.drop_capture(destination, piece: nil, transformation: nil) ⇒ DropCapture

Create a drop action with capture

Examples:

Action.drop_capture("b4", piece: "L")  # => #<DropCapture ...>

Parameters:

  • destination (String)

    destination CELL coordinate

  • piece (String, nil) (defaults to: nil)

    optional EPIN piece identifier

  • transformation (String, nil) (defaults to: nil)

    optional EPIN transformation

Returns:



162
163
164
# File 'lib/sashite/pan/action.rb', line 162

def self.drop_capture(destination, piece: nil, transformation: nil)
  DropCapture.new(destination, piece: piece, transformation: transformation)
end

.modify(square, piece) ⇒ Modify

Create an in-place transformation action

Examples:

Action.modify("e4", "+P")   # => #<Modify ...>
Action.modify("c3", "k'")   # => #<Modify ...>

Parameters:

  • square (String)

    CELL coordinate

  • piece (String)

    EPIN piece identifier (final state)

Returns:

  • (Modify)

    modification action instance



175
176
177
# File 'lib/sashite/pan/action.rb', line 175

def self.modify(square, piece)
  Modify.new(square, piece)
end

.move(source, destination, transformation: nil) ⇒ Move

Create a move action to an empty square

Examples:

Action.move("e2", "e4")                        # => #<Move ...>
Action.move("e7", "e8", transformation: "Q")   # => #<Move ...>

Parameters:

  • source (String)

    source CELL coordinate

  • destination (String)

    destination CELL coordinate

  • transformation (String, nil) (defaults to: nil)

    optional EPIN transformation

Returns:

  • (Move)

    move action instance



96
97
98
# File 'lib/sashite/pan/action.rb', line 96

def self.move(source, destination, transformation: nil)
  Move.new(source, destination, transformation: transformation)
end

.parse(pan_string) ⇒ Pass, ...

Parse a PAN string into an action object

Examples:

Action.parse("e2-e4")      # => #<Move ...>
Action.parse("d1+f3")      # => #<Capture ...>
Action.parse("...")        # => #<Pass ...>

Parameters:

  • pan_string (String)

    PAN notation string

Returns:

Raises:

  • (ArgumentError)

    if the PAN string is invalid



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/sashite/pan/action.rb', line 60

def self.parse(pan_string)
  string_value = String(pan_string)

  # Try each action type's parser in order of specificity
  return Pass.parse(string_value) if Pass.valid?(string_value)
  return Move.parse(string_value) if Move.valid?(string_value)
  return Capture.parse(string_value) if Capture.valid?(string_value)
  return Special.parse(string_value) if Special.valid?(string_value)
  return StaticCapture.parse(string_value) if StaticCapture.valid?(string_value)
  return Drop.parse(string_value) if Drop.valid?(string_value)
  return DropCapture.parse(string_value) if DropCapture.valid?(string_value)
  return Modify.parse(string_value) if Modify.valid?(string_value)

  raise ::ArgumentError, format(ERROR_INVALID_PAN, string_value)
end

.passPass

Create a pass action

Examples:

Action.pass  # => #<Pass>

Returns:

  • (Pass)

    pass action instance



82
83
84
# File 'lib/sashite/pan/action.rb', line 82

def self.pass
  Pass.instance
end

.special(source, destination, transformation: nil) ⇒ Special

Create a special move action with implicit side effects

Examples:

Action.special("e1", "g1")  # => #<Special ...>

Parameters:

  • source (String)

    source CELL coordinate

  • destination (String)

    destination CELL coordinate

  • transformation (String, nil) (defaults to: nil)

    optional EPIN transformation

Returns:

  • (Special)

    special action instance



123
124
125
# File 'lib/sashite/pan/action.rb', line 123

def self.special(source, destination, transformation: nil)
  Special.new(source, destination, transformation: transformation)
end

.static_capture(square) ⇒ StaticCapture

Create a static capture action (remove piece without movement)

Examples:

Action.static_capture("d4")  # => #<StaticCapture ...>

Parameters:

  • square (String)

    CELL coordinate of piece to capture

Returns:



134
135
136
# File 'lib/sashite/pan/action.rb', line 134

def self.static_capture(square)
  StaticCapture.new(square)
end

.valid?(pan_string) ⇒ Boolean

Check if a string represents a valid PAN action

Examples:

Action.valid?("e2-e4")     # => true
Action.valid?("P*e5")      # => true
Action.valid?("...")       # => true
Action.valid?("invalid")   # => false

Parameters:

  • pan_string (String)

    the string to validate

Returns:

  • (Boolean)

    true if the string is a valid PAN action



35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/sashite/pan/action.rb', line 35

def self.valid?(pan_string)
  return false unless pan_string.is_a?(::String)
  return false if pan_string.empty?

  # Try each action type's validation
  Pass.valid?(pan_string) ||
    Move.valid?(pan_string) ||
    Capture.valid?(pan_string) ||
    Special.valid?(pan_string) ||
    StaticCapture.valid?(pan_string) ||
    Drop.valid?(pan_string) ||
    DropCapture.valid?(pan_string) ||
    Modify.valid?(pan_string)
end