Class: Linotype::Game
- Inherits:
-
Object
- Object
- Linotype::Game
- Defined in:
- lib/linotype/game.rb
Instance Attribute Summary collapse
-
#current_player ⇒ Object
readonly
Returns the value of attribute current_player.
-
#moves ⇒ Object
Returns the value of attribute moves.
Instance Method Summary collapse
- #best_next_play ⇒ Object
- #board ⇒ Object
- #calc_potential_plays(remaining_letters) ⇒ Object
- #covered_tiles(player) ⇒ Object
- #create_tile_letter_array(letter_arg) ⇒ Object
- #defended_tiles(player) ⇒ Object
- #dictionary ⇒ Object
- #every_play_for_word(word) ⇒ Object
-
#initialize(args = {}) ⇒ Game
constructor
A new instance of Game.
- #invalid_moves ⇒ Object
- #letters ⇒ Object
- #other_player ⇒ Object
- #over? ⇒ Boolean
- #play(*tile_coordinates) ⇒ Object
- #player_number(player) ⇒ Object
- #potential_plays(remaining_letters = letters) ⇒ Object
- #score(player) ⇒ Object
- #scores ⇒ Object
- #test_potential_plays ⇒ Object
- #tile_rows ⇒ Object
- #toggle_current_player ⇒ Object
- #undo_last_move! ⇒ Object
- #valid_moves ⇒ Object
- #valid_potential_plays ⇒ Object
- #winner ⇒ Object
- #word_match(letter_group, word) ⇒ Object
Constructor Details
Instance Attribute Details
#current_player ⇒ Object (readonly)
Returns the value of attribute current_player.
5 6 7 |
# File 'lib/linotype/game.rb', line 5 def current_player @current_player end |
#moves ⇒ Object
Returns the value of attribute moves.
4 5 6 |
# File 'lib/linotype/game.rb', line 4 def moves @moves end |
Instance Method Details
#best_next_play ⇒ Object
77 78 79 |
# File 'lib/linotype/game.rb', line 77 def best_next_play valid_potential_plays.sort { |a, b| b[:score][:defended] <=> a[:score][:defended] }.first end |
#board ⇒ Object
101 102 103 |
# File 'lib/linotype/game.rb', line 101 def board tile_rows.collect { |row| row.collect { |tile| tile.to_hash } } end |
#calc_potential_plays(remaining_letters) ⇒ Object
117 118 119 120 121 122 123 124 125 126 |
# File 'lib/linotype/game.rb', line 117 def calc_potential_plays(remaining_letters) plays = [] letter_group = letters.group_by { |l| l } dictionary.words.each do |word| if word_match(letter_group, word) plays << word end end plays end |
#covered_tiles(player) ⇒ Object
183 184 185 |
# File 'lib/linotype/game.rb', line 183 def covered_tiles(player) tile_rows.flatten.select { |tile| tile.covered_by == player } end |
#create_tile_letter_array(letter_arg) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/linotype/game.rb', line 14 def create_tile_letter_array(letter_arg) case letter_arg when nil Board.new_random_letters when Array letter_arg when String square_size = Math.sqrt(letter_arg.length).ceil letter_array = [[]] letter_arg.each_char do |letter| letter_array << [] if letter_array.last.size == square_size letter_array.last << letter.upcase end letter_array end end |
#defended_tiles(player) ⇒ Object
179 180 181 |
# File 'lib/linotype/game.rb', line 179 def defended_tiles(player) tile_rows.flatten.select { |tile| tile.covered_by == player && tile.defended? } end |
#dictionary ⇒ Object
144 145 146 |
# File 'lib/linotype/game.rb', line 144 def dictionary Linotype::Dictionary.loaded end |
#every_play_for_word(word) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/linotype/game.rb', line 36 def every_play_for_word(word) tiles_per_letter = {} word.chars.to_a.uniq.each do |unique_letter| tiles_per_letter[unique_letter] = [] tile_rows.flatten.select { |tile| tile.letter == unique_letter }.each do |matching_tile| tiles_per_letter[unique_letter] << matching_tile end end variations = tiles_per_letter.values.inject(1) { |vars, tiles| tiles.count * vars } plays = [] v = 0 variations.times { plays << []; v += 1 } word.chars.each do |letter| play_number = 0 repetitions = variations / tiles_per_letter[letter].count tiles_per_letter[letter].each do |tile| repetitions.times do plays[play_number] << tile play_number += 1 end end end plays.select { |play| play.uniq.count == play.count } end |
#invalid_moves ⇒ Object
140 141 142 |
# File 'lib/linotype/game.rb', line 140 def invalid_moves @moves.select(&:invalid?) end |
#letters ⇒ Object
152 153 154 |
# File 'lib/linotype/game.rb', line 152 def letters @board.tiles.flatten.collect(&:letter) end |
#other_player ⇒ Object
156 157 158 |
# File 'lib/linotype/game.rb', line 156 def other_player @players.index(@current_player) == 0 ? @players[1] : @players[0] end |
#over? ⇒ Boolean
89 90 91 |
# File 'lib/linotype/game.rb', line 89 def over? uncovered_tiles.empty? || two_passes_in_a_row? end |
#play(*tile_coordinates) ⇒ Object
31 32 33 34 |
# File 'lib/linotype/game.rb', line 31 def play(*tile_coordinates) tiles = find_tiles(tile_coordinates) Move.new(self, @current_player, tiles).valid? end |
#player_number(player) ⇒ Object
105 106 107 |
# File 'lib/linotype/game.rb', line 105 def player_number(player) @players.index(player) + 1 end |
#potential_plays(remaining_letters = letters) ⇒ Object
113 114 115 |
# File 'lib/linotype/game.rb', line 113 def potential_plays(remaining_letters=letters) @potential_plays ||= calc_potential_plays(remaining_letters) end |
#score(player) ⇒ Object
109 110 111 |
# File 'lib/linotype/game.rb', line 109 def score(player) covered_tiles(player).count end |
#scores ⇒ Object
97 98 99 |
# File 'lib/linotype/game.rb', line 97 def scores @players.inject({}) { |scores, player| scores[player_number(player)] = score(player); scores } end |
#test_potential_plays ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/linotype/game.rb', line 61 def test_potential_plays potential_moves = [] potential_plays.each do |word_to_test| every_play_for_word(word_to_test).each do |tiles| move = Move.new(self, @current_player, tiles) potential_moves << move undo_last_move! end end potential_moves.collect(&:to_hash) end |
#tile_rows ⇒ Object
148 149 150 |
# File 'lib/linotype/game.rb', line 148 def tile_rows @board.tiles end |
#toggle_current_player ⇒ Object
170 171 172 |
# File 'lib/linotype/game.rb', line 170 def toggle_current_player @current_player = other_player end |
#undo_last_move! ⇒ Object
81 82 83 84 85 86 87 |
# File 'lib/linotype/game.rb', line 81 def undo_last_move! if (last_move = moves.pop) && last_move.valid? last_move.uncover_tiles! @current_player = other_player if last_move.valid? end moves.last.cover_tiles! if moves.any? end |
#valid_moves ⇒ Object
136 137 138 |
# File 'lib/linotype/game.rb', line 136 def valid_moves @moves.select(&:valid?) end |
#valid_potential_plays ⇒ Object
73 74 75 |
# File 'lib/linotype/game.rb', line 73 def valid_potential_plays test_potential_plays.select { |potential_play| potential_play[:valid] } end |
#winner ⇒ Object
93 94 95 |
# File 'lib/linotype/game.rb', line 93 def winner scores.inject(nil) { |winner, p| p[1] > winner.to_i ? p[0] : winner } if over? end |
#word_match(letter_group, word) ⇒ Object
128 129 130 131 132 133 134 |
# File 'lib/linotype/game.rb', line 128 def word_match(letter_group, word) word_letter_group = word.chars.to_a.group_by { |c| c } word.each_char do |letter| return false unless (letter_group[letter] && letter_group[letter].count >= word_letter_group[letter].count) end true end |