Module: Sashite::Lcn
- Defined in:
- lib/sashite/lcn.rb,
lib/sashite/lcn/conditions.rb
Overview
LCN (Location Condition Notation) implementation for Ruby
Provides a rule-agnostic format for describing location conditions in abstract strategy board games. LCN provides a standardized way to express constraints on board locations, defining what states specific locations should have.
## Concept
LCN is a foundational specification designed to be used by other formats that require location state definitions. It expresses environmental constraints as key-value pairs where keys are CELL coordinates and values are state values.
## State Value Types
LCN supports two categories of state values:
### Reserved Keywords
-
‘“empty”`: Location should be unoccupied
-
‘“enemy”`: Location should contain a piece from the opposing side (context-dependent)
### QPI Piece Identifiers
-
Exact piece requirements using QPI format (e.g., “C:K”, “c:p”, “S:+P”)
## Context Dependency
The ‘“enemy”` keyword is context-dependent and requires a reference piece for interpretation. The consuming specification must provide:
-
Reference piece identification (which piece determines the perspective)
-
Side determination logic (how the reference piece’s side is established)
-
Enemy evaluation rules (how opposing pieces are identified)
## Format Structure
LCN uses a simple JSON object structure: “‘json
"<cell-coordinate>": "<state-value>"
“‘
Where:
-
Keys: CELL coordinates (string, conforming to CELL specification)
-
Values: State values (reserved keywords or QPI identifiers)
## Examples
### Basic Conditions
# Empty location requirement
conditions = Sashite::Lcn.parse({ "e4" => "empty" })
conditions[:e4] # => "empty"
# Enemy piece requirement (context-dependent)
conditions = Sashite::Lcn.parse({ "f5" => "enemy" })
conditions[:f5] # => "enemy"
### Specific Piece Requirements
conditions = Sashite::Lcn.parse({
"h1" => "C:+R", # Chess rook with castling rights
"e1" => "C:+K", # Chess king with castling rights
"f5" => "c:-p" # Enemy pawn vulnerable to en passant
})
### Complex Path Conditions
# Path clearance for movement
path_conditions = Sashite::Lcn.parse({
"b2" => "empty",
"c3" => "empty",
"d4" => "empty"
})
# Castling requirements
castling = Sashite::Lcn.parse({
"f1" => "empty",
"g1" => "empty",
"h1" => "C:+R"
})
### Empty Conditions
no_conditions = Sashite::Lcn.parse({})
no_conditions.empty? # => true
## Design Properties
-
Rule-agnostic: Independent of specific game mechanics
-
Context-neutral: Provides format without imposing evaluation logic
-
Composable: Can be combined by consuming specifications
-
Type-safe: Clear distinction between keywords and piece identifiers
-
**Minimal syntax**: Clean key-value pairs without nesting
-
Functional: Pure functions with no side effects
-
Immutable: All instances are frozen for thread safety
Defined Under Namespace
Classes: Conditions
Constant Summary collapse
- EMPTY_KEYWORD =
Reserved keywords for common location states
"empty"- ENEMY_KEYWORD =
"enemy"- RESERVED_KEYWORDS =
[EMPTY_KEYWORD, ENEMY_KEYWORD].freeze
Class Method Summary collapse
-
.parse(data) ⇒ Lcn::Conditions
Parse LCN data into a Conditions object.
-
.valid?(data) ⇒ Boolean
Check if data represents valid LCN conditions.
Class Method Details
.parse(data) ⇒ Lcn::Conditions
Parse LCN data into a Conditions object
Creates a new LCN Conditions instance by parsing and validating the input data. Accepts both string and symbol keys for compatibility, but internally normalizes to symbol keys for Ruby idiomatic usage.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/sashite/lcn.rb', line 168 def self.parse(data) raise ArgumentError, "LCN data must be a Hash" unless data.is_a?(Hash) validated_conditions = {} data.each do |location, state_value| # Convert location to string for validation, then to symbol for storage location_str = location.to_s raise ArgumentError, "Invalid CELL coordinate: #{location_str}" unless valid_location?(location_str) raise ArgumentError, "Invalid state value: #{state_value}" unless valid_state_value?(state_value) # Store with symbol key for Ruby idiomatic access validated_conditions[location_str.to_sym] = state_value end Conditions.new(**validated_conditions) end |
.valid?(data) ⇒ Boolean
Check if data represents valid LCN conditions
Validates that the data is a Hash with:
-
Keys: Valid CELL coordinates
-
Values: Reserved keywords (“empty”, “enemy”) or valid QPI identifiers
130 131 132 133 134 135 136 |
# File 'lib/sashite/lcn.rb', line 130 def self.valid?(data) return false unless data.is_a?(Hash) data.all? do |location, state_value| valid_location?(location) && valid_state_value?(state_value) end end |