wordle_decoder 0.1.0 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -2
- data/Gemfile.lock +1 -1
- data/LICENSE.md +1 -0
- data/README.md +22 -5
- data/bin/wordle_decoder +142 -0
- data/lib/wordle_decoder/version.rb +1 -1
- data/lib/wordle_decoder/wordle_share.rb +34 -3
- data/lib/wordle_decoder.rb +8 -12
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f99c89b38bbf201f3cc823ce9cb134d952b2b58a9fd0832f92bfab41e63bd01
|
4
|
+
data.tar.gz: bcd052c478b24f5e0b5d360007688f04edd0c5fd47c8870f426759168fe4cc97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9641a6f0cce9a39b9b137a72ef8e7fc9cf0cb310ca658c2182cfe9aa3c8c66916ccacfcd76ea57236c8fd3b7e25182b9833433453f25acadbd31e35f4ca1a037
|
7
|
+
data.tar.gz: 6f39d15f60434b8a88a30c018b9860198c3d7080566a937cabd0d2d152232e599fb10e7b0a85969e405651c67c8cc65a681fcd0c5eaaf248d7aef1f58b075cd5
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/LICENSE.md
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
https://creativecommons.org/licenses/by-nc-sa/2.0/legalcode
|
data/README.md
CHANGED
@@ -1,19 +1,36 @@
|
|
1
1
|
# Wordle Decoder
|
2
2
|
|
3
|
-
It guesses your guesses based on all those little
|
3
|
+
It guesses your guesses based on all those little square emojis that we now love to share.
|
4
4
|
|
5
|
-
Given your Wordle share
|
5
|
+
Given your Wordle share, the decoder will spit back the five-letter words it thinks you played with some degree of confidence.
|
6
6
|
|
7
7
|
## Installation
|
8
8
|
|
9
|
+
Have Ruby 2.7 or later installed, then run the following at the command line:
|
10
|
+
|
9
11
|
$ gem install wordle_decoder
|
10
12
|
|
11
13
|
## Usage
|
12
14
|
|
13
|
-
After
|
15
|
+
After installing the gem, run `wordle_decoder` at the command line like so:
|
14
16
|
|
15
17
|
$ wordle_decoder
|
16
18
|
|
17
|
-
|
19
|
+
You'll be prompted to share your wordle. Go ahead and paste in your wordle share text. The share text should look something like this:
|
20
|
+
|
21
|
+
```
|
22
|
+
Wordle 258 3/6
|
23
|
+
|
24
|
+
⬛⬛🟨⬛🟨
|
25
|
+
⬛🟩🟩🟩⬛
|
26
|
+
🟩🟩🟩🟩🟩
|
27
|
+
```
|
28
|
+
You'll then be prompted to confirm the word of the day, or if it couldn't figure it out, you'll be asked for it. After that, it'll _try_ to guess your guesses.
|
29
|
+
|
30
|
+
## Why?
|
31
|
+
|
32
|
+
I wasn't sure if something like this was possible and thought it'd be a fun project to build. It does a pretty good job, at least some of the time... I built an excuse to play Wordle.
|
33
|
+
|
34
|
+
Enjoy,
|
18
35
|
|
19
|
-
|
36
|
+
[@mattruzicka](https://twitter.com/mattruzicka)
|
data/bin/wordle_decoder
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "wordle_decoder"
|
6
|
+
|
7
|
+
require "cli/ui"
|
8
|
+
|
9
|
+
CLI::UI::StdoutRouter.enable
|
10
|
+
|
11
|
+
print CLI::UI.fmt("\n Share your wordle:\n\n{{blue:>}} ")
|
12
|
+
|
13
|
+
input_lines = []
|
14
|
+
until WordleDecoder::WordleShare.final_line?(input_line = gets)
|
15
|
+
input_lines << input_line
|
16
|
+
if WordleDecoder::WordleShare.exit_program?(input_line)
|
17
|
+
puts "\n Goodbye!\n\n"
|
18
|
+
return
|
19
|
+
elsif WordleDecoder::WordleShare.needs_help?(input_line)
|
20
|
+
help_text = WordleDecoder::WordleShare.help_to_terminal
|
21
|
+
input_lines << "\n"
|
22
|
+
input_lines << help_text
|
23
|
+
input_lines << "\n"
|
24
|
+
print CLI::UI.fmt(help_text)
|
25
|
+
elsif input_lines.all? { |l| l.strip.empty? }
|
26
|
+
print CLI::UI.fmt("{{blue:>}} ")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
input_lines << input_line
|
30
|
+
|
31
|
+
clear_pasted_text_lines = input_lines.reverse_each.map { |line| "\033[A\r #{" " * line.length}" }
|
32
|
+
clear_pasted_text_lines << "\033[A\r "
|
33
|
+
puts clear_pasted_text_lines.join
|
34
|
+
|
35
|
+
wordle_share = WordleDecoder::WordleShare.new(input_lines)
|
36
|
+
puts CLI::UI.fmt(wordle_share.to_terminal)
|
37
|
+
puts "\n\n"
|
38
|
+
|
39
|
+
if wordle_share.find_answer
|
40
|
+
answer_confirmed = CLI::UI::Prompt.confirm("\r Is \"{{green:#{wordle_share.answer}}}\" the word of the day?")
|
41
|
+
unless answer_confirmed
|
42
|
+
wordle_share.answer = nil
|
43
|
+
puts "\n"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
wordle_share.answer_input = CLI::UI.ask("\r What was the word of the day?") until wordle_share.answer
|
48
|
+
|
49
|
+
puts "\n\n"
|
50
|
+
|
51
|
+
decoder = wordle_share.decoder
|
52
|
+
|
53
|
+
CLI::UI::Spinner.spin("Acting like I'm doing something.") do |spinner|
|
54
|
+
ellipsis_cycle = %w[.. ... .].cycle
|
55
|
+
stop_acting_at = Time.now.utc + 2
|
56
|
+
until Time.now.utc > stop_acting_at
|
57
|
+
sleep 0.3
|
58
|
+
spinner.update_title("Acting like I'm doing something#{ellipsis_cycle.next}")
|
59
|
+
end
|
60
|
+
spinner.update_title("Fine, I'll do it")
|
61
|
+
|
62
|
+
if decoder.best_guess
|
63
|
+
spinner.update_title("\r I decoded your wordle hints!}}")
|
64
|
+
else
|
65
|
+
no_guess_messages = ["You stumped me!", "Are you messing with me?", "Are you sure that was the word of the day?"]
|
66
|
+
spinner.update_title("\r 🤨 #{no_guess_messages.sample}}}")
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
if decoder.best_guess
|
71
|
+
puts CLI::UI.fmt("\n {{blue:{{underline:Guesses}} {{underline:Confidence}}}}")
|
72
|
+
puts CLI::UI.fmt(decoder.to_terminal)
|
73
|
+
end
|
74
|
+
|
75
|
+
salutations = ["Maybe some of those are your words!",
|
76
|
+
"I tried!",
|
77
|
+
"How'd I do?",
|
78
|
+
"Did I get it?",
|
79
|
+
"I'm also guessing you're great!",
|
80
|
+
"Don't spill your coffee.",
|
81
|
+
"Shout out to friends for sending me their wordles.",
|
82
|
+
"Shout out to https://www.youtube.com/watch?v=v68zYyaEmEA for word frequency source.",
|
83
|
+
"I hope you had a great time.",
|
84
|
+
"Hope to see you again.",
|
85
|
+
"Was great guessing you.",
|
86
|
+
"Thinking about heading to sleep.",
|
87
|
+
"Sometimes I just throw out mostly random stuff.",
|
88
|
+
"I didn't mean to offend.",
|
89
|
+
"I try not to be random...",
|
90
|
+
"I'm open source :)",
|
91
|
+
"I'd fork you to make me better.",
|
92
|
+
"TLDR: Another programmer played wordle.",
|
93
|
+
"How was I with my words?",
|
94
|
+
"I'm written in Ruby and bite like a python.",
|
95
|
+
"Here's an emoji ❤️",
|
96
|
+
"🤔 🤨 🧐",
|
97
|
+
"All my thinking to you.",
|
98
|
+
"I've learned about wordle and your people.",
|
99
|
+
"I'm not learning anything at the moment.",
|
100
|
+
"I wish I had time to machine learn you ;)",
|
101
|
+
"No, you have a great personality!",
|
102
|
+
"This one might be weird, if it's your first.",
|
103
|
+
"Is my strategy as good as yours?",
|
104
|
+
"I'm biased, but so are you!",
|
105
|
+
"I'd love to learn your strategy ;)",
|
106
|
+
"I'd grow neurons for you.",
|
107
|
+
"How well can you play without me guessing?",
|
108
|
+
"If you're seeing this, we probably know each other.",
|
109
|
+
"I hope things aren't getting too weird.",
|
110
|
+
"❤️ ❤️ ❤️",
|
111
|
+
"No, you're great!",
|
112
|
+
"Do you decode often?",
|
113
|
+
"All the best five-letter words to you!",
|
114
|
+
"My friends call me the wordle decoder.",
|
115
|
+
"Everything I am is written.",
|
116
|
+
"May my written code speak truly.",
|
117
|
+
"Who guessed better?",
|
118
|
+
"No excuse, but my thoughts are in a constant array.",
|
119
|
+
"Your words complete me.",
|
120
|
+
"Like peering into a soul.",
|
121
|
+
"I hope I didn't embarass myself.",
|
122
|
+
"I hope I didn't embarrass myself.",
|
123
|
+
"I hope I didn't embaras myself.",
|
124
|
+
"Can you decode my five letter word?",
|
125
|
+
"Sometimes I'm off by one...",
|
126
|
+
"Something's fishy...",
|
127
|
+
"Did you put something on me?",
|
128
|
+
"I'm only wrong about five letter words...",
|
129
|
+
"Your words are beautiful.",
|
130
|
+
"You make this wordle a better place!",
|
131
|
+
"What in the wordle was I thinking?",
|
132
|
+
"Those words you gave me were so good.",
|
133
|
+
"I truly enjoyed those words, thank you!",
|
134
|
+
"What lovely words you have!",
|
135
|
+
"I hope my words were as good as yours!",
|
136
|
+
"Please enjoy the rest of your day!",
|
137
|
+
"I may not be positive about your words, but I am about you!",
|
138
|
+
"Thank you for spending time with me!",
|
139
|
+
"I enjoyed our time together!"].freeze
|
140
|
+
|
141
|
+
puts CLI::UI.fmt("\n\n #{salutations.sample}\n " \
|
142
|
+
"{{blue:https://github.com/mattruzicka/wordle_decoder}}}}\n\n")
|
@@ -2,12 +2,31 @@
|
|
2
2
|
|
3
3
|
class WordleDecoder
|
4
4
|
class WordleShare
|
5
|
-
ANSWER_LINES = ["🟩🟩🟩🟩🟩",
|
5
|
+
ANSWER_LINES = ["🟩🟩🟩🟩🟩",
|
6
|
+
"ggggg",
|
7
|
+
":large_green_square:" * 5].freeze
|
6
8
|
|
7
9
|
def self.final_line?(input_lines)
|
8
10
|
ANSWER_LINES.any? { input_lines.include?(_1) }
|
9
11
|
end
|
10
12
|
|
13
|
+
NEEDS_HELP_INPUTS = %w[help what wordle wat ? man okay yes no test].freeze
|
14
|
+
|
15
|
+
def self.needs_help?(input)
|
16
|
+
NEEDS_HELP_INPUTS.include?(input.strip.downcase)
|
17
|
+
end
|
18
|
+
|
19
|
+
EXIT_PROGRAM_INPUTS = %w[exit no nvm].freeze
|
20
|
+
|
21
|
+
def self.exit_program?(input)
|
22
|
+
EXIT_PROGRAM_INPUTS.include?(input.strip)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.help_to_terminal
|
26
|
+
"\n {{italic:Copy and paste those 🟨, 🟩, and ⬛" \
|
27
|
+
" emojis from your wordle share.}} \n\n{{blue:>}} "
|
28
|
+
end
|
29
|
+
|
11
30
|
def self.wordle_answers
|
12
31
|
@wordle_answers ||= load_worldle_ansers
|
13
32
|
end
|
@@ -36,6 +55,8 @@ class WordleDecoder
|
|
36
55
|
|
37
56
|
def find_answer
|
38
57
|
title_line = input_lines.detect { |line| line.match?(GAME_DAY_REGEX) }
|
58
|
+
return unless title_line
|
59
|
+
|
39
60
|
game_day = title_line.match(GAME_DAY_REGEX).captures.first&.to_i
|
40
61
|
self.answer = self.class.wordle_answers[game_day]
|
41
62
|
end
|
@@ -80,11 +101,21 @@ class WordleDecoder
|
|
80
101
|
VALID_HINT_CHARS = WordPosition::EMOJI_HINT_CHARS.to_a.flatten.uniq
|
81
102
|
|
82
103
|
def parse_wordle_lines!
|
83
|
-
input_lines.
|
84
|
-
line
|
104
|
+
input_lines.filter_map do |line|
|
105
|
+
line = translate_emoji_shortcodes(line)
|
106
|
+
line if line.each_char.all? { |c| VALID_HINT_CHARS.include?(c) }
|
85
107
|
end
|
86
108
|
end
|
87
109
|
|
110
|
+
SHORTCODES_TO_EMOJIS = { ":black_large_square:" => "⬛",
|
111
|
+
":white_large_square:" => "⬜",
|
112
|
+
":large_green_square:" => "🟩",
|
113
|
+
":large_yellow_square:" => "🟨" }.freeze
|
114
|
+
|
115
|
+
def translate_emoji_shortcodes(line)
|
116
|
+
SHORTCODES_TO_EMOJIS.reduce(line) { |acc, (key, val)| acc.gsub(key, val) }
|
117
|
+
end
|
118
|
+
|
88
119
|
def parse_input_lines!
|
89
120
|
case input
|
90
121
|
when String
|
data/lib/wordle_decoder.rb
CHANGED
@@ -14,10 +14,6 @@ class WordleDecoder
|
|
14
14
|
@wordle_share = wordle_share
|
15
15
|
end
|
16
16
|
|
17
|
-
def to_terminal
|
18
|
-
@to_terminal ||= format_to_terminal
|
19
|
-
end
|
20
|
-
|
21
17
|
def best_guess
|
22
18
|
@best_guess ||= guesses.first
|
23
19
|
end
|
@@ -38,6 +34,14 @@ class WordleDecoder
|
|
38
34
|
lines.join("\n")
|
39
35
|
end
|
40
36
|
|
37
|
+
def to_terminal
|
38
|
+
str = +"\n"
|
39
|
+
best_guess.words_with_scores.reverse_each do |word, guess_score|
|
40
|
+
str << " #{word.to_terminal} #{word.confidence_score(guess_score)}\n"
|
41
|
+
end
|
42
|
+
str << " {{green:#{@wordle_share.answer}}}\n"
|
43
|
+
end
|
44
|
+
|
41
45
|
private
|
42
46
|
|
43
47
|
def initialize_and_sort_guesses
|
@@ -55,12 +59,4 @@ class WordleDecoder
|
|
55
59
|
WordPosition.new(line, index, @wordle_share.answer_chars)
|
56
60
|
end
|
57
61
|
end
|
58
|
-
|
59
|
-
def format_to_terminal
|
60
|
-
str = +"\n"
|
61
|
-
best_guess.words_with_scores.reverse_each do |word, guess_score|
|
62
|
-
str << " #{word.to_terminal} #{word.confidence_score(guess_score)}\n"
|
63
|
-
end
|
64
|
-
str << " {{green:#{@wordle_share.answer}}}\n\n"
|
65
|
-
end
|
66
62
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wordle_decoder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Ruzicka
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-03-
|
11
|
+
date: 2022-03-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: cli-ui
|
@@ -24,10 +24,11 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
|
-
description: Given your Wordle share text, with some degree of confidence,
|
27
|
+
description: Given your Wordle share text, with some degree of confidence,the decoder
|
28
28
|
will spit back the five-letter words it thinks you played.
|
29
29
|
email:
|
30
|
-
executables:
|
30
|
+
executables:
|
31
|
+
- wordle_decoder
|
31
32
|
extensions: []
|
32
33
|
extra_rdoc_files: []
|
33
34
|
files:
|
@@ -35,8 +36,10 @@ files:
|
|
35
36
|
- CHANGELOG.md
|
36
37
|
- Gemfile
|
37
38
|
- Gemfile.lock
|
39
|
+
- LICENSE.md
|
38
40
|
- README.md
|
39
41
|
- Rakefile
|
42
|
+
- bin/wordle_decoder
|
40
43
|
- lib/least_common_words.txt
|
41
44
|
- lib/less_common_words.txt
|
42
45
|
- lib/most_common_words.txt
|