# \[SOLUTION\] Hangman (#130) -- Guesser Class

**URL:** <https://www.ruby-forum.com/t/solution-hangman-130-guesser-class/108958>\
**Category:** Ruby\
**Created:** [July 10, 2007, 12:25am UTC](https://www.ruby-forum.com/t/solution-hangman-130-guesser-class/108958 "2007-07-10T00:25:03Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![rubyrubyruby\_onrail](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7feea3/32.png) [@rubyrubyruby\_onrail](https://www.ruby-forum.com/u/rubyrubyruby_onrail)\
**Post date:** [July 10, 2007, 12:25am UTC](https://www.ruby-forum.com/t/solution-hangman-130-guesser-class/108958/1 "2007-07-10T00:25:03Z")

</div>

My “Guesser” class will guess the letter and the position based on the  
words that are “x” characters in length. It will suggest a particular  
letter in a particular position that has the highest frequency. It will  
filter out words based on characters known in a particular position and  
characters known not to be in a particular position.

It can find almost all words within 20 guesses and many is less than 10;  
I’ve found that words of 6 characters in length are typically the  
toughest to discover with the position and character guessing method.  
Once it filters down to one word it will return the word in a string.  
If it doesn’t have a word that matches, it will begin guessing based on  
random character guesses from the first unknown position.

Note: I did use Unix command “egrep” to quickly parse the word database.  
You can fix that in the “load\_database” method.

Example Usage based on the term “writhe”

# 

# 

# @known = string of characters; “-” is the wildcard

# @unknown = array of array of letters that letters

# that have been ruled out

# @file = Dictionary File - one word per line

# 

# 

require ‘guesser’

guess = Guesser.new(:known =\> “------”,  
:unknown =\> [[], [], [], [], [], []]  
:file =\> “words.txt”)

guess.list.length # Total Words search from with six characters

guess.guess # Returns a guess of [letter, position]  
[:s, 5] # position is based on an index of 0  
# I’ve found the best guess to be “s”  
# for the last character because it rules out  
# all plurals

guess.list.length # The method “guess” created a list of words from the

11153 # database.  
# All the words are 6 characters in length.  
# Not necessary, just showing you how it filters down  
# the words

guess.create\_regex # Returns the Regexp used to find the word  
/^.{5}$/ # Not necessary, just for example purposes

guess.unknown = [[], [], [], [], [], [“s”]] # Insert an “s” to signify  
# that it is not  
# in that position of the  
# word.

guess.guess # Filters the words and guesses again  
[:e, 4] #

guess.list.length # Filtered by the method “guess” to have fewer words.  
7045 # Notice 4108 words did not have the last letter “s”

guess.create\_regex # Returns the Regexp used to find the list  
/^.{4}[^s]$/ #

guess.unknown = [[], [], [], [], [“e”], [“s”]]

guess.guess  
[:e, 5]

guess.list.length # Guess filters out 2400 more words based on the  
# Regexp  
4568 # Note that the “list” is a filtering list and cannot  
# be recreated in full  
# once it has been filtered. That was a conscious  
# decision to preserve resources.

guess.create\_regex # Not necessary, just shows for example purposes.  
/^.{4}[^e][^s]$/

guess.known = “-----e”.split(//) # Must be submitted as an array.  
# Converts the string “-----e” into an

```
                              # array
                              # Probably need to fix this in the
                              # class

```

guess.guess  
[:l, 4]

Eventually (16 guesses down the road), once the word is filtered down it  
would look something list this:

guess.unknown = [[“s”, “t”], [“l”, “o”], [], [“i”, “a”, “u”, “o”, “e”,  
“n”, “r”], [“e”, “l”, “i”, “u”], [“s”]]

guess.known = “—the”.split(//)

guess.create\_regex  
/^[^st][^lo].{1}[t][h][e]$/

guess.guess  
“writhe”
