diff --git a/lib/adagrams.rb b/lib/adagrams.rb index e69de29..a7eef32 100644 --- a/lib/adagrams.rb +++ b/lib/adagrams.rb @@ -0,0 +1,103 @@ +require "csv" + +def draw_letters + available_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} + drawn_letters = [] + 10.times do + letter = available_letters.keys.sample + while available_letters[letter] == 0 + letter = available_letters.keys.sample + end + drawn_letters.push(letter) + available_letters[letter] = available_letters[letter] - 1 + end + return drawn_letters +end + +# Method that deletes element in array at its specific index. Prevents deletion of mathcing elements +class Array + def delete_elements_in_(array) + array.each do |x| + if index = index(x) + delete_at(index) + end + end + end +end + +# Checks if user inputs letters from their letter bank +def uses_available_letters?(input, letters_in_hand) + used_letters = [] + input.each_char do |letter| + if letters_in_hand.include?(letter) == true + letters_in_hand.delete_elements_in_([letter]) + used_letters << letter + else + letters_in_hand = (letters_in_hand << used_letters).flatten! # Resets letter bank if previous user input included invalid letters + return false + end + end + letters_in_hand = (letters_in_hand << used_letters).flatten! + return true +end + +#Wave 3 +def score_word(word) + word = word.downcase + score = 0 + word.each_char do |letter| + case letter + when "a", "e", "i", "o", "u", "l", "n", "r", "s", "t" + score += 1 + when "d", "g" + score += 2 + when "b", "c", "m", "p" + score += 3 + when "f", "h", "v", "w", "y" + score += 4 + when "k" + score += 5 + when "j", "x" + score += 8 + when "q", "z" + score += 10 + end + end + if word.length >= 7 + score += 8 + end + return score +end + +#Wave 4 +def highest_score_from(words) + winning = {} + high_score = 0 + best_word = nil + words.each do |word| + if score_word(word) > high_score + high_score = score_word(word) + best_word = word + elsif score_word(word) == high_score + if best_word.length == 10 + next + elsif word.length == 10 + best_word = word + elsif word.length < best_word.length + best_word = word + end + end + end + winning[:word] = best_word + winning[:score] = high_score + return winning +end + +# Wave 5 +def is_in_english_dict?(input) + english_words = CSV.read("assets/dictionary-english.csv") + return english_words.flatten!.include?(input) +end diff --git a/specs/adagrams_spec.rb b/specs/adagrams_spec.rb index ae2ccd0..36b5616 100644 --- a/specs/adagrams_spec.rb +++ b/specs/adagrams_spec.rb @@ -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 @@ -26,81 +26,79 @@ 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 @@ -108,13 +106,13 @@ 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 @@ -122,13 +120,13 @@ 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 @@ -136,13 +134,13 @@ 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 @@ -150,13 +148,13 @@ 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 @@ -168,4 +166,16 @@ expect(best_word[:score]).must_equal 18 end end + + describe "is in dictionary" do + it "returns true for word in English dictionary" do + word = "cat" + expect(is_in_english_dict?(word)).must_equal true + end + + it "returns false if word not in English dictionary" do + word = "qqq" + expect(is_in_english_dict?(word)).must_equal false + end + end end