Skip to content
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
Binary file added .DS_Store
Binary file not shown.
141 changes: 141 additions & 0 deletions lib/adagrams.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
require "pry"
require "csv"

LETTER_POOL =
{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}

def score_word(word)
word = word.upcase

score = 0
word.split("").each do |char|
case
when "AEIOULNRST".include?(char)
score += 1
when "DG".include?(char)
score += 2
when "BCMP".include?(char)
score += 3
when "FHVWY".include?(char)
score += 4
when "K".include?(char)
score += 5
when "JX".include?(char)
score += 8
when "QZ".include?(char)
score += 10
end
end
if word.length >= 7
score += 8
end

return score
end

def draw_letters
letters_hash = {}
letters_array = []
i = 0
until i == 10
char = LETTER_POOL.to_a.sample[0]

Choose a reason for hiding this comment

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

By this logic, you're as likely to draw an e as you are a z!

Instead, you might create an array containing all the letters, with code similar to this:

letter_counts = {
  # the hash you had before
}
letters = []
letter_counts.each do |letter, count|
  count.times do
    letters << letter
  end
end

Then you could pull a random tile with letters.sample and get a nice even distribution.


if letters_hash.has_key?(char)
if letters_hash[char] < LETTER_POOL[char].to_i
letters_hash.merge!({char => letters_hash[char] + 1})
letters_array << char.to_s
i += 1
end
else
letters_hash.merge!({char => 1})
letters_array << char.to_s
i += 1
end
end
return letters_array
end

def uses_available_letters?(input, letters_in_hand)
input.upcase!
popping_array = letters_in_hand.clone
check = true
input.split("").each do |char|
if !popping_array.include?(char)
check = false

Choose a reason for hiding this comment

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

I'll leave this as a "vague thing" to think about... I think that while you iterate through input.chars, you can actually determine that uses_available_letters? can return false before the loop finishes.

Remember, when you use the return keyword, it will kick the program execution out of the method early, and return whatever value you give it.

else
index = popping_array.find_index(char)
popping_array.delete_at(index)
end
end
return check
end

def highest_score_from(words)
words_and_scores = []
words.each do |word|
hash = {}
score = score_word(word)
hash.merge!({word: word, score: score})
words_and_scores << hash
end

temp_hash = words_and_scores.max_by { |x| x[:score] }

max_score = temp_hash[:score]

highest_scoring_words = words_and_scores.select { |x| x[:score] == max_score }

winner = ""
if highest_scoring_words.length > 1
highest_scoring_words.each do |hash|
if hash[:word].length == 10
winner = hash[:word]
break
else
winner_hash = highest_scoring_words.min_by { |hash2| hash2[:word].length }
winner = winner_hash[:word]
end
end
result_hash = {word: winner, score: max_score}
else
result_hash = temp_hash
end

return result_hash
end

def is_in_english_dict?(input)
dictionary = CSV.read("assets/dictionary-english.csv")
input.downcase!
word_in_array = [input]
if dictionary.include? word_in_array
return true
else
return false
end
end
114 changes: 68 additions & 46 deletions specs/adagrams_spec.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
require 'minitest/autorun'
require 'minitest/reporters'
require 'minitest/skip_dsl'
require "minitest/autorun"
require "minitest/reporters"
require "minitest/skip_dsl"

require_relative '../lib/adagrams'
require_relative "../lib/adagrams"

# Get that nice colorized output
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new

describe 'Adagrams' do
describe 'draw_letters method' do
it 'draws ten letters from the letter pool' do
describe "Adagrams" do
describe "draw_letters method" do
it "draws ten letters from the letter pool" do
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
it "returns an array, and each item is a single-letter string" do
drawn_letters = draw_letters
expect(drawn_letters.size).must_equal 10

Expand All @@ -26,137 +26,135 @@
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'
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'
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'
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

end

describe 'score_word method' do
it 'returns an accurate numerical score according to the score chart' do
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
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
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
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']
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[: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']
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[: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
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']
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[: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
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']
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[: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
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']
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[: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
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']
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[: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
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']
words = ["AAAAAAAAAA", "EEEEEEEEEE"]

# verify both have a score of 10
expect(score_word(words.first)).must_equal 18
Expand All @@ -169,3 +167,27 @@
end
end
end

describe "determines whether words are in the English dictionary" do
it "finds the word in the dictionary" do
# arrange
word = "giraffe"
# act
check_word = is_in_english_dict?(word)

# assert

expect(check_word).must_equal true
end

it "doesn't find non-word in the dictionary" do
# arrange
word = "girafee"
# act
check_word = is_in_english_dict?(word)

# assert

expect(check_word).must_equal false
end
end