Class: Sashite::Ggn::Ruleset::Source::Destination::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/sashite/ggn/ruleset/source/destination/engine.rb

Overview

Movement possibility evaluator

Evaluates whether movements are possible based on environmental pre-conditions as defined in the GGN specification v1.0.0.

The Engine acts as the final stage in the GGN navigation chain, determining which movement possibilities from the GGN data structure are valid given the current board state.

Instance Method Summary collapse

Constructor Details

#initialize(*possibilities) ⇒ Engine

Note:

This constructor is typically called internally through the navigation chain: ruleset.select(piece).from(source).to(destination)

Create a new Engine with movement possibilities

Examples:

Structure of a possibility

{
  "must" => { "e3" => "empty", "e4" => "empty" },
  "deny" => { "f3" => "enemy" }
}


36
37
38
39
40
# File 'lib/sashite/ggn/ruleset/source/destination/engine.rb', line 36

def initialize(*possibilities)
  @possibilities = validate_and_freeze(possibilities)

  freeze
end

Instance Method Details

#where(active_side, squares) ⇒ Array<Hash>

Evaluate which movement possibilities match the current position

Returns the subset of movement possibilities whose pre-conditions are satisfied by the current board state. This is the core evaluation method that determines if a movement is pseudo-legal.

Each possibility is evaluated independently with the following logic:

  • All “must” conditions must be satisfied (AND logic)

  • No “deny” conditions can be satisfied (NOR logic)

The “enemy” keyword in conditions is evaluated from the active player’s perspective, following the LCN specification’s standard interpretation.

Examples:

Chess pawn two-square advance

active_side = :first
squares = {
  "e2" => "C:P",  # White pawn on starting square
  "e3" => nil,    # Path must be clear
  "e4" => nil     # Destination must be empty
}
possibilities = engine.where(active_side, squares)
# => [{"must" => {"e3" => "empty", "e4" => "empty"}, "deny" => {}}]

Capture evaluation with enemy keyword

active_side = :first
squares = {
  "e4" => "C:P",  # White pawn
  "d5" => "c:p"   # Black pawn (enemy from white's perspective)
}
possibilities = engine.where(active_side, squares)
# => [{"must" => {"d5" => "enemy"}, "deny" => {}}]

No matching possibilities (blocked path)

squares = { "e2" => "C:P", "e3" => "c:p", "e4" => nil }
possibilities = engine.where(active_side, squares)
# => []

Raises:

  • (ArgumentError)

    if active_side is not :first or :second



93
94
95
96
97
98
99
100
# File 'lib/sashite/ggn/ruleset/source/destination/engine.rb', line 93

def where(active_side, squares)
  validate_active_side!(active_side)
  validate_squares!(squares)

  @possibilities.select do |possibility|
    satisfies_conditions?(possibility, active_side, squares)
  end
end