class Upwords::Move

Public Class Methods

new(tiles = []) click to toggle source

Initialized with a list of 2D arrays, each containing a position (row, col) and a letter

# File lib/upwords/move.rb, line 7
def initialize(tiles = [])
  @shape = Shape.new(tiles.map {|(row, col), letter| [row, col]})
  @move = tiles.to_h
end

Public Instance Methods

[](row, col) click to toggle source

Return the letter in position (row, col) of the move

# File lib/upwords/move.rb, line 62
def [](row, col)
  @move[[row, col]]
end
can_play_letters?(board, raise_exception = false) click to toggle source

Check if entire move can be played on a board violating any board constraints, such as being out of bounds or exceeding the maximum stack height

# File lib/upwords/move.rb, line 50
def can_play_letters?(board, raise_exception = false)
  @move.all? do |(row, col), letter|
    board.can_play_letter?(letter, row, col, raise_exception)
  end
end
new_illegal_words(board, dict) click to toggle source

Return a list of new words that are not legal that would result from playing this move on the board

# File lib/upwords/move.rb, line 108
def new_illegal_words(board, dict)
  new_words(board).reject {|word| dict.legal_word?(word.to_s)}
end
new_words(board, raise_exception = false) click to toggle source

Return a list of new words that would result from playing this move on the board

# File lib/upwords/move.rb, line 90
def new_words(board, raise_exception = false)
  if can_play_letters?(board, raise_exception) 
    # HACK: update board with new move
    words = (board.play_move(self).word_positions).select do |word_posns|
      word_posns.any? {|row, col| position?(row, col)}
      
    end.map do |word_posns|
      Word.new(word_posns, board)
    end
  
    # HACK: remove move from board
    remove_from(board)
  
    return words
  end
end
play(board) click to toggle source

Play move on board and return the board NOTE: this method mutates the boards! TODO: consider adding the 'can_play_letters?' check?

# File lib/upwords/move.rb, line 69
def play(board)
  @move.reduce(board) do |b, (posn, letter)| 
    b.play_letter(letter, *posn)
    b
  end
end
position?(row, col) click to toggle source

Check if a particular position (row, col) is covered by the move

# File lib/upwords/move.rb, line 57
def position?(row, col)
  @move.key?([row, col])
end
remove_from(board) click to toggle source

Remove a previous move from the board and return the board (throws an exception if the move does not exist on the board) NOTE: this method mutates the boards!

# File lib/upwords/move.rb, line 78
def remove_from(board)
  if @move.any? {|(row, col), letter| board.top_letter(row, col) != letter}
    raise IllegalMove, "Move does not exist on board and therefore cannot be removed!"
  else
    (@move.each_key).reduce(board) do |b, posn| 
      b.remove_top_letter(*posn)
      b
    end
  end
end
score(board, player) click to toggle source

Calculate value of move Most of the word score calculate logic is in the Word class. However, this method will also add 20 points if the player uses all of their letters in the move

# File lib/upwords/move.rb, line 15
def score(board, player)
  new_words(board).reduce(player.rack_capacity == @move.size ? 20 : 0) do |total, word|
    total += word.score
  end
end