Class: Upwords::Shape
- Inherits:
-
Object
- Object
- Upwords::Shape
- Defined in:
- lib/upwords/shape.rb
Instance Attribute Summary collapse
-
#positions ⇒ Object
readonly
Returns the value of attribute positions.
Instance Method Summary collapse
- #add(row, col) ⇒ Object (also: #<<)
- #col_range ⇒ Object
-
#covering_moves?(board) ⇒ Boolean
Check if move shape completely covers any existing word on the board.
- #empty? ⇒ Boolean
-
#gaps_covered_by?(board) ⇒ Boolean
Check if all empty spaces in the rows and columns spanned by the move shape are covered by a previously-played tile on board For example, if the move shape = [1,1] [1,2] [1,4], then this method returns ‘true’ if the board has a tile at position [1,3] and ‘false’ if it does not.
-
#in_middle_square?(board) ⇒ Boolean
Check if at least one position within the move shape is within the middle 2x2 square on the board This check is only performed at the beginning of the game.
- #include?(row, col) ⇒ Boolean
-
#initialize(positions = []) ⇒ Shape
constructor
A new instance of Shape.
-
#legal?(board, raise_exception = false) ⇒ Boolean
Check if move creates a legal shape when added to a given board.
- #row_range ⇒ Object
- #size ⇒ Object
- #straight_line? ⇒ Boolean
-
#touching?(board) ⇒ Boolean
Check if at least one position within the move shape is adjacent to or overlapping any tile on the board.
Constructor Details
#initialize(positions = []) ⇒ Shape
Returns a new instance of Shape.
9 10 11 12 |
# File 'lib/upwords/shape.rb', line 9 def initialize(positions = []) @positions = Set.new positions.reduce(self) {|shape, (row, col)| shape.add(row, col)} end |
Instance Attribute Details
#positions ⇒ Object (readonly)
Returns the value of attribute positions.
7 8 9 |
# File 'lib/upwords/shape.rb', line 7 def positions @positions end |
Instance Method Details
#add(row, col) ⇒ Object Also known as: <<
83 84 85 86 87 88 89 90 |
# File 'lib/upwords/shape.rb', line 83 def add(row, col) if row.is_a?(Integer) && col.is_a?(Integer) @positions.add [row, col] self else raise ArgumentError, "[#{row}, #{col}] is not a valid position]" end end |
#col_range ⇒ Object
79 80 81 |
# File 'lib/upwords/shape.rb', line 79 def col_range Range.new(*@positions.map {|row, col| col}.minmax) end |
#covering_moves?(board) ⇒ Boolean
Check if move shape completely covers any existing word on the board
37 38 39 40 41 |
# File 'lib/upwords/shape.rb', line 37 def covering_moves?(board) (board.word_positions).any? do |word_posns| positions >= word_posns end end |
#empty? ⇒ Boolean
94 95 96 |
# File 'lib/upwords/shape.rb', line 94 def empty? @positions.empty? end |
#gaps_covered_by?(board) ⇒ Boolean
Check if all empty spaces in the rows and columns spanned by the move shape are covered by a previously-played tile on board For example, if the move shape = [1,1] [1,2] [1,4], then this method returns ‘true’ if the board has a tile at position [1,3] and ‘false’ if it does not.
46 47 48 49 50 51 52 |
# File 'lib/upwords/shape.rb', line 46 def gaps_covered_by?(board) row_range.all? do |row| col_range.all? do |col| @positions.include?([row, col]) || board.nonempty_space?(row, col) end end end |
#in_middle_square?(board) ⇒ Boolean
Check if at least one position within the move shape is within the middle 2x2 square on the board This check is only performed at the beginning of the game
65 66 67 68 69 |
# File 'lib/upwords/shape.rb', line 65 def in_middle_square?(board) board.middle_square.any? do |posn| @positions.include?(posn) end end |
#include?(row, col) ⇒ Boolean
102 103 104 |
# File 'lib/upwords/shape.rb', line 102 def include? (row, col) @positions.include? [row, col] end |
#legal?(board, raise_exception = false) ⇒ Boolean
Check if move creates a legal shape when added to a given board. NOTE: All checks assume that the move in question has not been played on the board yet.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/upwords/shape.rb', line 16 def legal?(board, raise_exception = false) if board.empty? && !in_middle_square?(board) raise IllegalMove, "You must play at least one letter in the middle 2x2 square!" if raise_exception elsif board.empty? && (self.size < board.min_word_length) raise IllegalMove, "Valid words must be at least #{board.min_word_length} letter(s) long!" if raise_exception elsif !straight_line? raise IllegalMove, "The letters in your move must be along a single row or column!" if raise_exception elsif !gaps_covered_by?(board) raise IllegalMove, "The letters in your move must be internally connected!" if raise_exception elsif !(board.empty? || touching?(board)) raise IllegalMove, "At least one letter in your move must be touching a previously played word!" if raise_exception elsif covering_moves?(board) raise IllegalMove, "Cannot completely cover up any previously-played words!" if raise_exception else return true end return false end |
#row_range ⇒ Object
75 76 77 |
# File 'lib/upwords/shape.rb', line 75 def row_range Range.new(*@positions.map {|row, col| row}.minmax) end |
#size ⇒ Object
98 99 100 |
# File 'lib/upwords/shape.rb', line 98 def size @positions.size end |
#straight_line? ⇒ Boolean
71 72 73 |
# File 'lib/upwords/shape.rb', line 71 def straight_line? row_range.size == 1 || col_range.size == 1 end |
#touching?(board) ⇒ Boolean
Check if at least one position within the move shape is adjacent to or overlapping any tile on the board
55 56 57 58 59 60 61 |
# File 'lib/upwords/shape.rb', line 55 def touching?(board) @positions.any? do |row, col| [[0, 0], [1, 0], [-1, 0], [0, 1], [0, -1]].any? do |dr, dc| board.nonempty_space?(row + dr, col + dc) end end end |