ruby-wordle 0.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 911b41c72a106def560cc14de90dce996c354e615054d67ea3d3c150a29dad21
4
+ data.tar.gz: 80a2fabaa942be49066e69af631ae473b2f5b774439fb2aa626e7e6748f3498f
5
+ SHA512:
6
+ metadata.gz: b363d91c62414d150ae0675ea0345253659d20e7f2202c0c2a2fa5ba516125ace8f3a3023c21878dbf29b0c0d8a990c9ed755d4ac4fc0b2ed3ab47a6998660a3
7
+ data.tar.gz: 77816914e691cae8ee15bd5a11d8ff1e2c06b873d88de5bbb5b7c3e2e9676a8cd87d7674c7cbdb0f996546e82c28baea718b904a70a6b6cfb506e4b1d407480e
data/.gitignore ADDED
@@ -0,0 +1,58 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ # Ignore Byebug command history file.
17
+ .byebug_history
18
+
19
+ ## Specific to RubyMotion:
20
+ .dat*
21
+ .repl_history
22
+ build/
23
+ *.bridgesupport
24
+ build-iPhoneOS/
25
+ build-iPhoneSimulator/
26
+
27
+ ## Specific to RubyMotion (use of CocoaPods):
28
+ #
29
+ # We recommend against adding the Pods directory to your .gitignore. However
30
+ # you should judge for yourself, the pros and cons are mentioned at:
31
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
32
+ #
33
+ # vendor/Pods/
34
+
35
+ ## Documentation cache and generated files:
36
+ /.yardoc/
37
+ /_yardoc/
38
+ /doc/
39
+ /rdoc/
40
+
41
+ ## Environment normalization:
42
+ /.bundle/
43
+ /vendor/bundle
44
+ /lib/bundler/man/
45
+
46
+ # for a library or gem, you might want to ignore these files since the code is
47
+ # intended to run in multiple environments; otherwise, check them in:
48
+ # Gemfile.lock
49
+ # .ruby-version
50
+ # .ruby-gemset
51
+
52
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
53
+ .rvmrc
54
+
55
+ # Used by RuboCop. Remote config files pulled in from inherit_from directive.
56
+ # .rubocop-https?--*
57
+
58
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'readline'
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2022 Yoichiro Hasebe
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # Ruby-Wordle
2
+
3
+ A set of ruby scripts to generate word-lists, solve Wordle, and play Wordle on the command line
4
+
5
+ ⬜️⬜️⬜️⬜️⬜️ \
6
+ ⬜️⬜️⬜️🟨🟨 \
7
+ ⬜️🟩⬜️🟩⬜️ \
8
+ 🟩🟩⬜️🟩🟩 \
9
+ 🟩🟩🟩🟩🟩
10
+
11
+ ----
12
+
13
+ ### Installation
14
+
15
+ ```
16
+ > gem install ruby-wordle
17
+ ```
18
+
19
+ ----
20
+
21
+ ### Play Wordle
22
+
23
+ **Usage Example**
24
+
25
+ ```plain-text
26
+ > ruby-worldle play
27
+ ```
28
+
29
+ <img src='https://github.com/yohasebe/ruby-wordle/blob/main/img/ruby-wordle-play.png?raw=true' width='500' />
30
+
31
+ You can ask for help by typing "?↵" while playing. In the suggestion list, basic words consisting of 5 different letters are printed in red 🟥 while basic words having the same letters used more than once are printed in blue 🟦
32
+
33
+ ----
34
+
35
+ ### Wordle Solver
36
+
37
+ **Usage Example**
38
+
39
+ ```plain-text
40
+ > ruby-worldle solver
41
+ ```
42
+
43
+ <img src='https://github.com/yohasebe/ruby-wordle/blob/main/img/ruby-wordle-solver.png?raw=true' width='500' />
44
+
45
+ In the result list, basic words consisting of 5 different letters are printed in red 🟥 while basic words having the same letters used more than once are printed in blue 🟦
46
+
47
+ ----
48
+
49
+ ### Word Lists
50
+
51
+ #### Word List Generator Script
52
+
53
+ 🟢 `lib/ruby-wordle/script-filter.rb`
54
+
55
+ A ruby script to generate *n*-letter word lists (`word-list.txt` and `word-list-uniq.txt`)
56
+
57
+ The default *n* value is 5. Change `NUM_LETTERS` if necessary, and run the script as follows. A directory will be created automatically with the title having the number specified in the script (e.g. `word-lists/5-letters`, `word-lists/6-letters`) and resulting word lists will be stored in that directory.
58
+
59
+ ----
60
+
61
+ #### Lists of English Words of 5 Letters (useful to solve Wordle)
62
+
63
+ 🟡 `word-lists/5-letters/word-list.txt`
64
+
65
+ A list of five-letter words, generated from the original word list.
66
+
67
+ 🟡 `word-lists/5-letters/word-list-uniq-letters.txt`
68
+
69
+ A list of five-letter words consisting of five different letters, generated from the original word list.
70
+
71
+ 🟡 `word-lists/5-letters/word-list-basic.txt`
72
+
73
+ A list of five-letter words, generated from the basic word list.
74
+
75
+ 🟡 `word-lists/5-letters/word-list-basic-uniq-letters.txt`
76
+
77
+ A list of five-letter words consisting of five different letters, generated from the basic word list.
78
+
79
+ ----
80
+
81
+ #### Original/Basic Lists of English Words
82
+
83
+ ⚪️ `word-lists/word-list-original.txt`
84
+
85
+ A large word list based on `words_alpha.txt` in [dwyl/english-words](https://github.com/dwyl/english-words), containing more than 370,000 items.
86
+
87
+ ⚪️ `word-lists/word-list-basic.txt`
88
+
89
+ A smaller word list containing about 13,000 basic English words.
90
+
91
+ ----
92
+
93
+ ### Author
94
+
95
+ Yoichiro HASEBE
96
+
97
+ ----
98
+
99
+ ### License
100
+
101
+ MIT
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/ruby-wordle ADDED
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH << File.join( File.dirname(__FILE__), '..', 'lib')
4
+ $LOAD_PATH << File.join( File.dirname(__FILE__), '..', 'lib', 'ruby-wordle')
5
+
6
+ require 'version'
7
+ require 'script-play'
8
+ require 'script-solver'
9
+
10
+ if ARGV[0] == "-v" || ARGV[0] == "--version"
11
+ puts "Ruby Wordle #{RubyWordle::VERSION}"
12
+ exit
13
+ elsif ARGV[0] == "play" || ARGV[0] == "play" || ARGV[0] == "p"
14
+ RubyWordlePlay::play_wordle
15
+ elsif ARGV[0] == "solver" || ARGV[0] == "solve" || ARGV[0] == "s"
16
+ RubyWordleSolver::run_interactively
17
+ else
18
+ puts "Ruby Wordle #{RubyWordle::VERSION}"; puts
19
+ puts "Usage: ruby-wordle (play|solve)"
20
+ puts; puts "See https://github.com/yohasebe/ruby-wordle"
21
+ exit
22
+ end
23
+
24
+
Binary file
Binary file
@@ -0,0 +1,48 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ NUM_LETTERS = 5
4
+
5
+ HOME_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
6
+
7
+ original_word_list = File.readlines("#{HOME_DIR}/word-lists/word-list-original.txt")
8
+ basic_word_list = File.readlines("#{HOME_DIR}/word-lists/word-list-basic.txt")
9
+ n_letter_dir = "#{HOME_DIR}/word-lists/#{NUM_LETTERS}-letters"
10
+
11
+ unless Dir.exist? n_letter_dir
12
+ Dir.mkdir File.expand_path(n_letter_dir)
13
+ end
14
+
15
+ n_letter_word_file = File.new(File.join(n_letter_dir, "word-list.txt"), "w")
16
+ uniq_n_letter_word_file = File.new(File.join(n_letter_dir, "word-list-uniq-letters.txt"), "w")
17
+ basic_n_letter_word_file = File.new(File.join(n_letter_dir, "word-list-basic.txt"), "w")
18
+ uniq_basic_n_letter_word_file = File.new(File.join(n_letter_dir, "word-list-basic-uniq-letters.txt"), "w")
19
+
20
+ original_word_list.sort!.uniq!
21
+ original_word_list.each do |line|
22
+ chars = line.strip.split(//)
23
+ if chars.size == NUM_LETTERS
24
+ line.downcase!
25
+ n_letter_word_file.write line
26
+ if chars.uniq.size == chars.size
27
+ uniq_n_letter_word_file.write line
28
+ end
29
+ end
30
+ end
31
+
32
+ basic_word_list.sort!.uniq!
33
+ basic_word_list.each do |line|
34
+ chars = line.strip.split(//)
35
+ if chars.size == NUM_LETTERS
36
+ line.downcase!
37
+ basic_n_letter_word_file.write line
38
+ if chars.uniq.size == chars.size
39
+ uniq_basic_n_letter_word_file.write line
40
+ end
41
+ end
42
+ end
43
+
44
+ n_letter_word_file.close
45
+ uniq_n_letter_word_file.close
46
+ basic_n_letter_word_file.close
47
+ uniq_basic_n_letter_word_file.close
48
+
@@ -0,0 +1,124 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require "readline"
4
+ require "script-solver"
5
+
6
+ module RubyWordlePlay
7
+ NUM_LETTERS = 5
8
+ NUM_ATTEMPTS = 6
9
+
10
+ LPAD = " " * 1
11
+ PROMPT = "〉".bold.red
12
+
13
+ @word_list_basic = File.readlines("#{HOME_DIR}/word-lists/#{NUM_LETTERS}-letters/word-list-basic.txt").map(&:strip)
14
+ @word_list_original = File.readlines("#{HOME_DIR}/word-lists/#{NUM_LETTERS}-letters/word-list.txt").map(&:strip)
15
+ @word = @word_list_basic.sample
16
+ @not_used = []
17
+ @not_used_here = {1 => [], 2 => [], 3 => [], 4 => [], 5 => []}
18
+ @letters_known = ".....".split(//)
19
+
20
+ def self.check_dict(attempt)
21
+ @word_list_original.include?(attempt)
22
+ end
23
+
24
+ def self.evaluate(attempt)
25
+ puts
26
+ @letters_known = attempt.split(//)
27
+ correct = []
28
+ wrong = []
29
+ @word.split(//).each_with_index do |l, i|
30
+ if attempt[i] == l
31
+ correct << i
32
+ else
33
+ wrong << i
34
+ @letters_known[i] = '.'
35
+ end
36
+ end
37
+ attempt.split(//).each_with_index do |l, i|
38
+ if correct.include?(i)
39
+ print " #{@word[i]} ".upcase.bg_green
40
+ else
41
+ elsewhere = wrong.map{|i|@word[i]}.index(l)
42
+ if elsewhere
43
+ print " #{l} ".upcase.bg_brown
44
+ @not_used_here[i + 1] << l unless @not_used_here[i + 1].include? l
45
+ else
46
+ print " ".bg_gray
47
+ @not_used << attempt[i] if /[a-z]/ =~ attempt[i]
48
+ @not_used.uniq!
49
+ @not_used.sort!
50
+ end
51
+ end
52
+ end
53
+ puts
54
+ correct.size == NUM_LETTERS
55
+ end
56
+
57
+ def self.get_help
58
+ letters_used = []
59
+ @not_used_here.each do |k, v|
60
+ v.each do |r|
61
+ letters_used << [k - 1, r]
62
+ end
63
+ end
64
+ RubyWordleSolver.solve_wordle(@letters_known.join, letters_used, @not_used, :basic, @word)
65
+ end
66
+
67
+ def self.ask_for_attempt(str)
68
+ puts
69
+ print " #{str} ".bold.bg_cyan + " "
70
+ attempt = Readline.readline(LPAD + PROMPT, true).strip.downcase
71
+ if attempt == "quit" || attempt == "q"
72
+ exit
73
+ elsif attempt == "help" || attempt == "h" || attempt == "?"
74
+ get_help
75
+ attempt = ask_for_attempt(str)
76
+ end
77
+
78
+ unless /\A[a-z]{5}\z/ =~ attempt
79
+ puts
80
+ puts LPAD + "Sorry,".red + " the input format is not right"
81
+ puts
82
+ attempt = ask_for_attempt(str)
83
+ end
84
+
85
+ unless check_dict(attempt)
86
+ puts
87
+ puts LPAD + "Sorry,".red + " it's not listed in the dictionary"
88
+ puts
89
+ attempt = ask_for_attempt(str)
90
+ end
91
+ attempt
92
+ end
93
+
94
+ def self.draw_decorated_border
95
+ puts
96
+ puts (' '.bg_green * 5 + ' '.bg_gray * 3 + ' '.bg_brown * 5 + ' '.bg_gray * 3) * 4
97
+ puts
98
+ end
99
+
100
+ def play_wordle
101
+ draw_decorated_border;
102
+ puts "Input a word of 5 letters and press \"↵\"".cyan.bold
103
+ puts "Type \"?↵\" for help, \"quit↵\" to exit".gray
104
+
105
+ NUM_ATTEMPTS.times do |i|
106
+ attempt = ask_for_attempt("#{i + 1}/#{NUM_ATTEMPTS}")
107
+ result = evaluate(attempt)
108
+ puts
109
+ if result
110
+ puts "C O R R E C T !".upcase.bg_magenta
111
+ exit
112
+ elsif i + 1 == NUM_ATTEMPTS
113
+ puts " ANSWER: #{@word} ".upcase.bg_red
114
+ exit
115
+ else
116
+ puts @not_used.uniq.map{|l| " #{l.upcase} "}.join.bg_black if !@not_used.empty?
117
+ puts
118
+ end
119
+ end
120
+ draw_decorated_border
121
+ end
122
+
123
+ module_function :play_wordle
124
+ end
@@ -0,0 +1,179 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ HOME_DIR = File.expand_path(File.join(File.dirname(__FILE__), "..", ".."))
4
+
5
+ require "readline"
6
+ require "script-utils"
7
+
8
+ module RubyWordleSolver
9
+ NUM_LETTERS = 5
10
+ MAX_SUGGESTIONS = 128
11
+
12
+ LPAD = " " * 7
13
+ PROMPT = "〉".bold.red
14
+
15
+ @word_list = File.readlines("#{HOME_DIR}/word-lists/#{NUM_LETTERS}-letters/word-list.txt").map(&:strip)
16
+ @word_list_basic = File.readlines("#{HOME_DIR}/word-lists/#{NUM_LETTERS}-letters/word-list-basic.txt").map(&:strip)
17
+
18
+ @basic_word_list = {}
19
+ File.readlines("#{HOME_DIR}/word-lists/#{NUM_LETTERS}-letters/word-list-basic.txt").map(&:strip).each do |b|
20
+ @basic_word_list[b] = true
21
+ end
22
+
23
+ @basic_word_uniq_list = {}
24
+ File.readlines("#{HOME_DIR}/word-lists/#{NUM_LETTERS}-letters/word-list-basic-uniq-letters.txt").map(&:strip).each do |b|
25
+ @basic_word_uniq_list[b] = true
26
+ end
27
+
28
+ @letters_known = nil
29
+ @letters_used = nil
30
+ @letters_not_used = nil
31
+
32
+ def self.get_letters_known
33
+ puts
34
+ puts "STEP 1".bold.bg_green + " Input " + "known letters".underline + " using alphabets and dots"
35
+ puts LPAD + "Then press \"↵\" (Type \"quit↵\" to exit)"
36
+ if @letters_known
37
+ puts LPAD + "Last time: #{@letters_known.bg_green}"
38
+ else
39
+ puts LPAD + "Example: #{'s...h'.bg_green}"
40
+ end
41
+
42
+ letters_known = Readline.readline(LPAD + PROMPT, true).strip.downcase
43
+
44
+ exit if letters_known == "quit" || letters_known == "q"
45
+ unless /\A[a-z\.]{5}\z/ =~ letters_known
46
+ puts LPAD + "Sorry,".red + " the input format is not right"
47
+ letters_known = get_letters_known
48
+ end
49
+ letters_known
50
+ end
51
+
52
+ def self.get_letters_used
53
+ puts
54
+ puts "STEP 2".bold.bg_brown + " Input pairs of " + "a position and a letter".underline
55
+ puts LPAD + "Then press \"↵\" (Type \"quit↵\" to exit)"
56
+ if @letters_used
57
+ puts LPAD + "Last time: #{@letters_used.map{|p, l| (p + 1).to_s + l}.join(' ').bg_brown}"
58
+ else
59
+ puts LPAD + "Example: #{'1g 2e 5a'.bg_brown}"
60
+ end
61
+
62
+ letters_used = Readline.readline(LPAD + PROMPT, true).strip.downcase
63
+
64
+ exit if letters_used == "quit" || letters_used == "q"
65
+ if letters_used.strip == ""
66
+ array_letters_used = []
67
+ elsif /\A(?:[1-5][a-z][\s,]*)+\z/ =~ letters_used
68
+ array_letters_used = []
69
+ letters_used.gsub(/\s+/, "").split(//).each_slice(2) do |k, v|
70
+ array_letters_used << [k.to_i - 1, v]
71
+ end
72
+ else
73
+ puts LPAD + "Sorry,".red + " the input format is not right"
74
+ array_letters_used = get_letters_used
75
+ end
76
+ array_letters_used
77
+ end
78
+
79
+ def self.get_letters_not_used
80
+ puts
81
+ puts "STEP 3".bold.bg_gray + " Input " + "letters not used".underline + " in the word"
82
+ puts LPAD + "Then press \"↵\" (Type \"quit↵\" to exit)"
83
+ if @letters_not_used
84
+ puts LPAD + "Last time: #{@letters_not_used.join.bg_gray}"
85
+ else
86
+ puts LPAD + "Example: #{'ieagh'.bg_gray}"
87
+ end
88
+
89
+ letters_not_used = Readline.readline(LPAD + PROMPT, true).strip.downcase
90
+
91
+ exit if letters_not_used == "quit" || letters_not_used == "q"
92
+ if letters_not_used.strip == ""
93
+ array_letters_not_used = []
94
+ elsif /\A[a-z\s]+\z/ =~ letters_not_used
95
+ array_letters_not_used = letters_not_used.split(//)
96
+ else
97
+ puts LPAD + "Sorry,".red + " the input format is not right"
98
+ array_letters_not_used = get_letters_not_used
99
+ end
100
+ array_letters_not_used
101
+ end
102
+
103
+ def self.draw_decorated_border
104
+ puts; puts (' '.bg_green * 5 + ' '.bg_gray * 3 + ' '.bg_brown * 5 + ' '.bg_gray * 3) * 4; puts
105
+ end
106
+
107
+ def solve_wordle(letters_known, letters_used, letters_not_used, mode = :original, answer = nil)
108
+ word_list = mode == :original ? @word_list : @word_list_basic
109
+ indices_unknown_letters = (0 ... letters_known.length).find_all { |i| letters_known[i, 1] == '.' }
110
+
111
+ word_list_a = word_list.select do |word|
112
+ Regexp.compile(letters_known) =~ word
113
+ end
114
+
115
+ word_list_b = word_list_a.select do |word|
116
+ word_letters = word.split(//)
117
+ letters_in_candidate = word_letters.values_at(*indices_unknown_letters) - letters_used.map{|l| l[1]}
118
+ cond1 = letters_used.all? do |position, letter|
119
+ word_letters[position] != letter
120
+ end
121
+ cond2 = (letters_used.map{|l| l[1]} - word_letters).empty?
122
+ cond3 = (letters_in_candidate - letters_not_used).size == letters_in_candidate.size
123
+ cond1 && cond2 && cond3
124
+ end
125
+
126
+ if answer
127
+ word_list_b.delete(answer)
128
+ reduced_list = word_list_b.sample(MAX_SUGGESTIONS - 1)
129
+ reduced_list << answer
130
+ else
131
+ reduced_list = word_list_b.sample(MAX_SUGGESTIONS)
132
+ end
133
+
134
+ results = reduced_list.sort.map do |word|
135
+ if @basic_word_uniq_list[word]
136
+ mode == :original ? word.red.bold : word.red
137
+ elsif @basic_word_list[word]
138
+ mode == :original ? word.blue.bold : word.blue
139
+ else
140
+ word
141
+ end
142
+ end
143
+ puts
144
+ results.each_with_index do |word, i|
145
+ if (i + 1) % 8 == 0 || results.size == i + 1
146
+ print word + "\n"
147
+ else
148
+ print word + " "
149
+ end
150
+ end
151
+ word_list_b
152
+ end
153
+
154
+ def run_interactively
155
+ draw_decorated_border
156
+ @letters_known = get_letters_known
157
+ @letters_used = get_letters_used
158
+ @letters_not_used = get_letters_not_used
159
+ results = solve_wordle(@letters_known, @letters_used, @letters_not_used)
160
+ draw_decorated_border
161
+
162
+ exit if results.size < 2
163
+
164
+ puts " ? ".bold.bg_magenta + " Press \"↵\" to continue."
165
+ puts LPAD + "Type \"quit↵\" to exit."
166
+
167
+ response = Readline.readline(LPAD + PROMPT, true).strip.downcase
168
+
169
+ if response == "quit" || response == "q"
170
+ exit
171
+ else
172
+ run_interactively
173
+ end
174
+ end
175
+
176
+ module_function :run_interactively
177
+ module_function :solve_wordle
178
+ end
179
+
@@ -0,0 +1,23 @@
1
+ class String
2
+ def black; "\e[30m#{self}\e[0m" end
3
+ def red; "\e[31m#{self}\e[0m" end
4
+ def green; "\e[32m#{self}\e[0m" end
5
+ def brown; "\e[33m#{self}\e[0m" end
6
+ def blue; "\e[34m#{self}\e[0m" end
7
+ def magenta; "\e[35m#{self}\e[0m" end
8
+ def cyan; "\e[36m#{self}\e[0m" end
9
+ def gray; "\e[37m#{self}\e[0m" end
10
+ def bg_black; "\e[40m#{self}\e[0m" end
11
+ def bg_red; "\e[41m#{self}\e[0m" end
12
+ def bg_green; "\e[42m#{self}\e[0m" end
13
+ def bg_brown; "\e[43m#{self}\e[0m" end
14
+ def bg_blue; "\e[44m#{self}\e[0m" end
15
+ def bg_magenta; "\e[45m#{self}\e[0m" end
16
+ def bg_cyan; "\e[46m#{self}\e[0m" end
17
+ def bg_gray; "\e[47m#{self}\e[0m" end
18
+ def bold; "\e[1m#{self}\e[22m" end
19
+ def italic; "\e[3m#{self}\e[23m" end
20
+ def underline; "\e[4m#{self}\e[24m" end
21
+ def blink; "\e[5m#{self}\e[25m" end
22
+ def reverse_color; "\e[7m#{self}\e[27m" end
23
+ end
@@ -0,0 +1,3 @@
1
+ module RubyWordle
2
+ VERSION = "0.9.2"
3
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require "ruby-wordle/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "ruby-wordle"
8
+ s.version = RubyWordle::VERSION
9
+ s.authors = ["Yoichiro Hasebe"]
10
+ s.email = ["yohasebe@gmail.com"]
11
+ s.homepage = "http://github.com/yohasebe/ruby-wordle"
12
+ s.summary = %q{A set of ruby scripts to generate word-lists, solve Wordle, and play Wordle}
13
+ s.description = %q{A set of ruby scripts to generate word-lists, solve Wordle, and play Wordle}
14
+ s.licenses = ["MIT"]
15
+ s.files = `git ls-files`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ # specify any dependencies here; for example:
20
+ s.add_runtime_dependency 'readline'
21
+ end