class Upwords::Board

Attributes

max_height[RW]
min_word_length[RW]
size[RW]

Public Class Methods

build(moves, size=10, max_height=5) click to toggle source
# File lib/upwords/board.rb, line 100
def self.build(moves, size=10, max_height=5)
  moves.reduce(Board.new(size, max_height)) do |board, move|
    board.play_move(move)
  end
end
new(size=10, max_height=5) click to toggle source

creates a 10 x 10 board

# File lib/upwords/board.rb, line 7
def initialize(size=10, max_height=5)
  if !size.positive?
    raise ArgumentError, "Board size must be greater than zero!"
  else
    @size = size
    @max_height = max_height
    @min_word_length = 2
    @grid = Hash.new do |h, (row, col)|
      if row < 0 || col < 0 || num_rows <= row || num_columns <= col
        raise IllegalMove, "#{row}, #{col} is out of bounds!"
      else
        h[[row, col]] = []    # Initialize with empty array
      end
    end
  end
end

Public Instance Methods

can_play_letter?(letter, row, col, raise_exception = false) click to toggle source
# File lib/upwords/board.rb, line 61
def can_play_letter?(letter, row, col, raise_exception = false)
  if stack_height(row, col) == max_height
    raise IllegalMove, "You cannot stack any more letters on this space" if raise_exception
  elsif top_letter(row, col) == letter
    raise IllegalMove, "You cannot stack a letter on the same letter!" if raise_exception
  else 
    return true
  end

  return false
end
coordinates() click to toggle source
# File lib/upwords/board.rb, line 96
def coordinates
  (0...num_rows).to_a.product((0...num_columns).to_a)
end
empty?() click to toggle source
# File lib/upwords/board.rb, line 24
def empty?
  @grid.empty? || @grid.each_key.all? {|k| @grid[k].empty?}
end
middle_square() click to toggle source

Defines a 2x2 square in the middle of the board (in the case of the 10 x 10 board) The top left corner of the square is the initial cursor position The square itself defines the region where at least one of the first letters must be placed

# File lib/upwords/board.rb, line 43
def middle_square
  [1, 0].product([1, 0]).map do |r, c|
    [(num_rows) / 2 - r, (num_columns) / 2 - c]
  end
end
nonempty_space?(row, col) click to toggle source
# File lib/upwords/board.rb, line 28
def nonempty_space?(row, col)
  @grid.key?([row, col]) && stack_height(row, col) > 0
end
nonempty_spaces() click to toggle source
# File lib/upwords/board.rb, line 92
def nonempty_spaces
  coordinates.select {|row, col| nonempty_space?(row, col)}.to_set
end
num_columns() click to toggle source
# File lib/upwords/board.rb, line 36
def num_columns
  @size
end
num_rows() click to toggle source
# File lib/upwords/board.rb, line 32
def num_rows
  @size
end
play_letter(letter, row, col) click to toggle source
# File lib/upwords/board.rb, line 73
def play_letter(letter, row, col)
  if can_play_letter?(letter, row, col, raise_exception = true)
    @grid[[row, col]] << letter
    return [[row, col], letter] # Return position after successfully playing a move
  end  
end
play_move(move) click to toggle source
# File lib/upwords/board.rb, line 53
def play_move(move)
  move.play(self)
end
remove_top_letter(row, col) click to toggle source
# File lib/upwords/board.rb, line 80
def remove_top_letter(row, col)
  @grid[[row, col]].pop
end
stack_height(row, col) click to toggle source
# File lib/upwords/board.rb, line 49
def stack_height(row, col)
  @grid[[row, col]].size
end
top_letter(row, col) click to toggle source
# File lib/upwords/board.rb, line 84
def top_letter(row, col)
  @grid[[row, col]].last
end
undo_move(move) click to toggle source
# File lib/upwords/board.rb, line 57
def undo_move(move)
  move.remove_from(self)
end
word_positions() click to toggle source
# File lib/upwords/board.rb, line 88
def word_positions
  row_word_posns + column_word_posns
end

Private Instance Methods

collect_word_posns(&block) click to toggle source
# File lib/upwords/board.rb, line 108
def collect_word_posns(&block)
  SortedSet.new(nonempty_spaces).divide(&block).select do |w| 
    w.length >= min_word_length
  end.to_set
end
column_word_posns() click to toggle source
# File lib/upwords/board.rb, line 118
def column_word_posns
  collect_word_posns {|(r1,c1),(r2,c2)| (r1 - r2).abs == 1 && c1 == c2 }
end
row_word_posns() click to toggle source
# File lib/upwords/board.rb, line 114
def row_word_posns
  collect_word_posns {|(r1,c1),(r2,c2)| (c1 - c2).abs == 1 && r1 == r2 }
end