Initial commit
This commit is contained in:
commit
b4a061c6d7
5 changed files with 258 additions and 0 deletions
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
dictionary.txt
|
||||||
|
bad-in-dictionary.txt
|
||||||
|
|
||||||
|
*.log
|
7
Gemfile
Normal file
7
Gemfile
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
source "https://rubygems.org"
|
||||||
|
|
||||||
|
gem "pry"
|
||||||
|
|
||||||
|
gem "capybara"
|
||||||
|
gem "selenium-webdriver"
|
||||||
|
gem "webdrivers"
|
54
Gemfile.lock
Normal file
54
Gemfile.lock
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
GEM
|
||||||
|
remote: https://rubygems.org/
|
||||||
|
specs:
|
||||||
|
addressable (2.8.0)
|
||||||
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
|
capybara (3.36.0)
|
||||||
|
addressable
|
||||||
|
matrix
|
||||||
|
mini_mime (>= 0.1.3)
|
||||||
|
nokogiri (~> 1.8)
|
||||||
|
rack (>= 1.6.0)
|
||||||
|
rack-test (>= 0.6.3)
|
||||||
|
regexp_parser (>= 1.5, < 3.0)
|
||||||
|
xpath (~> 3.2)
|
||||||
|
childprocess (4.1.0)
|
||||||
|
coderay (1.1.3)
|
||||||
|
matrix (0.4.2)
|
||||||
|
method_source (1.0.0)
|
||||||
|
mini_mime (1.1.2)
|
||||||
|
nokogiri (1.13.1-x86_64-linux)
|
||||||
|
racc (~> 1.4)
|
||||||
|
pry (0.14.1)
|
||||||
|
coderay (~> 1.1)
|
||||||
|
method_source (~> 1.0)
|
||||||
|
public_suffix (4.0.6)
|
||||||
|
racc (1.6.0)
|
||||||
|
rack (2.2.3)
|
||||||
|
rack-test (1.1.0)
|
||||||
|
rack (>= 1.0, < 3)
|
||||||
|
regexp_parser (2.2.0)
|
||||||
|
rexml (3.2.5)
|
||||||
|
rubyzip (2.3.2)
|
||||||
|
selenium-webdriver (4.1.0)
|
||||||
|
childprocess (>= 0.5, < 5.0)
|
||||||
|
rexml (~> 3.2, >= 3.2.5)
|
||||||
|
rubyzip (>= 1.2.2)
|
||||||
|
webdrivers (5.0.0)
|
||||||
|
nokogiri (~> 1.6)
|
||||||
|
rubyzip (>= 1.3.0)
|
||||||
|
selenium-webdriver (~> 4.0)
|
||||||
|
xpath (3.2.0)
|
||||||
|
nokogiri (~> 1.8)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
x86_64-linux
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
capybara
|
||||||
|
pry
|
||||||
|
selenium-webdriver
|
||||||
|
webdrivers
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
2.2.22
|
140
finder.rb
Executable file
140
finder.rb
Executable file
|
@ -0,0 +1,140 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require "pry"
|
||||||
|
require "logger"
|
||||||
|
|
||||||
|
require "capybara"
|
||||||
|
require "selenium-webdriver"
|
||||||
|
require "webdrivers"
|
||||||
|
|
||||||
|
@logger = Logger.new("run.log")
|
||||||
|
@logger.info("Beginning new run")
|
||||||
|
|
||||||
|
def measure(label, &block)
|
||||||
|
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||||
|
result = yield
|
||||||
|
finish = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||||
|
|
||||||
|
# @logger.info("#{label.to_s}: #{finish - start} seconds")
|
||||||
|
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
bad_words = File.readlines("bad-in-dictionary.txt").map(&:strip)
|
||||||
|
all_words = File.readlines("dictionary.txt").map(&:strip) - bad_words
|
||||||
|
word_size = 5
|
||||||
|
ignore = []
|
||||||
|
|
||||||
|
session = Capybara::Session.new(:selenium_chrome)
|
||||||
|
session.visit "https://www.wordleunlimited.com/"
|
||||||
|
|
||||||
|
loop do
|
||||||
|
bad_letters = measure(:bad) do
|
||||||
|
session
|
||||||
|
.find_all('div.Game-keyboard-button.letter-absent', wait: 0)
|
||||||
|
.map(&:text)
|
||||||
|
.map(&:downcase)
|
||||||
|
end
|
||||||
|
exact_letters = measure(:exact) do
|
||||||
|
session
|
||||||
|
.find_all('div.Game-keyboard-button.letter-correct', wait: 0)
|
||||||
|
.map(&:text)
|
||||||
|
.map(&:downcase)
|
||||||
|
end
|
||||||
|
elsewhere_letters = measure(:elsewhere) do
|
||||||
|
session
|
||||||
|
.find_all('div.Game-keyboard-button.letter-elsewhere', wait: 0)
|
||||||
|
.map(&:text)
|
||||||
|
.map(&:downcase)
|
||||||
|
end
|
||||||
|
letters = exact_letters + elsewhere_letters
|
||||||
|
locked_in = measure(:locked) do
|
||||||
|
session.find_all('div.RowL.RowL-locked-in', wait: 0)
|
||||||
|
end
|
||||||
|
guesses = locked_in.map { |row| row.text.tr("\n", "").downcase }
|
||||||
|
template = measure(:template) do
|
||||||
|
if locked_in.any?
|
||||||
|
locked_in
|
||||||
|
.last
|
||||||
|
.find_all('div.RowL-letter', wait: 0)
|
||||||
|
.map do |letter|
|
||||||
|
if letter.[]("class").split.include?("letter-correct")
|
||||||
|
letter.text.downcase
|
||||||
|
else
|
||||||
|
"*"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Array.new(5, "*")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elsewhere_template = Array.new(5) { [] }
|
||||||
|
measure(:block_letters) do
|
||||||
|
if locked_in.any?
|
||||||
|
locked_in.each do |guess|
|
||||||
|
guess
|
||||||
|
.find_all('div.RowL-letter', wait: 0).each_with_index do |letter, index|
|
||||||
|
if letter.[]("class").split.include?("letter-elsewhere") || letter.[]("class").split.include?("letter-absent")
|
||||||
|
elsewhere_template[index] << letter.text.downcase
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if template.none? { |letter| letter == "*" }
|
||||||
|
@logger.info("You won with #{guesses.join(', ')}")
|
||||||
|
session.find('div.Game-keyboard-button', text: 'Enter', wait: 0).click()
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
if letters.none? && locked_in.none?
|
||||||
|
letters = "aetsr".chars
|
||||||
|
end
|
||||||
|
|
||||||
|
if locked_in.count == 6
|
||||||
|
@logger.info("You lost #{guesses.join(', ')}")
|
||||||
|
session.find('div.Game-keyboard-button', text: 'Enter', wait: 0).click()
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
guess = all_words
|
||||||
|
.select { |word| word.length == word_size }
|
||||||
|
.reject { |word| bad_letters.any? { |letter| word.chars.include?(letter) } }
|
||||||
|
.select { |word| (letters - word.chars).length == 0 }
|
||||||
|
.reject { |word| ignore.include?(word) }
|
||||||
|
.reject { |word| guesses.include?(word) }
|
||||||
|
.select do |word|
|
||||||
|
template.each_with_index.all? do |letter, index|
|
||||||
|
letter == "*" || letter == word.chars[index]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
.select do |word|
|
||||||
|
word.chars.each_with_index.all? do |letter, index|
|
||||||
|
(elsewhere_template[index] - [letter]) == elsewhere_template[index]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
.sample
|
||||||
|
|
||||||
|
measure(:guess) do
|
||||||
|
guess.chars.map(&:upcase).each do |letter|
|
||||||
|
session
|
||||||
|
.find('div.Game-keyboard-button', text: /\A#{letter}\Z/, wait: 0)
|
||||||
|
.click()
|
||||||
|
end
|
||||||
|
session
|
||||||
|
.find('div.Game-keyboard-button', text: 'Enter', wait: 0)
|
||||||
|
.click()
|
||||||
|
end
|
||||||
|
|
||||||
|
measure(:not_found) do
|
||||||
|
if session.has_text?(:visible, "Not a valid word", wait: 2)
|
||||||
|
ignore << guess
|
||||||
|
File.open('bad-in-dictionary.txt', 'a') do |file|
|
||||||
|
file.write("#{guess}\n")
|
||||||
|
end
|
||||||
|
5.times do
|
||||||
|
session.find('div.Game-keyboard-button', text: '⌫', wait: 0).click()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
53
manual.rb
Normal file
53
manual.rb
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'pry'
|
||||||
|
|
||||||
|
all_words = File.readlines("dictionary.txt")
|
||||||
|
lower = ('a'..'z').to_a
|
||||||
|
upper = ('A'..'Z').to_a
|
||||||
|
|
||||||
|
guesses = []
|
||||||
|
letters = []
|
||||||
|
bad_letters = []
|
||||||
|
template = []
|
||||||
|
while guesses.size < 6
|
||||||
|
print "Your guess: "
|
||||||
|
guess = gets.strip
|
||||||
|
print "New bad letters: "
|
||||||
|
new_bad_letters = gets.strip.chars
|
||||||
|
|
||||||
|
if guesses.size == 0
|
||||||
|
guesses << guess
|
||||||
|
length = guess.length
|
||||||
|
template = Array.new(length, "*")
|
||||||
|
end
|
||||||
|
|
||||||
|
if guess == "X"
|
||||||
|
guesses.pop
|
||||||
|
else
|
||||||
|
bad_letters += new_bad_letters
|
||||||
|
letters += guess.chars
|
||||||
|
.reject { |letter| new_bad_letters.include?(letter) }
|
||||||
|
.map(&:downcase)
|
||||||
|
|
||||||
|
guess.chars.each_with_index do |letter, index|
|
||||||
|
template[index] = letter if upper.include?(letter)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
guesses << all_words
|
||||||
|
.map(&:strip)
|
||||||
|
.select { |word| word.length == length }
|
||||||
|
.reject { |word| bad_letters.any? { |letter| word.chars.include?(letter) } }
|
||||||
|
.select { |word| (letters - word.chars).length == 0 }
|
||||||
|
.select do |word|
|
||||||
|
template.map(&:downcase).each_with_index.all? do |letter, index|
|
||||||
|
letter == "*" || letter == word[index]
|
||||||
|
end
|
||||||
|
end.sample
|
||||||
|
|
||||||
|
puts "You should guess '#{guesses.last}'"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
puts guesses
|
Loading…
Reference in a new issue