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

Branches - Michaela & Angele #17

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
139 changes: 139 additions & 0 deletions lib/adagrams.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
require 'csv'

def return_letter_pool_hash

letter_pool_hash = {

Choose a reason for hiding this comment

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

This is great just as it is! I just wanted to mention for the future that this is usually a great example of when a global variable (ie. LETTER_POOL_HASH = ...). That way you wouldn't need to write a method and then gets called several times and a new copy of the hash wouldn't get created each time.

"A" => {number_of_tiles: 9, number_of_points: 1},
"B" => {number_of_tiles: 2, number_of_points: 3},
"C" => {number_of_tiles: 2, number_of_points: 3},
"D" => {number_of_tiles: 4, number_of_points: 2},
"E" => {number_of_tiles: 12, number_of_points: 1},
"F" => {number_of_tiles: 2, number_of_points: 4},
"G" => {number_of_tiles: 3, number_of_points: 2},
"H" => {number_of_tiles: 2, number_of_points: 4},
"I" => {number_of_tiles: 9, number_of_points: 1},
"J" => {number_of_tiles: 1, number_of_points: 8},
"K" => {number_of_tiles: 1, number_of_points: 5},
"L" => {number_of_tiles: 4, number_of_points: 1},
"M" => {number_of_tiles: 2, number_of_points: 3},
"N" => {number_of_tiles: 6, number_of_points: 1},
"O" => {number_of_tiles: 8, number_of_points: 1},
"P" => {number_of_tiles: 2, number_of_points: 3},
"Q" => {number_of_tiles: 1, number_of_points: 10},
"R" => {number_of_tiles: 6, number_of_points: 1},
"S" => {number_of_tiles: 4, number_of_points: 1},
"T" => {number_of_tiles: 6, number_of_points: 1},
"U" => {number_of_tiles: 4, number_of_points: 1},
"V" => {number_of_tiles: 2, number_of_points: 4},
"W" => {number_of_tiles: 2, number_of_points: 4},
"X" => {number_of_tiles: 1, number_of_points: 8},
"Y" => {number_of_tiles: 2, number_of_points: 4},
"Z" => {number_of_tiles: 1, number_of_points: 10}
}

return letter_pool_hash

end

def draw_letters

letter_pool_hash = return_letter_pool_hash

letter_pool_array = letter_pool_hash.map do |letter, letter_info|
(letter * letter_info[:number_of_tiles]).split("")
end

letter_pool_array = letter_pool_array.flatten

drawn_letters = letter_pool_array.sample(10)
return drawn_letters

end

def uses_available_letters? (input, letters_in_hand)

copy_of_hand = letters_in_hand.clone
letters_of_input = input.upcase.split("")

letters_of_input.each do |letter_from_input|
if copy_of_hand.include? letter_from_input

index_of_input_letter = copy_of_hand.index(letter_from_input)
copy_of_hand.delete_at(index_of_input_letter)

else

copy_of_hand = letters_in_hand.clone

Choose a reason for hiding this comment

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

This method looks great! I just wanted to name that this line isn't necessary as the copy_of_hand variable as soon as the method returns on the next line. If that short explanation isn't clear, feel free to ask a fellow student or one of us instructors to get clarity on that.

return false

end
end

return true

end

def score_word(word)

letter_pool_hash = return_letter_pool_hash

word_array = word.upcase.split("")

word_points = word_array.map do |letter|
letter_pool_hash[letter][:number_of_points]
end

if word_array.length >= 7
word_points << 8
end

return word_points.sum

end

def highest_score_from(words)
scores_hash = {}

words.each do |word|
scores_hash[word] = score_word(word)
end

highest_score = scores_hash.values.max
highest_scores_hash = scores_hash.select do |word, score|
score == highest_score
end

if highest_scores_hash.length == 1
return {word: highest_scores_hash.keys[0], score: highest_scores_hash.values[0]}
else

highest_scores_hash.each do |word, score|
if word.length == 10
return {word: word, score: score}
end
end

min_length = highest_scores_hash.map { |word, score| word.length }.min

Choose a reason for hiding this comment

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

This is a super clever and interesting way to do this!

highest_scores_hash.each do |word, score|
if word.length == min_length
return {word: word, score: score}
end
end

end
end

def is_in_english_dict?(input)

dict_array = []
CSV.foreach("assets/dictionary-english.csv") do |row|
dict_array << row
end

dict_array = dict_array.flatten

answer = dict_array.include?(input.downcase) ? true : false

return answer

end
124 changes: 81 additions & 43 deletions test/adagrams_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,169 +13,207 @@
drawn_letters = draw_letters
expect(drawn_letters.size).must_equal 10
end

it 'returns an array, and each item is a single-letter string' do
drawn_letters = draw_letters
expect(drawn_letters.size).must_equal 10

expect(drawn_letters).must_be_instance_of Array
drawn_letters.each do |letter|
expect(letter).must_be_instance_of String
expect(letter.length).must_equal 1
end
end
end

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'

is_valid = uses_available_letters? test_word, drawn_letters

expect(is_valid).must_equal true
end

it 'returns false word contains letters not in the drawn letters' do
drawn_letters = ['D', 'O', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X']
test_word = 'DOG'

is_valid = uses_available_letters? test_word, drawn_letters

expect(is_valid).must_equal false
end

it 'returns false word contains repeated letters more than in the drawn letters' do
drawn_letters = ['A', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X']
test_word = 'AAA'

is_valid = uses_available_letters? test_word, drawn_letters

expect(is_valid).must_equal false
end

it 'does not change the letters in hand' do
drawn_letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
dl_copy = drawn_letters.dup

# Hint: if your implementation of uses_available_letters?
# needs to change the hand, you should make a copy first
uses_available_letters? 'ABCD', drawn_letters

expect(drawn_letters).must_equal dl_copy
end
end

describe 'score_word method' do
it 'returns an accurate numerical score according to the score chart' do
expect(score_word("A")).must_equal 1
expect(score_word("DOG")).must_equal 5
expect(score_word("WHIMSY")).must_equal 17
end

it 'returns a score regardless of input case' do
expect(score_word("a")).must_equal 1
expect(score_word("dog")).must_equal 5
expect(score_word("wHiMsY")).must_equal 17
end

it 'returns a score of 0 if given an empty input' do
expect(score_word("")).must_equal 0
end

it 'adds an extra 8 points if the word is 7 or more characters long' do
expect(score_word("XXXXXXX")).must_equal 64
expect(score_word("XXXXXXXX")).must_equal 72
expect(score_word("XXXXXXXXX")).must_equal 80
end
end

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']
best_word = highest_score_from words

expect(best_word[:word]).must_equal 'XXXX'
expect(best_word[:score]).must_equal 32
end

it 'accurately finds best scoring word even if not sorted' do
words = ['XXX', 'XXXX', 'XX', 'X']
best_word = highest_score_from words

expect(best_word[:word]).must_equal 'XXXX'
expect(best_word[:score]).must_equal 32
end

it 'in case of tied score, prefers the word with fewer letters' do
# the character 'M' is worth 3 points, 'W' is 4 points
words = ['MMMM', 'WWW']

# verify both have a score of 12
expect(score_word(words.first)).must_equal 12
expect(score_word(words.last)).must_equal 12

best_word = highest_score_from words

expect(best_word[:word]).must_equal 'WWW'
expect(best_word[:score]).must_equal 12
end

it 'in case of tied score, prefers the word with fewer letters regardless of order' do
# the character 'M' is worth 3 points, 'W' is 4 points
words = ['WWW', 'MMMM']

# verify both have a score of 12
expect(score_word(words.first)).must_equal 12
expect(score_word(words.last)).must_equal 12

best_word = highest_score_from words

expect(best_word[:word]).must_equal 'WWW'
expect(best_word[:score]).must_equal 12
end

it 'in case of tied score, prefers most the word with 10 letters' do
# the character 'A' is worth 1 point, 'B' is 3 points
words = ['AAAAAAAAAA', 'BBBBBB']

# verify both have a score of 10
expect(score_word(words.first)).must_equal 18
expect(score_word(words.last)).must_equal 18

best_word = highest_score_from words

expect(best_word[:word]).must_equal 'AAAAAAAAAA'
expect(best_word[:score]).must_equal 18
end

it 'in case of tied score, prefers most the word with 10 letters regardless of order' do
# the character 'A' is worth 1 point, 'B' is 3 points
words = ['BBBBBB', 'AAAAAAAAAA']

# verify both have a score of 10
expect(score_word(words.first)).must_equal 18
expect(score_word(words.last)).must_equal 18

best_word = highest_score_from words

expect(best_word[:word]).must_equal 'AAAAAAAAAA'
expect(best_word[:score]).must_equal 18
end

it 'in case of tied score and same length words, prefers the first word' do
# the character 'A' is worth 1 point, 'E' is 1 point
words = ['AAAAAAAAAA', 'EEEEEEEEEE']

# verify both have a score of 10
expect(score_word(words.first)).must_equal 18
expect(score_word(words.last)).must_equal 18

best_word = highest_score_from words

expect(best_word[:word]).must_equal words.first
expect(best_word[:score]).must_equal 18
end
end

describe 'is_in_english_dict? method' do
it 'returns true if input is contained in the english dictionary' do
# Arrange
input = "adverbs"
# Act
answer = is_in_english_dict?(input)
# Assert
expect(answer).must_equal true

end
it 'returns false if input is not contained in the english dictionary' do
# Arrange
input = "laallaloo"
# Act
answer = is_in_english_dict?(input)
# Assert
expect(answer).must_equal false
end

it 'returns correct answer regardless of input case' do
# Arrange
input = "AdVeRbS"
# Act
answer = is_in_english_dict?(input)
# Assert
expect(answer).must_equal true
end

it 'returns false if given an empty input' do
# Arrange
input = ""
# Act
answer = is_in_english_dict?(input)
# Assert
expect(answer).must_equal false
end
end
end