Method: Upwords::Player#cpu_move
- Defined in:
- lib/upwords/player.rb
#cpu_move(board, dict, batch_size = 1000, min_score = 0) ⇒ Object
Execute a legal move based on a predefined strategy
Basic strategy:
-
Find all legal move shapes and all possible letter permutations across those shapes (this computation is relatively quick)
-
Retun the highest score from permutation that do not produce in any illegal new words (this computation is slow…)
-
To speed up the above computation: + Only check a batch of permutations at a time (specified in ‘batch_size’ argument) + After each batch, terminate the subroutine if it finds a score that is at least as high as the given ‘min_score’ + Decrement the ‘min_score’ after each batch that does not terminate the subroutine to prevent endless searches
TODO: refactor the the ‘strategy’ component out of this method, so different strategies can be swapped in and out
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/upwords/player.rb', line 135 def cpu_move(board, dict, batch_size = 1000, min_score = 0) possible_moves = self.legal_move_shapes_letter_permutations(board) possible_moves.shuffle! top_score = 0 top_score_move = nil while top_score_move.nil? || (top_score < min_score) do # Check if next batch contains any legal moves and save the top score ([batch_size, possible_moves.size].min).times do move_arr = possible_moves.pop move = Move.new(move_arr) if move.legal_words?(board, dict) move_score = move.score(board, self) if move_score >= top_score top_score = move_score top_score_move = move_arr end end end # Decrement minimum required score after each cycle to help prevent long searches min_score = [(min_score - 1), 0].max end top_score_move end |