Implement basic board intelligent strategy
This commit is contained in:
parent
202f0ce06c
commit
6b591eaa35
6 changed files with 119 additions and 3 deletions
|
@ -3,6 +3,8 @@ require "selenium-webdriver"
|
|||
require "webdrivers"
|
||||
|
||||
require_relative "../nonexistant_guess_error"
|
||||
require_relative "../played_board"
|
||||
require_relative "../played_letter"
|
||||
|
||||
module Board
|
||||
class WordleUnlimited
|
||||
|
@ -80,6 +82,29 @@ module Board
|
|||
end
|
||||
end
|
||||
|
||||
def state
|
||||
PlayedBoard.new(
|
||||
locked_in.map do |row|
|
||||
letters = row
|
||||
.find_all('div.RowL-letter', wait: 0)
|
||||
.map do |letter|
|
||||
state = if letter.[]("class").split.include?("letter-correct")
|
||||
:correct
|
||||
elsif letter.[]("class").split.include?("letter-elsewhere")
|
||||
:elsewhere
|
||||
elsif letter.[]("class").split.include?("letter-absent")
|
||||
:absent
|
||||
end
|
||||
|
||||
PlayedLetter.new(
|
||||
letter: letter.text.downcase,
|
||||
state: state
|
||||
)
|
||||
end
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def exact_letters
|
||||
|
|
17
lib/game.rb
17
lib/game.rb
|
@ -1,13 +1,17 @@
|
|||
require "debug"
|
||||
require "logger"
|
||||
|
||||
require_relative "outcome"
|
||||
require_relative "nonexistant_guess_error"
|
||||
require_relative "outcome"
|
||||
require_relative "played_board"
|
||||
require_relative "played_letter"
|
||||
|
||||
require_relative "board/wordle_unlimited"
|
||||
|
||||
require_relative "dictionary/dictionary"
|
||||
require_relative "dictionary/live_dictionary"
|
||||
|
||||
require_relative "strategy/basic_board"
|
||||
require_relative "strategy/most_common"
|
||||
require_relative "strategy/naive"
|
||||
require_relative "strategy/template"
|
||||
|
@ -16,11 +20,13 @@ require_relative "strategy/wheel_of_fortune"
|
|||
|
||||
class Game
|
||||
attr_reader :board, :dictionary, :start_strategy, :strategy, :outcomes
|
||||
attr :logger
|
||||
|
||||
def initialize(
|
||||
board: Board::WordleUnlimited,
|
||||
dictionary: Dictionary::LiveDictionary,
|
||||
start_strategy: Strategy::MostCommon,
|
||||
strategy: Strategy::Template
|
||||
start_strategy: Strategy::Vowels,
|
||||
strategy: Strategy::BasicBoard
|
||||
)
|
||||
@board = board.new
|
||||
@dictionary = dictionary.new
|
||||
|
@ -28,6 +34,8 @@ class Game
|
|||
@strategy = strategy.new(dictionary: @dictionary)
|
||||
|
||||
@outcomes = []
|
||||
|
||||
@logger = Logger.new("loss-logger.log")
|
||||
end
|
||||
|
||||
def play
|
||||
|
@ -42,6 +50,7 @@ class Game
|
|||
bad_letters: board.bad_letters,
|
||||
guesses: board.guesses,
|
||||
template: board.template,
|
||||
board: board.state,
|
||||
)
|
||||
|
||||
begin
|
||||
|
@ -64,6 +73,8 @@ class Game
|
|||
guesses: board.guesses,
|
||||
)
|
||||
board.reset!
|
||||
|
||||
logger.info(outcomes.last.to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,4 +14,12 @@ class Outcome
|
|||
def loss?
|
||||
state == :loss
|
||||
end
|
||||
|
||||
def to_s
|
||||
"#{state}: #{correct} guessing #{guesses_to_s}"
|
||||
end
|
||||
|
||||
def guesses_to_s
|
||||
guesses.join(", ")
|
||||
end
|
||||
end
|
||||
|
|
21
lib/played_board.rb
Normal file
21
lib/played_board.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
class PlayedBoard < Array
|
||||
def good_letters
|
||||
(correct_letters + elsewhere_letters).uniq
|
||||
end
|
||||
|
||||
def bad_letters
|
||||
absent_letters - good_letters
|
||||
end
|
||||
|
||||
def correct_letters
|
||||
flatten.select(&:correct?).uniq.map(&:letter)
|
||||
end
|
||||
|
||||
def elsewhere_letters
|
||||
flatten.select(&:elsewhere?).uniq.map(&:letter)
|
||||
end
|
||||
|
||||
def absent_letters
|
||||
flatten.select(&:absent?).uniq.map(&:letter)
|
||||
end
|
||||
end
|
20
lib/played_letter.rb
Normal file
20
lib/played_letter.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
class PlayedLetter
|
||||
attr :letter, :state
|
||||
|
||||
def initialize(letter:, state:)
|
||||
@letter = letter
|
||||
@state = state
|
||||
end
|
||||
|
||||
def correct?
|
||||
state == :correct
|
||||
end
|
||||
|
||||
def elsewhere?
|
||||
state == :elsewhere
|
||||
end
|
||||
|
||||
def absent?
|
||||
state == :absent
|
||||
end
|
||||
end
|
31
lib/strategy/basic_board.rb
Normal file
31
lib/strategy/basic_board.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
module Strategy
|
||||
class BasicBoard
|
||||
attr :dictionary, :word_size
|
||||
|
||||
def initialize(dictionary:, word_size: 5)
|
||||
@dictionary = dictionary
|
||||
@word_size = word_size
|
||||
end
|
||||
|
||||
def guess(board:, **args)
|
||||
transposed_board = board.transpose
|
||||
dictionary.words
|
||||
.select { |word| word.length == word_size }
|
||||
.reject { |word| (word.chars & board.bad_letters).any? }
|
||||
.select { |word| (board.good_letters - word.chars).length == 0 }
|
||||
.reject do |word| # any word has character where board has letter absent
|
||||
transposed_board.each_with_index.any? do |letters, index|
|
||||
letters.reject(&:correct?).map(&:letter).include?(word[index])
|
||||
end
|
||||
end
|
||||
.select do |word| # make sure correct letters used in right spot
|
||||
transposed_board.each_with_index.all? do |letters, index|
|
||||
correct_letter = letters.select(&:correct?).first
|
||||
|
||||
!correct_letter || word[index] == correct_letter.letter
|
||||
end
|
||||
end
|
||||
.sample
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue