Skip to content
125 changes: 125 additions & 0 deletions lib/adagrams.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
def draw_letters
letter_distribution = {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future consider defining something like letter_distribution outside of the method as a constant.

LETTER_DISTRIBUTION = { 
  # ...
}

def draw_letters

Using a constant isn't always going to be the right call but it's worth thinking about. For example, it's fine here because this data is just from a hash but if it was loaded from a file or something it might be worth only creating it once.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the format you used here, though. I think having the letter to go its number of occurrences is really readable.

"a" => 9,
"b" => 2,
"c" => 2,
"d" => 4,
"e" => 12,
"f" => 2,
"g" => 3,
"h" => 2,
"i" => 9,
"j" => 1,
"k" => 1,
"l" => 4,
"m" => 2,
"n" => 6,
"o" => 8,
"p" => 2,
"q" => 1,
"r" => 6,
"s" => 4,
"t" => 6,
"u" => 4,
"v" => 2,
"w" => 2,
"x" => 1,
"y" => 2,
"z" => 1,
}
letter_pool = []
letter_distribution.each do |str, n|
n.times do
letter_pool << str.downcase

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you compute something like this in a method you should think about whether or not it should be a constant. Here it's perfectly reasonable to write the method this way but it's worth keeping in mind.

If it's expensive to compute (like, if it needs to read from a file) then you may want to store it once instead of generating it multiple times.

end
end
hand = letter_pool.shuffle[0..9]
return hand
end

def uses_available_letters?(input, letters_in_hand)
if input.length > 10
puts "Too many letters! Try again: "
input = gets.chomp.downcase

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't be handing input from the user here. The wave-N-game should handle that for you.

The reason for this is that it's tricky to test code that asks for user input so it's nice to have that all in one place.

end
if (input.chars.all? { |char| letters_in_hand.include? char })

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice use of .all?!

valid_input = true
else
valid_input = false
end

input.chars.each do |letter|
hand_count = letters_in_hand.count(letter)
input_count = input.count(letter)
if hand_count >= input_count
valid_input = true
else
valid_input = false
break
end
end
return valid_input
end

def score_word(word)
score_chart = {
"a" => 1,
"b" => 3,
"c" => 3,
"d" => 2,
"e" => 1,
"f" => 4,
"g" => 2,
"h" => 4,
"i" => 1,
"j" => 8,
"k" => 5,
"l" => 1,
"m" => 3,
"n" => 1,
"o" => 1,
"p" => 3,
"q" => 10,
"r" => 1,
"s" => 1,
"t" => 1,
"u" => 1,
"v" => 4,
"w" => 4,
"x" => 8,
"y" => 4,
"z" => 10,
}
word = word.downcase
if word.length > 6
total_points = 8
else
total_points = 0
end

word.each_char do |letter|
total_points += (score_chart[letter])
end
return total_points

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like how concise this method is. 😃

end

def highest_score_from(words)
highest_score = 0
winning_word = {:word => "", :score => 0}
words.each do |word|
if score_word(word) > highest_score
highest_score = score_word(word)
winning_word[:word] = word.upcase
winning_word[:score] = highest_score
elsif score_word(word) == highest_score
if word.length == 10 && !(word.length == winning_word[:word].length)
winning_word[:word] = word.upcase
elsif word.length == 10 && (word.length == winning_word[:word])
winning_word[:word].downcase = winning_word[:word].downcase

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant:

Suggested change
winning_word[:word].downcase = winning_word[:word].downcase
winning_word[:word] = winning_word[:word].downcase

The code you have produces a NoMethodError.

elsif (word.length <= winning_word[:word].length) && (winning_word[:word].length != 10)
winning_word[:word] = word.upcase
end
end
end
return winning_word
end