Module: Sashite::Cell
- Defined in:
- lib/sashite/cell.rb
Overview
CELL (Coordinate Encoding for Layered Locations) implementation for Ruby
Provides functionality for working with multi-dimensional game board coordinates using a cyclical ASCII character system.
This implementation is strictly compliant with CELL Specification v1.0.0
Constant Summary collapse
- REGEX =
Regular expression for validating CELL coordinates according to specification v1.0.0 Optimized version with redundant nested repeat operator removed for clean Ruby execution
/\A[a-z]+(?:[1-9]\d*[A-Z]+[a-z]+)*(?:[1-9]\d*[A-Z]*)?\z/
Class Method Summary collapse
-
.component_to_index(component, type) ⇒ Integer
Convert a component to its 0-indexed position.
-
.dimension_type(dimension) ⇒ Symbol
Determine the character set type for a given dimension Following CELL specification cyclical system: dimension n % 3 determines character set.
-
.dimensions(string) ⇒ Integer
Get the number of dimensions in a coordinate.
-
.extract_component(string, type) ⇒ String?
Extract the next component from a string based on expected type Strictly follows CELL specification patterns.
-
.from_indices(*indices) ⇒ String
Convert an array of 0-indexed integers to a CELL coordinate.
-
.index_to_component(index, type) ⇒ String
Convert a 0-indexed position to a component.
-
.index_to_letters(index) ⇒ String
Convert 0-indexed position to letter sequence Extended alphabet per CELL specification: 0=a, 1=b, …, 25=z, 26=aa, 27=ab, …, 701=zz, 702=aaa, etc.
-
.letters_to_index(letters) ⇒ Integer
Convert letter sequence to 0-indexed position Extended alphabet per CELL specification: a=0, b=1, …, z=25, aa=26, ab=27, …, zz=701, aaa=702, etc.
-
.parse(string) ⇒ Array<String>
Parse a coordinate string into dimensional components.
-
.parse_recursive(string, dimension) ⇒ Array<String>
Recursively parse a coordinate string into components following the strict CELL specification cyclical pattern.
-
.regex ⇒ Regexp
Get the validation regular expression.
-
.to_indices(string) ⇒ Array<Integer>
Convert a CELL coordinate to an array of 0-indexed integers.
-
.valid?(string) ⇒ Boolean
Check if a string represents a valid CELL coordinate.
Class Method Details
.component_to_index(component, type) ⇒ Integer
Convert a component to its 0-indexed position
172 173 174 175 176 177 178 179 180 181 |
# File 'lib/sashite/cell.rb', line 172 def self.component_to_index(component, type) case type when :lowercase letters_to_index(component) when :numeric component.to_i - 1 when :uppercase letters_to_index(component.downcase) end end |
.dimension_type(dimension) ⇒ Symbol
Determine the character set type for a given dimension Following CELL specification cyclical system: dimension n % 3 determines character set
136 137 138 139 140 141 142 |
# File 'lib/sashite/cell.rb', line 136 def self.dimension_type(dimension) case dimension % 3 when 1 then :lowercase # n % 3 = 1: Latin lowercase letters when 2 then :numeric # n % 3 = 2: Arabic numerals when 0 then :uppercase # n % 3 = 0: Latin uppercase letters end end |
.dimensions(string) ⇒ Integer
Get the number of dimensions in a coordinate
43 44 45 46 47 |
# File 'lib/sashite/cell.rb', line 43 def self.dimensions(string) return 0 unless valid?(string) parse(string).length end |
.extract_component(string, type) ⇒ String?
Extract the next component from a string based on expected type Strictly follows CELL specification patterns
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/sashite/cell.rb', line 150 def self.extract_component(string, type) case type when :lowercase # Latin lowercase letters: [a-z]+ match = string.match(/\A([a-z]+)/) match ? match[1] : nil when :numeric # Arabic numerals: [1-9]\d* (CELL specification requires positive integers only) match = string.match(/\A([1-9]\d*)/) match ? match[1] : nil when :uppercase # Latin uppercase letters: [A-Z]+ match = string.match(/\A([A-Z]+)/) match ? match[1] : nil end end |
.from_indices(*indices) ⇒ String
Convert an array of 0-indexed integers to a CELL coordinate
93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/sashite/cell.rb', line 93 def self.from_indices(*indices) return "" if indices.empty? result = indices.map.with_index do |index, dimension| dimension_type = dimension_type(dimension + 1) index_to_component(index, dimension_type) end.join # Verify the result is valid according to CELL specification valid?(result) ? result : "" end |
.index_to_component(index, type) ⇒ String
Convert a 0-indexed position to a component
188 189 190 191 192 193 194 195 196 197 |
# File 'lib/sashite/cell.rb', line 188 def self.index_to_component(index, type) case type when :lowercase index_to_letters(index) when :numeric (index + 1).to_s when :uppercase index_to_letters(index).upcase end end |
.index_to_letters(index) ⇒ String
Convert 0-indexed position to letter sequence Extended alphabet per CELL specification: 0=a, 1=b, …, 25=z, 26=aa, 27=ab, …, 701=zz, 702=aaa, etc.
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/sashite/cell.rb', line 226 def self.index_to_letters(index) # Find the length of the result length = 1 base = 0 loop do range_size = 26**length break if index < base + range_size base += range_size length += 1 end # Convert within the found length adjusted_index = index - base result = "" length.times do |pos| char_index = adjusted_index / (26**(length - pos - 1)) result += (char_index + 97).chr adjusted_index %= (26**(length - pos - 1)) end result end |
.letters_to_index(letters) ⇒ Integer
Convert letter sequence to 0-indexed position Extended alphabet per CELL specification: a=0, b=1, …, z=25, aa=26, ab=27, …, zz=701, aaa=702, etc.
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/sashite/cell.rb', line 204 def self.letters_to_index(letters) length = letters.length index = 0 # Add positions from shorter sequences (1...length).each do |len| index += 26**len end # Add position within current length letters.each_char.with_index do |char, pos| index += (char.ord - 97) * (26**(length - pos - 1)) end index end |
.parse(string) ⇒ Array<String>
Parse a coordinate string into dimensional components
58 59 60 61 62 63 64 |
# File 'lib/sashite/cell.rb', line 58 def self.parse(string) return [] unless string.is_a?(::String) return [] if string.empty? return [] unless valid?(string) parse_recursive(string, 1) end |
.parse_recursive(string, dimension) ⇒ Array<String>
Recursively parse a coordinate string into components following the strict CELL specification cyclical pattern
118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/sashite/cell.rb', line 118 def self.parse_recursive(string, dimension) return [] if string.empty? expected_type = dimension_type(dimension) component = extract_component(string, expected_type) return [] if component.nil? # Extract component and recursively parse the rest remaining = string[component.length..] [component] + parse_recursive(remaining, dimension + 1) end |
.regex ⇒ Regexp
Get the validation regular expression
108 109 110 |
# File 'lib/sashite/cell.rb', line 108 def self.regex REGEX end |
.to_indices(string) ⇒ Array<Integer>
Convert a CELL coordinate to an array of 0-indexed integers
75 76 77 78 79 80 81 82 |
# File 'lib/sashite/cell.rb', line 75 def self.to_indices(string) return [] unless valid?(string) parse(string).map.with_index do |component, index| dimension_type = dimension_type(index + 1) component_to_index(component, dimension_type) end end |
.valid?(string) ⇒ Boolean
Check if a string represents a valid CELL coordinate
26 27 28 29 30 31 32 |
# File 'lib/sashite/cell.rb', line 26 def self.valid?(string) return false unless string.is_a?(String) return false if string.empty? # Use the optimized CELL v1.0.0 regex for validation string.match?(REGEX) end |