Module: Crucigrama::Crossword::WordQuery
- Included in:
- Crucigrama::Crossword
- Defined in:
- lib/crucigrama/crossword/word_query.rb
Overview
This module provides methods to query word existence, placement and search on a crossword
Instance Method Summary collapse
-
#black_positions ⇒ Array<Hash<Symbol,Integer>>
The list of black positions (or empty cells) in the crossword.
-
#can_set_word?(word, coordinates, direction) ⇒ Boolean
If the given word can be set on the crossword on the given coordinates and the given direction.
-
#word_at(coordinates, direction) ⇒ String?
The word in the crossword at the given coordinates and direction, if there is one, or nil otherwise.
-
#word_at?(coordinates, direction, word) ⇒ Boolean
If the word at the given coordinates and direction on the crossword is the given word.
-
#word_positions ⇒ Hash<String,Hash<Symbol, Array<Hash<Symbol, Integer>>>>
A relation of the words in the crosswords and their starting positions in both directions.
-
#words ⇒ Array<String>
The list of words present in the crossword.
Instance Method Details
#black_positions ⇒ Array<Hash<Symbol,Integer>>
Returns the list of black positions (or empty cells) in the crossword.
34 35 36 37 38 39 40 |
# File 'lib/crucigrama/crossword/word_query.rb', line 34 def black_positions @black_positions ||= lines(:horizontal).collect.with_index do |row, vertical_index| row.chars.collect.with_index do |cell, horizontal_index| cell == self.class::BLACK ? {:horizontal => horizontal_index, :vertical => vertical_index} : nil end.compact end.flatten end |
#can_set_word?(word, coordinates, direction) ⇒ Boolean
Returns if the given word can be set on the crossword on the given coordinates and the given direction. The word can be set if it is not out of bounds on the crossword (that is, the cells it would occupy are defined) and if every crossword cell it would occupy either contains the corresponding word character or is a black position or empty cell.
78 79 80 81 82 83 84 85 |
# File 'lib/crucigrama/crossword/word_query.rb', line 78 def can_set_word?(word, coordinates, direction) return false if out_of_bounds(word, coordinates, direction) return true if word.empty? other_direction = direction_other_than(direction) line = line(coordinates[other_direction], direction) regexp_str = line[coordinates[direction]..line.length][0..word.length-1].gsub(self.class::BLACK, '.') Regexp.new(regexp_str).match(word) end |
#word_at(coordinates, direction) ⇒ String?
Returns the word in the crossword at the given coordinates and direction, if there is one, or nil otherwise.
12 13 14 15 16 17 18 19 |
# File 'lib/crucigrama/crossword/word_query.rb', line 12 def word_at(coordinates, direction) other_direction = direction_other_than(direction) words.detect do |word| (word_positions[word][direction]||=[]).detect do |position| position[other_direction] == coordinates[other_direction] and position[direction] <= coordinates[direction] and position[direction] + word.length > coordinates[direction] end end end |
#word_at?(coordinates, direction, word) ⇒ Boolean
Returns if the word at the given coordinates and direction on the crossword is the given word.
29 30 31 |
# File 'lib/crucigrama/crossword/word_query.rb', line 29 def word_at?(coordinates, direction, word) word_at(coordinates, direction) == word end |
#word_positions ⇒ Hash<String,Hash<Symbol, Array<Hash<Symbol, Integer>>>>
reimplement using lines(direction)
Returns a relation of the words in the crosswords and their starting positions in both directions. Words are the primary key in the returned tree, followed by the direction (:horizontal or :vertical). The list of positions is given as an Array of hashes with values for the :horizontal and :vertical coordinates.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/crucigrama/crossword/word_query.rb', line 53 def word_positions @word_positions ||= begin result = {} [:horizontal, :vertical].each do |direction| other_direction = direction_other_than(direction) lines(direction).each.with_index do |row, row_index| position = 0 row.split(self.class::BLACK).each do |word| unless word.empty? result[word]||= {} result[word][direction]||= [] result[word][direction] << {direction => position, other_direction=> row_index} end position+= word.length + 1 end end end result end end |
#words ⇒ Array<String>
Returns the list of words present in the crossword.
43 44 45 |
# File 'lib/crucigrama/crossword/word_query.rb', line 43 def words word_positions.keys end |