Cell.rb
CELL (Coordinate Expression Location Label) support for the Ruby language.
What is CELL?
CELL (Coordinate Expression Location Label) defines a consistent and rule-agnostic format for representing locations in abstract strategy board games. CELL provides a standardized way to identify positions on game boards and pieces held in hand/reserve, establishing a common foundation for location reference across the Sashité notation ecosystem.
This gem implements the CELL Specification v1.0.0, providing a Ruby interface for working with game locations through a clean and simple API that serves as a foundational building block for other Sashité specifications.
Installation
# In your Gemfile
gem "sashite-cell"
Or install manually:
gem install sashite-cell
CELL Format
A CELL location is represented by a single string following one of two patterns:
Board Coordinates
Any non-empty string containing only alphanumeric characters (a-z
, A-Z
, 0-9
):
e4 # Chess notation
5c # Shōgi notation
A3a # 3D coordinate
center # Custom coordinate
Hand/Reserve Location
The reserved character *
represents pieces held off-board:
* # Hand/reserve location
Basic Usage
Creating Location Objects
The primary interface is the Sashite::Cell::Location
class, which represents a game location in CELL format:
require "sashite/cell"
# Parse CELL strings into location objects
board_pos = Sashite::Cell::Location.parse("e4")
# => #<Sashite::Cell::Location:0x... @coordinate="e4">
hand_pos = Sashite::Cell::Location.parse("*")
# => #<Sashite::Cell::Location:0x... @coordinate="*">
# Create directly with constructor
location = Sashite::Cell::Location.new("e4")
hand = Sashite::Cell::Location.new("*")
# Convenience method
location = Sashite::Cell.location("e4")
Converting to CELL String
Convert a location object back to its CELL string representation:
location = Sashite::Cell::Location.parse("e4")
location.to_s
# => "e4"
hand = Sashite::Cell::Location.parse("*")
hand.to_s
# => "*"
Checking Location Types
Distinguish between board coordinates and hand/reserve locations:
board_loc = Sashite::Cell::Location.parse("e4")
hand_loc = Sashite::Cell::Location.parse("*")
board_loc.board? # => true
board_loc.hand? # => false
hand_loc.board? # => false
hand_loc.hand? # => true
Game-Specific Examples
Chess
# Standard chess coordinates
locations = %w[a1 e4 h8].map { |coord| Sashite::Cell::Location.parse(coord) }
# Check if valid chess square
def valid_chess_square?(location)
return false unless location.board?
coord = location.to_s
coord.length == 2 &&
coord[0].between?("a", "h") &&
coord[1].between?("1", "8")
end
valid_chess_square?(Sashite::Cell::Location.parse("e4")) # => true
valid_chess_square?(Sashite::Cell::Location.parse("z9")) # => false
Shōgi
# Shōgi board coordinates and hand
board_positions = %w[9a 5e 1i].map { |coord| Sashite::Cell::Location.parse(coord) }
hand_position = Sashite::Cell::Location.parse("*")
# Group by location type
positions = board_positions + [hand_position]
grouped = positions.group_by(&:hand?)
# => {false => [board positions], true => [hand position]}
Go
# Go coordinates (traditional notation)
go_positions = %w[A1 T19 K10].map { |coord| Sashite::Cell::Location.parse(coord) }
# Custom validation for Go board
def valid_go_position?(location, board_size = 19)
return false unless location.board?
coord = location.to_s
return false unless [2, 3].include?(coord.length)
letter = coord[0]
number = coord[1..].to_i
letter.between?("A", ("A".ord + board_size - 1).chr) &&
number.between?(1, board_size)
end
Custom Coordinate Systems
# 3D chess coordinates
location_3d = Sashite::Cell::Location.parse("A3a")
# Named locations
center = Sashite::Cell::Location.parse("center")
corner = Sashite::Cell::Location.parse("NE")
# Hexagonal coordinates
hex_coord = Sashite::Cell::Location.parse("Q3R7")
Advanced Usage
Working with Collections
# Mix of board and hand locations
locations = [
Sashite::Cell::Location.parse("e4"),
Sashite::Cell::Location.parse("d5"),
Sashite::Cell::Location.parse("*"),
Sashite::Cell::Location.parse("a1")
]
# Separate board from hand locations
board_locations = locations.select(&:board?)
hand_locations = locations.select(&:hand?)
# Convert collection to strings
coordinates = locations.map(&:to_s)
# => ["e4", "d5", "*", "a1"]
Game State Representation
# Represent piece positions
piece_locations = {
"white_king" => Sashite::Cell::Location.parse("e1"),
"black_king" => Sashite::Cell::Location.parse("e8"),
"white_rook" => Sashite::Cell::Location.parse("a1"),
"captured_pieces" => Sashite::Cell::Location.parse("*")
}
# Find pieces on specific ranks/files
def pieces_on_file(locations, file)
locations.select do |piece, location|
location.board? && location.to_s.start_with?(file)
end
end
e_file_pieces = pieces_on_file(piece_locations, "e")
Validation and Error Handling
# Check validity before parsing
Sashite::Cell.valid?("e4") # => true
Sashite::Cell.valid?("*") # => true
Sashite::Cell.valid?("") # => false
Sashite::Cell.valid?("e-4") # => false
Sashite::Cell.valid?("@") # => false
# Safe parsing
def safe_parse(coord_string)
return nil unless Sashite::Cell.valid?(coord_string)
Sashite::Cell::Location.parse(coord_string)
rescue ArgumentError
nil
end
# Invalid coordinates raise ArgumentError
begin
Sashite::Cell::Location.parse("")
rescue ArgumentError => e
puts "Invalid coordinate: #{e.message}"
end
Integration with Other Notations
# CELL serves as foundation for move notation
class SimpleMove
def initialize(from, to)
@from = Sashite::Cell::Location.parse(from)
@to = Sashite::Cell::Location.parse(to)
end
def from_board?
@from.board?
end
def to_board?
@to.board?
end
def drop_move?
@from.hand? && @to.board?
end
def capture_move?
@from.board? && @to.board?
end
def to_s
"#{@from}→#{@to}"
end
end
# Usage
move = SimpleMove.new("e4", "e5") # Normal move
drop = SimpleMove.new("*", "e4") # Drop from hand
API Reference
Module Methods
-
Sashite::Cell.valid?(cell_string)
- Check if a string is valid CELL notation -
Sashite::Cell.location(coordinate)
- Convenience method to create locations
Sashite::Cell::Location Class Methods
-
Sashite::Cell::Location.parse(cell_string)
- Parse a CELL string into a location object -
Sashite::Cell::Location.new(coordinate)
- Create a new location instance
Instance Methods
Type Checking
-
#board?
- Check if location represents a board coordinate -
#hand?
- Check if location represents hand/reserve
Conversion
-
#to_s
- Convert to CELL string representation -
#inspect
- Detailed string representation for debugging
Comparison
-
#==
- Compare locations for equality -
#eql?
- Strict equality comparison -
#hash
- Hash value for use in collections
Properties of CELL
- Rule-agnostic: CELL does not encode game states, movement rules, or game-specific conditions
- Universal location identification: Supports both board positions and hand/reserve areas
- Canonical representation: Equivalent locations yield identical strings
- Arbitrary coordinate systems: Flexible format supports any alphanumeric coordinate system
- Foundational specification: Serves as building block for other Sashité notations
Constraints
- Board coordinates must contain only alphanumeric characters (
a-z
,A-Z
,0-9
) - Board coordinates must be non-empty strings
- Hand/reserve locations must be exactly the character
*
- No other characters or formats are permitted
Use Cases
CELL is particularly useful in the following scenarios:
- Move notation systems: As coordinate foundation for MIN, PMN, and GGN specifications
- Game engine development: When implementing position tracking across different board layouts
- Board representation: When storing piece positions in databases or memory structures
- Cross-game compatibility: When building systems that work with multiple game types
- Position analysis: When comparing locations across different coordinate systems
- User interface development: When translating between display coordinates and logical positions
Dependencies
This gem has no external dependencies beyond Ruby standard library.
Specification
Documentation
License
The gem is available as open source under the terms of the MIT License.
About Sashité
This project is maintained by Sashité — promoting chess variants and sharing the beauty of Chinese, Japanese, and Western chess cultures.