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 "webdrivers"
|
||||||
|
|
||||||
require_relative "../nonexistant_guess_error"
|
require_relative "../nonexistant_guess_error"
|
||||||
|
require_relative "../played_board"
|
||||||
|
require_relative "../played_letter"
|
||||||
|
|
||||||
module Board
|
module Board
|
||||||
class WordleUnlimited
|
class WordleUnlimited
|
||||||
|
@ -80,6 +82,29 @@ module Board
|
||||||
end
|
end
|
||||||
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
|
private
|
||||||
|
|
||||||
def exact_letters
|
def exact_letters
|
||||||
|
|
17
lib/game.rb
17
lib/game.rb
|
@ -1,13 +1,17 @@
|
||||||
require "debug"
|
require "debug"
|
||||||
|
require "logger"
|
||||||
|
|
||||||
require_relative "outcome"
|
|
||||||
require_relative "nonexistant_guess_error"
|
require_relative "nonexistant_guess_error"
|
||||||
|
require_relative "outcome"
|
||||||
|
require_relative "played_board"
|
||||||
|
require_relative "played_letter"
|
||||||
|
|
||||||
require_relative "board/wordle_unlimited"
|
require_relative "board/wordle_unlimited"
|
||||||
|
|
||||||
require_relative "dictionary/dictionary"
|
require_relative "dictionary/dictionary"
|
||||||
require_relative "dictionary/live_dictionary"
|
require_relative "dictionary/live_dictionary"
|
||||||
|
|
||||||
|
require_relative "strategy/basic_board"
|
||||||
require_relative "strategy/most_common"
|
require_relative "strategy/most_common"
|
||||||
require_relative "strategy/naive"
|
require_relative "strategy/naive"
|
||||||
require_relative "strategy/template"
|
require_relative "strategy/template"
|
||||||
|
@ -16,11 +20,13 @@ require_relative "strategy/wheel_of_fortune"
|
||||||
|
|
||||||
class Game
|
class Game
|
||||||
attr_reader :board, :dictionary, :start_strategy, :strategy, :outcomes
|
attr_reader :board, :dictionary, :start_strategy, :strategy, :outcomes
|
||||||
|
attr :logger
|
||||||
|
|
||||||
def initialize(
|
def initialize(
|
||||||
board: Board::WordleUnlimited,
|
board: Board::WordleUnlimited,
|
||||||
dictionary: Dictionary::LiveDictionary,
|
dictionary: Dictionary::LiveDictionary,
|
||||||
start_strategy: Strategy::MostCommon,
|
start_strategy: Strategy::Vowels,
|
||||||
strategy: Strategy::Template
|
strategy: Strategy::BasicBoard
|
||||||
)
|
)
|
||||||
@board = board.new
|
@board = board.new
|
||||||
@dictionary = dictionary.new
|
@dictionary = dictionary.new
|
||||||
|
@ -28,6 +34,8 @@ class Game
|
||||||
@strategy = strategy.new(dictionary: @dictionary)
|
@strategy = strategy.new(dictionary: @dictionary)
|
||||||
|
|
||||||
@outcomes = []
|
@outcomes = []
|
||||||
|
|
||||||
|
@logger = Logger.new("loss-logger.log")
|
||||||
end
|
end
|
||||||
|
|
||||||
def play
|
def play
|
||||||
|
@ -42,6 +50,7 @@ class Game
|
||||||
bad_letters: board.bad_letters,
|
bad_letters: board.bad_letters,
|
||||||
guesses: board.guesses,
|
guesses: board.guesses,
|
||||||
template: board.template,
|
template: board.template,
|
||||||
|
board: board.state,
|
||||||
)
|
)
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
@ -64,6 +73,8 @@ class Game
|
||||||
guesses: board.guesses,
|
guesses: board.guesses,
|
||||||
)
|
)
|
||||||
board.reset!
|
board.reset!
|
||||||
|
|
||||||
|
logger.info(outcomes.last.to_s)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,4 +14,12 @@ class Outcome
|
||||||
def loss?
|
def loss?
|
||||||
state == :loss
|
state == :loss
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"#{state}: #{correct} guessing #{guesses_to_s}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def guesses_to_s
|
||||||
|
guesses.join(", ")
|
||||||
|
end
|
||||||
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