class Pangrid::XWord

solution = Cell[] width, height = int across_clues = string[] down_clues = string[] rebus = { solution => [int, rebus_char] }

Public Instance Methods

across?(x, y) click to toggle source
# File lib/pangrid/xw.rb, line 90
def across?(x, y)
  boundary?(x - 1, y) && !boundary?(x, y) && !boundary?(x + 1, y)
end
black?(x, y) click to toggle source

Clue numbering

# File lib/pangrid/xw.rb, line 82
def black?(x, y)
  solution[y][x].black?
end
boundary?(x, y) click to toggle source
# File lib/pangrid/xw.rb, line 86
def boundary?(x, y)
  (x < 0) || (y < 0) || (x >= width) || (y >= height) || black?(x, y)
end
down?(x, y) click to toggle source
# File lib/pangrid/xw.rb, line 94
def down?(x, y)
  boundary?(x, y - 1) && !boundary?(x, y) && !boundary?(x, y + 1)
end
each_cell() { |solution[x]| ... } click to toggle source
# File lib/pangrid/xw.rb, line 134
def each_cell
  (0 ... height).each do |y|
    (0 ... width).each do |x|
      yield solution[y][x]
    end
  end
end
each_cell_with_coords() { |x, y, solution[x]| ... } click to toggle source
# File lib/pangrid/xw.rb, line 142
def each_cell_with_coords
  (0 ... height).each do |y|
    (0 ... width).each do |x|
      yield [x, y, solution[y][x]]
    end
  end
end
encode_rebus!() click to toggle source

Collect a hash of rebus solutions, each mapped to an integer.

# File lib/pangrid/xw.rb, line 171
def encode_rebus!
  k = 0
  self.rebus = {}
  each_cell do |c|
    if c.rebus?
      r = c.solution
      if self.rebus[s]
        sym, _ = self.rebus[s]
        r.symbol = sym.to_s
      else
        k += 1
        self.rebus[r.solution] = [k, r.display_char]
        r.symbol = k.to_s
      end
    end
  end
end
inspect_grid() click to toggle source
# File lib/pangrid/xw.rb, line 189
def inspect_grid
  number
  solution.map {|row|
    row.map {|c|
      s = c.solution
      o = case s
      when :black
        "#"
      when :null
        "."
      when String
        c.to_char
      when Rebus
        c.to_char
      else
        raise PuzzleFormatError, "Unrecognised cell #{c}"
      end
      if c.number && c.number > 0
        o = "#{c.number} #{o}"
      end
      o = o.rjust(4)
    }.join("|")
  }.join("\n")
end
number(words = false) click to toggle source
# File lib/pangrid/xw.rb, line 112
def number(words = false)
  n, across, down = 1, [], []
  words_a, words_d = [], []
  (0 ... height).each do |y|
    (0 ... width).each do |x|
      if across? x, y
        across << n
        words_a << word_from(x, y, :across)
      end
      if down? x, y
        down << n
        words_d << word_from(x, y, :down)
      end
      if across.last == n || down.last == n
        solution[y][x].number = n
        n += 1
      end
    end
  end
  words ? [across, down, words_a, words_d] : [across, down]
end
to_array(opts = {}) { |c) : to_char| ... } click to toggle source

{:black => char, :null => char} -> Any[]

# File lib/pangrid/xw.rb, line 151
def to_array(opts = {})
  opts = {:black => '#', :null => ' '}.merge(opts)
  solution.map {|row|
    row.map {|c|
      s = c.solution
      case s
      when :black, :null
        opts[s]
      when String
        block_given? ? (yield c) : c.to_char
      when Rebus
        block_given? ? (yield c) : c.to_char
      else
        raise PuzzleFormatError, "Unrecognised cell #{c}"
      end
    }
  }
end
word_from(x, y, dir) click to toggle source

Word starting from a square

# File lib/pangrid/xw.rb, line 99
def word_from(x, y, dir)
  s = ""
  while !boundary?(x, y) do
    s += solution[y][x].to_w
    if dir == :across
      x += 1
    else
      y += 1
    end
  end
  s
end