wordle 0.3.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff0c43c46f9e5e2e25088128a3cd8e2f634bda564b98a0b36473c0d9fb1a25b7
4
- data.tar.gz: bbcaf825639fd41c6388b501388cc108048d1c4464e59a3cad7eaa2451586679
3
+ metadata.gz: 4aa10bd48df4f525022634f4a41a1c4009f25e6da6bd9992470c2c963f08a91c
4
+ data.tar.gz: 99047acbf6078ca14d65aaaf71d0727fbb489557d58c72ed02c41d67bbb9b22e
5
5
  SHA512:
6
- metadata.gz: 366f914646b492bd8c00f4a4334db6ebb494b447cd54c34ea0d6c47310be1ab7ed3af5662c05daf5bcf8056dbb0899db2848599525ed17859eb40e6b111d500b
7
- data.tar.gz: 1a21fa7349041d534f29588cb45b9ca41e4e0deef0d6812de0e1384a80613a94667b925b3c32cacf9d6d99bc587807b0419f416a9b6ebe16cb43142d1de13cce
6
+ metadata.gz: a807bcfa10a95e25cb272da8d28a8bd65172e3d623ba76f8e0bc98fd8e4f8618e205a18b6ead77c79e3c21171b6801e64c729029cdbbd9615d713cef53767a87
7
+ data.tar.gz: 3e44a8f3ed4eb337de645d60d50399393206d56df15e29262d6a327ae52c3b2edf6dd8e9daee3eeaffb05d66470916cddf518113d2c4d0fb1a0eca720e976db0
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.1.0
data/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ ## [0.6.0] - 2022-04-14
2
+
3
+ - Adds hard mode.
4
+
5
+ ## [0.5.0] - 2022-02-02
6
+
7
+ - Prints outs squares for sharing at the end of a game.
8
+ - Sharing prints out unique hash for word that was played, which can be passed
9
+ to -i option so you can play the same word as a friend.
10
+
11
+ ## [0.4.0] - 2022-01-14
12
+
13
+ - Fixes bug where too many letters would get marked as yellow. Resolves
14
+ [https://github.com/JonathanWThom/wordle/issues/3](https://github.com/JonathanWThom/wordle/issues/3).
15
+
1
16
  ## [0.3.0] - 2022-01-10
2
17
 
3
18
  - Adds a better world list. From the Wordle source itself : )
data/Gemfile.lock CHANGED
@@ -1,19 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- wordle (0.3.0)
4
+ wordle (0.6.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.2)
10
+ debug (1.4.0)
11
+ irb (>= 1.3.6)
12
+ reline (>= 0.2.7)
10
13
  diff-lcs (1.5.0)
14
+ io-console (0.5.11)
15
+ irb (1.4.1)
16
+ reline (>= 0.3.0)
11
17
  parallel (1.21.0)
12
18
  parser (3.1.0.0)
13
19
  ast (~> 2.4.1)
14
20
  rainbow (3.0.0)
15
21
  rake (13.0.6)
16
22
  regexp_parser (2.2.0)
23
+ reline (0.3.1)
24
+ io-console (~> 0.5)
17
25
  rexml (3.2.5)
18
26
  rspec (3.10.0)
19
27
  rspec-core (~> 3.10.0)
@@ -53,6 +61,7 @@ PLATFORMS
53
61
  x86_64-linux
54
62
 
55
63
  DEPENDENCIES
64
+ debug (>= 1.0.0)
56
65
  rake (~> 13.0)
57
66
  rspec (~> 3.0)
58
67
  standard (~> 1.3)
data/README.md CHANGED
@@ -2,8 +2,9 @@
2
2
 
3
3
  Ruby implementation of [Wordle](https://www.powerlanguage.co.uk/wordle/).
4
4
 
5
- <img width="794" alt="Screen Shot 2022-01-10 at 9 18 19 PM" src="https://user-images.githubusercontent.com/22665228/148885575-39805830-274e-40e6-be14-4c6bc6db37ec.png">
5
+ <img width="869" alt="Screen Shot 2022-02-02 at 10 32 02 PM" src="https://user-images.githubusercontent.com/22665228/152292863-33743039-d9f4-4afa-a321-684d7b67cdb3.png">
6
6
 
7
+ [![Build](https://github.com/JonathanWThom/wordle/actions/workflows/build.yml/badge.svg)](https://github.com/JonathanWThom/wordle/actions/workflows/build.yml)
7
8
 
8
9
  ## Installation
9
10
 
@@ -13,6 +14,14 @@ Ruby implementation of [Wordle](https://www.powerlanguage.co.uk/wordle/).
13
14
 
14
15
  Just run `wordle` from the command line.
15
16
 
17
+ This version will pull a new word at random every time you run it from a very weird and long list. It's much more difficult than the original due to some of the words being a bit uncommon.
18
+
19
+ ```
20
+ Usage: wordle [options]
21
+ -i, --identifier=IDENTIFIER Pass word identifer to target a specific word that someone else has played. Identifier gets printed at the end of the game to share with a friend.
22
+ -d, --difficult Hard mode. Any revealed hints must be used in subsequent guesses.
23
+ ```
24
+
16
25
  ## Development
17
26
 
18
27
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -23,6 +32,10 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
23
32
 
24
33
  Bug reports and pull requests are welcome on GitHub at https://github.com/JonathanWThom/wordle. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/JonathanWThom/wordle/blob/main/CODE_OF_CONDUCT.md).
25
34
 
35
+ ## Acknowledgements
36
+
37
+ I cribbed my word list from the Wordle site itself. I have no association with the site, its creator, or the New York Times - I'm just a fan!
38
+
26
39
  ## License
27
40
 
28
41
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/lib/integer.rb ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Integer
4
+ def ordinalize
5
+ {
6
+ 1 => "1st",
7
+ 2 => "2nd",
8
+ 3 => "3rd",
9
+ 4 => "4th",
10
+ 5 => "5th"
11
+ }[self]
12
+ end
13
+ end
data/lib/wordle/game.rb CHANGED
@@ -2,29 +2,35 @@
2
2
 
3
3
  module Wordle
4
4
  class Game
5
- def self.play
6
- new.play
5
+ def self.play(*args)
6
+ new(*args).play
7
7
  end
8
8
 
9
- def initialize
9
+ def initialize(options_reader = Options.new)
10
10
  @list = List.new
11
+ @options = options_reader.read
11
12
  @target_word = generate_word
12
13
  end
13
14
 
14
- # print letters that have already been used?
15
- # compare to real words
16
-
17
15
  def play
18
16
  winner = false
19
- attempts = 0
20
17
 
21
18
  Legend.print
22
19
  puts "Guess a 5 letter word: "
20
+ guesses = []
21
+ must_include = []
22
+ must_match = Array.new(5)
23
23
 
24
- while attempts < 6 && !winner
24
+ while guesses.length < 6 && !winner
25
25
  guess = gets.chomp
26
26
 
27
- validator = GuessValidator.new(guess, @list)
27
+ validator = GuessValidator.new(
28
+ guess,
29
+ @list,
30
+ @options[:difficult],
31
+ must_include,
32
+ must_match
33
+ )
28
34
  if validator.invalid?
29
35
  puts validator.error
30
36
  next
@@ -32,27 +38,37 @@ module Wordle
32
38
 
33
39
  analyzer = GuessAnalyzer.new(@target_word, guess)
34
40
  puts analyzer.colors
41
+ guesses << analyzer.squares
42
+ if @options[:difficult]
43
+ must_include = analyzer.must_include(must_include)
44
+ must_match = analyzer.must_match(must_match)
45
+ end
35
46
 
36
47
  if analyzer.match?
37
48
  winner = true
38
49
  break
39
50
  end
40
-
41
- attempts += 1
42
51
  end
43
52
 
53
+ hash = Digest::SHA2.hexdigest(@target_word)[..5]
44
54
  if winner
45
- puts "Winner!"
55
+ puts "\nWordle Gem #{hash} #{guesses.length}/6\n\n"
46
56
  else
47
- puts "Word was: #{@target_word}"
48
- puts "Better luck next time!"
57
+ puts "\nWord was: #{@target_word}\n"
58
+ puts "\nWordle Gem #{hash} X/6*\n\n"
49
59
  end
60
+
61
+ puts guesses
50
62
  end
51
63
 
52
64
  private
53
65
 
54
66
  def generate_word
55
- @list.random
67
+ if @options[:identifier]
68
+ @list.by_hash(@options[:identifier])
69
+ else
70
+ @list.random
71
+ end
56
72
  end
57
73
  end
58
74
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../string"
4
-
5
3
  module Wordle
6
4
  class GuessAnalyzer
7
5
  def initialize(target_word, guess)
@@ -14,21 +12,73 @@ module Wordle
14
12
  end
15
13
 
16
14
  def colors
17
- target_letters = @target_word.chars
18
- guess_letters = @guess.chars
19
- colored_letters = ""
20
-
21
- guess_letters.each_with_index do |letter, i|
22
- colored_letters += if letter == target_letters[i]
23
- letter.green
24
- elsif target_letters.include?(letter)
25
- letter.yellow
26
- else
27
- letter.gray
15
+ raw_colors.each_with_index.map do |color, i|
16
+ guess_letters[i].send(color)
17
+ end.join("")
18
+ end
19
+
20
+ def squares
21
+ color_map = {
22
+ green: "🟩",
23
+ yellow: "🟨",
24
+ gray: "⬛️"
25
+ }
26
+
27
+ raw_colors.each_with_index.map do |color, i|
28
+ color_map[color]
29
+ end.join("")
30
+ end
31
+
32
+ def must_include(prev_must_include)
33
+ raw_colors.each_with_index do |color, i|
34
+ if color == :yellow && !prev_must_include.include?(guess_letters[i])
35
+ prev_must_include << guess_letters[i]
36
+ end
37
+ end
38
+
39
+ prev_must_include
40
+ end
41
+
42
+ def must_match(prev_must_match)
43
+ raw_colors.each_with_index do |color, i|
44
+ if color == :green
45
+ prev_must_match[i] = guess_letters[i]
28
46
  end
29
47
  end
30
48
 
31
- colored_letters
49
+ prev_must_match
50
+ end
51
+
52
+ private
53
+
54
+ def guess_letters
55
+ @_guess_letters ||= @guess.chars
56
+ end
57
+
58
+ def raw_colors
59
+ @_raw_colors ||= begin
60
+ target_letters = @target_word.chars
61
+ colors = []
62
+
63
+ guess_letters.each_with_index do |letter, i|
64
+ if letter == target_letters[i]
65
+ colors[i] = :green
66
+ target_letters[i] = nil
67
+ end
68
+ end
69
+
70
+ guess_letters.each_with_index do |letter, i|
71
+ if colors[i].nil?
72
+ colors[i] = if target_letters.include?(letter)
73
+ :yellow
74
+ else
75
+ :gray
76
+ end
77
+ end
78
+ end
79
+
80
+ colors
81
+ end
32
82
  end
33
83
  end
34
84
  end
@@ -2,23 +2,62 @@
2
2
 
3
3
  module Wordle
4
4
  class GuessValidator
5
- attr_reader :error
6
-
7
- def initialize(guess, list)
5
+ def initialize(
6
+ guess,
7
+ list,
8
+ difficult,
9
+ must_include,
10
+ must_match
11
+ )
8
12
  @guess = guess
9
13
  @list = list
14
+ @difficult = difficult
15
+ @must_include = must_include
16
+ @must_match = must_match
17
+ @validated = false
10
18
  end
11
19
 
12
20
  def invalid?
21
+ !error.nil?
22
+ end
23
+
24
+ def error
25
+ validate if !@validated
26
+
27
+ @error
28
+ end
29
+
30
+ private
31
+
32
+ def validate
33
+ validate_normal_mode
34
+ validate_hard_mode if @difficult
35
+ @validated = true
36
+ end
37
+
38
+ def validate_normal_mode
13
39
  if @guess.length != 5
14
40
  @error = "Guess must be 5 letters long"
15
- return true
16
41
  elsif @list.invalid?(@guess)
17
- @error = "Guess must be a real word"
18
- return true
42
+ @error = "Guess not in word list"
43
+ end
44
+ end
45
+
46
+ def validate_hard_mode
47
+ @must_include.each do |letter|
48
+ if !@guess.include?(letter)
49
+ @error = "Guess must include #{letter}"
50
+ break
51
+ end
19
52
  end
20
53
 
21
- false
54
+ @guess.each_char.with_index do |letter, i|
55
+ match = @must_match[i]
56
+ if match && match != letter
57
+ @error = "#{(i + 1).ordinalize} letter must be #{match}"
58
+ break
59
+ end
60
+ end
22
61
  end
23
62
  end
24
63
  end
data/lib/wordle/legend.rb CHANGED
@@ -10,6 +10,8 @@ module Wordle
10
10
  puts green_example
11
11
  puts yellow_example
12
12
  puts gray_example
13
+ puts "\nRestart and add -i flag to target a specific word by hash, for example:"
14
+ puts "$ wordle -i ed541a\n\n"
13
15
  end
14
16
 
15
17
  private
data/lib/wordle/list.rb CHANGED
@@ -2,14 +2,20 @@
2
2
 
3
3
  module Wordle
4
4
  class List
5
- def initialize(length = 5)
6
- @length = length
7
- end
8
-
9
5
  def random
10
6
  list.sample.downcase.strip
11
7
  end
12
8
 
9
+ def by_hash(hash)
10
+ word = list.detect do |word|
11
+ Digest::SHA2.hexdigest(word.downcase.strip)[..5] == hash
12
+ end
13
+
14
+ raise Wordle::Error, "Invalid word identifier, are you sure you copied it correctly?" if word.nil?
15
+
16
+ word
17
+ end
18
+
13
19
  def invalid?(word)
14
20
  !list.include?(word)
15
21
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Wordle
4
+ class Options
5
+ def read
6
+ options = {}
7
+
8
+ parser = OptionParser.new do |opts|
9
+ opts.banner = "Usage: wordle [options]"
10
+
11
+ opts.on("-iIDENTIFIER", "--identifier=IDENTIFIER", "Pass word identifer to target a specific word that someone else has played. Identifier gets printed at the end of the game to share with a friend.") do |i|
12
+ options[:identifier] = i
13
+ end
14
+
15
+ opts.on("-d", "--difficult", "Hard mode. Any revealed hints must be used in subsequent guesses.") do |d|
16
+ options[:difficult] = d
17
+ end
18
+ end
19
+
20
+ begin
21
+ parser.parse!
22
+ rescue OptionParser::InvalidOption
23
+ puts "Option not recognized"
24
+ end
25
+
26
+ options
27
+ end
28
+ end
29
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wordle
4
- VERSION = "0.3.0"
4
+ VERSION = "0.6.0"
5
5
  end
data/lib/wordle.rb CHANGED
@@ -1,7 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "digest"
4
+ require "optparse"
5
+ require_relative "integer"
3
6
  require_relative "string"
4
7
  require_relative "wordle/version"
8
+ require_relative "wordle/options"
5
9
  require_relative "wordle/source"
6
10
  require_relative "wordle/list"
7
11
  require_relative "wordle/guess_validator"
data/wordle.gemspec CHANGED
@@ -35,4 +35,5 @@ Gem::Specification.new do |spec|
35
35
 
36
36
  # For more information and examples about making a new gem, check out our
37
37
  # guide at: https://bundler.io/guides/creating_gem.html
38
+ spec.add_development_dependency "debug", ">= 1.0.0"
38
39
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wordle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan Thom
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-01-11 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2022-04-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: debug
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.0.0
13
27
  description:
14
28
  email:
15
29
  - jonathanthom@hey.com
@@ -20,6 +34,7 @@ extra_rdoc_files: []
20
34
  files:
21
35
  - ".rspec"
22
36
  - ".standard.yml"
37
+ - ".tool-versions"
23
38
  - CHANGELOG.md
24
39
  - CODE_OF_CONDUCT.md
25
40
  - Gemfile
@@ -30,6 +45,7 @@ files:
30
45
  - bin/console
31
46
  - bin/setup
32
47
  - exe/wordle
48
+ - lib/integer.rb
33
49
  - lib/string.rb
34
50
  - lib/wordle.rb
35
51
  - lib/wordle/game.rb
@@ -37,9 +53,9 @@ files:
37
53
  - lib/wordle/guess_validator.rb
38
54
  - lib/wordle/legend.rb
39
55
  - lib/wordle/list.rb
56
+ - lib/wordle/options.rb
40
57
  - lib/wordle/source.rb
41
58
  - lib/wordle/version.rb
42
- - sig/wordle.rbs
43
59
  - wordle.gemspec
44
60
  homepage: https://github.com/jonathanwthom/wordle
45
61
  licenses:
@@ -64,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
64
80
  - !ruby/object:Gem::Version
65
81
  version: '0'
66
82
  requirements: []
67
- rubygems_version: 3.2.32
83
+ rubygems_version: 3.3.3
68
84
  signing_key:
69
85
  specification_version: 4
70
86
  summary: Wordle CLI in Ruby
data/sig/wordle.rbs DELETED
@@ -1,4 +0,0 @@
1
- module Wordle
2
- VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
- end