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

Edges Layla and Dionisia's Adagrams! #16

Open
wants to merge 27 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 127 additions & 0 deletions lib/adagrams.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
require 'csv'

# wave 1
def stores_letters
letters = [ "A", "A", "A", "A", "A", "A", "A", "A", "A", "B", "B", "C", "C", "D", "D", "D", "D", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "F", "F", "G", "G", "G", "H", "H", "I", "I", "I", "I", "I", "I", "I", "I", "I", "J", "K", "L", "L", "L", "L", "M", "M", "N", "N", "N", "N", "N", "N", "O", "O", "O", "O", "O", "O", "O", "O", "P", "P", "Q", "R", "R", "R", "R", "R", "R", "S", "S", "S", "S", "T", "T", "T", "T", "T", "T", "U", "U", "U", "U", "V", "V", "W", "W", "X", "Y", "Y", "Z" ]
end

Choose a reason for hiding this comment

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

This data structure makes sense for storing the pool of letters. However, laid out like this it's not easy to see the distribution of letters. Something like this might be a bit easier to read:

letters = [
  "A", "A", "A", "A", "A", "A", "A", "A", "A",
  "B", "B",
  "C", "C",
  ...
]

Or, if you were feeling fancy:

letter_distribution = {
  A: 9,
  B: 2,
  C: 2,
  ...
}
letters = []
letter_distribution.each do |letter, count|
  count.times do
    letters << letter
  end
end


def draw_letters
letter = stores_letters.shuffle.pop(10)
return letter
end

def welcome
puts "Welcome to adagrams. Here are your letters."
draw_letters
end


def game_instructions
puts "Based on these letters, give us a word."
print "Word: "
end

Choose a reason for hiding this comment

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

You shouldn't need to implement these methods - that's what the wave-X-game.rb files attached to this project are for.


# def get_user_input
# user_input = gets.chomp
# return user_input
# end

# wave 2
def uses_available_letters?(input, letters_in_hand)
input = input.upcase.split("")
input.each do |letter|
if letters_in_hand.include?(letter)

Choose a reason for hiding this comment

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

There are two problems with this implementation:

  1. You will never return true for a word with a repeated letter. For example,

    hand = ["E", "F", "R", "A", "E", "L", "V", "A", "D", "K"]
    uses_available_letters?("ADA", hand)
    # => false

    The reason why is that Ruby's Array#delete method will remove all matching elements from an array, not just the first match.

  2. This method is destructive! Because you call delete on the input, the hand will be reduced by the letters in the input. For example:

    hand = draw_letters
    puts hand
    # => ["T", "T", "E", "F", "R", "A", "E", "L", "V", "A"]
    uses_available_letters?('tte', hand)
    puts hand
    # => ["E", "F", "R", "A", "E", "L", "V", "A"]

    This is bad because it's unexpected behavior. Nothing about "check whether this word is made up of letters in this hand" suggests that the hand will be changed in the process, but that's exactly what happens.

    The way to address this problem would be to make a copy of the hand before removing letters from it.

I will acknowledge that none of the tests checked for either of these behaviors, but that doesn't change the fact that they're bugs.

letters_in_hand.delete(letter)
else
return false
end
end
return true
end


# wave 3
def score_word(word)
score = 0

score_hash = {
"A" => 1,
"E" => 1,
"I" => 1,

Choose a reason for hiding this comment

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

I like this data structure. Why not store this data in a constant?

"O" => 1,
"U" => 1,
"L" => 1,
"N" => 1,
"R" => 1,
"S" => 1,
"T" => 1,
"D" => 2,
"G" => 2,
"B" => 3,
"C" => 3,
"M" => 3,
"P" => 3,
"F" => 4,
"H" => 4,
"V" => 4,
"W" => 4,
"Y" => 4,
"K" => 5,
"J" => 8,
"X" => 8,
"Q" => 10,
"Z" => 10
}

word = word.upcase.split("")
word.each do |letter|
score += score_hash[letter]
end
bonus_length = [7, 8, 9, 10]
if bonus_length.include?(word.length)
score += 8
end
return score
end

# wave 4
def highest_score_from(words)

winning_word_and_score = {
word: "",
score: 0
}

words.each do |word|
score = score_word(word)

if score > winning_word_and_score[:score]
winning_word_and_score[:score] = score
winning_word_and_score[:word] = word
elsif score == winning_word_and_score[:score] #if it is a tie
# if current word has 10 letters and current winner does not,
# current word becomes new current winner.
if word.length == 10 && winning_word_and_score[:word].length != 10
winning_word_and_score[:word] = word

Choose a reason for hiding this comment

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

Good work getting this tricky tie-breaking logic sorted out.

# is current word has less letters than current winner,
# and current winner has less than 10 letters, current word
# becomes new current winner.
# backslash at the end of the line allows the line to continue onto the
# next line.
elsif (word.length < winning_word_and_score[:word].length) \
&& (winning_word_and_score[:word].length != 10)
winning_word_and_score[:word] = word
end
end
end

return winning_word_and_score
end

# wave 5
def is_in_english_dict?(input)
CSV.open("assets/dictionary-english.csv", "r").each do |word|
return true if word.include?(input.downcase)
end
return false
end
18 changes: 17 additions & 1 deletion specs/adagrams_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
# Get that nice colorized output
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new

# wave 1
describe 'Adagrams' do
describe 'draw_letters method' do
it 'draws ten letters from the letter pool' do
Expand All @@ -26,8 +27,8 @@
end
end

# wave 2
describe 'uses_available_letters? method' do

it 'returns true if the submitted letters are valid against the drawn letters' do
drawn_letters = ['D', 'O', 'G', 'X', 'X', 'X', 'X', 'X', 'X', 'X']
test_word = 'DOG'
Expand Down Expand Up @@ -57,6 +58,7 @@

end

# wave 3
describe 'score_word method' do
it 'returns an accurate numerical score according to the score chart' do
expect(score_word("A")).must_equal 1
Expand All @@ -80,7 +82,9 @@
expect(score_word("XXXXXXXXX")).must_equal 80
end
end
#

# wave 4
describe 'highest_score_from method' do
it 'returns a hash that contains the word and score of best word in an array' do
words = ['X', 'XX', 'XXX', 'XXXX']
Expand Down Expand Up @@ -167,5 +171,17 @@
expect(best_word[:word]).must_equal words.first
expect(best_word[:score]).must_equal 18
end

it 'if the user_input is in the dictionary' do
# Arrange
user_input = 'CAT'

# Act
result = is_in_english_dict?(user_input)

# Assert
expect(result).must_equal true
end
end

end