Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Leaves - Mariya & Yasmin #20

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
109 changes: 109 additions & 0 deletions lib/adagrams.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# wave1 code
def draw_letters
pool_of_letters = {
"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
}

players_letters = []
alphabet = ("A".."Z").to_a

until players_letters.length == 10

Choose a reason for hiding this comment

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

This is clever. Consider this other method to draw_letters that uses the pool_of_letters hash to create an array of letters. You could then shuffle this array of letters and pop off a letter 10 times.

letters = []
pool_of_letters.each do |letter, count|
  count.times do
    letters << letter
  end
end

random_letter = alphabet.sample
if pool_of_letters[random_letter] && pool_of_letters[random_letter] > 0
players_letters << random_letter
pool_of_letters[random_letter] -= 1
end
end
return players_letters
end

# wave2 code
def uses_available_letters?(input, letters_in_hand)

Choose a reason for hiding this comment

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

Review this implementation of this method that does not require the creation of new hashes:

def uses_available_letters?(input, letters_in_hand)
  input_array = input.split('')
  letters_in_hand_copy = letters_in_hand.shuffle

  input_array.each do |letter_in_word|
    if letters_in_hand_copy.include?(letter_in_word)
      letters_in_hand_copy.delete(letter_in_word)
    else
      return false
    end
  end
  
  return true
end

user_word = input.upcase.chars
word_hash = {}
user_word.each do |letter|
if word_hash["#{letter}"].nil?

Choose a reason for hiding this comment

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

You do not need to use interpolation. letter is already a string.

word_hash["#{letter}"] = 1
else
word_hash["#{letter}"] += 1
end
end

full_pile = {}
letters_in_hand.each do |letter|
if full_pile["#{letter}"].nil?

Choose a reason for hiding this comment

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

letters_in_hand_hash would be a more meaningful name then full_pile and would follow the convention introduced in the previous loop.

full_pile["#{letter}"] = 1
else
full_pile["#{letter}"] += 1
end
end
return word_hash.all? do |letter, count|

Choose a reason for hiding this comment

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

This is a lot to put into a return statement. It would be good to do something like the code below. Notice the use of a comment to explain your logic. This would be useful for the two loops above as there is a lot of logic packed into this method.

# return true if every letter of the word is in the letters_in_hand_hash and they're used no more times than they appear in the letters_in_hand array

uses_available_letters_boolean = word_hash.all? do |letter, count|
  full_pile.has_key?(letter) && (full_pile[letter] >= word_hash[letter])
end
return uses_available_letters_boolean

full_pile.has_key?(letter) && (full_pile[letter] >= word_hash[letter])
end
end

#Wave_3
def score_word(word)
one_point_letter = %w[A E I O U L N R S T]

Choose a reason for hiding this comment

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

While this if/elif control structure works, it means that the information about which letter has which score is locked into this piece of code, and can't easily be used elsewhere. For example, if you wanted to display the value of each letter in a hand, you would need to repeat this work.

An alternative approach would be to store the letter scores in a hash, something like this:

LETTER_SCORES = {
  "A" => 1
  "B" => 3,
  "C" => 3,
  "D" => 2,
  # ...
}

Then to get the score for a letter, you can say LETTER_SCORES[letter].

two_point_letter = %w[D G]
three_point_letter = %w[B C M P]
four_point_letter = %w[F H V W Y]
five_point_letter = %w[K]
eight_point_letter = %w[J X]
ten_point_letter = %w[Q Z]

letters = word.upcase.chars
total = 0
letters.each do |score|
if one_point_letter.include?(score)
total += 1
elsif two_point_letter.include?(score)
total += 2
elsif three_point_letter.include?(score)
total += 3
elsif four_point_letter.include?(score)
total += 4
elsif five_point_letter.include?(score)
total += 5
elsif eight_point_letter.include?(score)
total += 8
elsif ten_point_letter.include?(score)
total += 10
end
end

extra_points = [7, 8, 9, 10]
if extra_points.include?(letters.length)
total += 8
end
return total
end

#wave_4
def tie_breaker(old_word, new_word)

Choose a reason for hiding this comment

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

This is a great use of a helper method and is elegant code/logic.

return old_word if old_word.length == 10
return new_word if new_word.length == 10
tie_breaker_length_array = [old_word, new_word]
winner = tie_breaker_length_array.min_by do |word|
word.length
end
return winner
end

def highest_score_from(words)

Choose a reason for hiding this comment

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

Again, the logic in this method is clear, elegant, and efficient.

winner = {
word: nil,
score: 0
}
words.each do |word|
total = score_word(word)
if total > winner[:score]
winner[:word] = word
winner[:score] = total
elsif winner[:score] == total
winner[:word] = tie_breaker(winner[:word], word)
winner[:score] = total
end
end
return winner
end