diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..deb52f2c --- /dev/null +++ b/Rakefile @@ -0,0 +1,9 @@ +require 'rake/testtask' + +Rake::TestTask.new do |t| + t.libs = ["lib"] + t.warning = true + t.test_files = FileList['specs/*_spec.rb'] +end + +task default: :test diff --git a/lib/player.rb b/lib/player.rb new file mode 100644 index 00000000..0838417d --- /dev/null +++ b/lib/player.rb @@ -0,0 +1,69 @@ +require_relative '../lib/scoring' +require_relative '../lib/tilebag' + +class Player + WINNING_SCORE = 100 + + def initialize(name, scores_array=[], words_played=[]) + @name = name + @scores_array = scores_array + @words_played = words_played + return @name + end + + def name_return + @name + end + + # returns sum of scores of played words + def total_score + @scores_array.reduce(0, :+) + end + + # returns an array of all the words played by Player + def plays + return @words_played + end + + # adds word to the words_played array + def play(word) + # test to see if score is over 100 + if @scores_array.reduce(0, :+) >= WINNING_SCORE + return false + end + @words_played << word + @scores_array << Scoring.score(word) + end + + # returns true if over 100pts, otherwise false(haven't won yet) + def won? + if @scores_array.reduce(0, :+) >= WINNING_SCORE + "You win!" + return true + else + "You haven't won yet." + return false + end + end + + # returns highest scored word from words_played array + def highest_scoring_word + Scoring.highest_score_from(@words_played) + end + + # returns the highest score + def highest_word_score + @scores_array.max + end + + def draw_tiles(number_of_tiles) + tilebag = TileBag.new + tilebag.draw_tiles(number_of_tiles) + end + + def tiles(number_of_tiles) + tilebag = TileBag.new + tilebag = draw_tiles(number_of_tiles) + end +end + diff --git a/lib/scoring.rb b/lib/scoring.rb new file mode 100644 index 00000000..7843be4d --- /dev/null +++ b/lib/scoring.rb @@ -0,0 +1,91 @@ +class Scoring + LETTER_SCORING = { + "A" => 1, + "B" => 3, + "C" => 3, + "D" => 2, + "E" => 1, + "F" => 4, + "G" => 2, + "H" => 4, + "I" => 1, + "J" => 8, + "K" => 5, + "L" => 1, + "M" => 3, + "N" => 1, + "O" => 1, + "P" => 3, + "Q" => 10, + "R" => 1, + "S" => 1, + "T" => 1, + "U" => 1, + "V" => 4, + "W" => 4, + "X" => 8, + "Y" => 4, + "Z" => 10, + } + + def self.score(word) + word = word.upcase! + word_array = word.split("") # could use .chars here + score_value = 0 + + # applies 50 point bonus for words >= 7 letters + amount_of_loops = word_array.length + if amount_of_loops >= 7 + score_value +=50 + end + word_array.each do |letter| + LETTER_SCORING.each do |hash_letter, point_value| + if hash_letter == letter + score_value += point_value + end + end + end + return score_value.to_i + end + + def self.highest_score_from(array_of_words) + score_values_array = [] + + array_of_words = array_of_words.map(&:upcase) + array_of_words.each do |word_in_array| + score_value = 0 + letter_array = word_in_array.split("") + # checks for the 50 point bonus + amount_of_loops = letter_array.length + if amount_of_loops >= 7 + score_value +=50 + end + + #split each word into letters, scan and score each letter + letter_array.each do |letter| + LETTER_SCORING.each do |hash_letter, point_value| + if hash_letter == letter + score_value += point_value + end + end + end + # collects all of the scores for each word + score_values_array << score_value + end + + # index of the highest scoring word = array of word values() + high_value_index = score_values_array.index(score_values_array.max) + + # used to check for a tie + tie_value_index = + score_values_array.each_index.select {|i| score_values_array[i] == score_values_array.max} + # tie_value_index holds the indexes of the highest score. if more than one, it's a tie + if tie_value_index.length > 1 + #can handle any number of words that are tied + return tie_value_index.min{|a, b| a.size <=> b.size} + else + # returns the highest value word when there is no tie + return array_of_words[high_value_index] + end + end +end diff --git a/lib/tilebag.rb b/lib/tilebag.rb new file mode 100644 index 00000000..472914c7 --- /dev/null +++ b/lib/tilebag.rb @@ -0,0 +1,27 @@ +class TileBag + + def initialize + @tilebag = [ + "A", "A", "A", "A", "A", "A", "A", "A", "A", "N", "N", "N", "N", "N", "N", + "B", "B", "O", "O", "O", "O", "O", "O", "O", "O", "C", "C", "P", "P", "D", + "D", "D", "D", "Q", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", "E", + "E", "R", "R", "R", "R", "R", "R", "F", "F", "S", "S", "S", "S", "G", "G", + "G", "T", "T", "T", "T", "T", "T", "H", "H", "U", "U", "U", "U", "I", "I", + "I", "I", "I", "I", "I", "I", "I", "V", "V", "J", "W", "W", "K", "X", "L", + "L", "L", "L", "Y", "Y", "M", "M", "Z" + ] + end + + def draw_tiles(number_of_tiles) + if number_of_tiles > 7 + raise ArgumentError,"That's too many tiles! Stop CHEATING" + else + @tilebag = @tilebag.shuffle + tiles_drawn = @tilebag.shift(number_of_tiles) + end + end + + def tiles_remaining + @tilebag.length + end +end \ No newline at end of file diff --git a/scrabble.rb b/scrabble.rb new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/scrabble.rb @@ -0,0 +1 @@ + diff --git a/specs/player_spec.rb b/specs/player_spec.rb new file mode 100644 index 00000000..bf89ac70 --- /dev/null +++ b/specs/player_spec.rb @@ -0,0 +1,93 @@ +require_relative './spec_helper' +require_relative '../lib/player' +require_relative '../lib/tilebag' + +describe Player do + WORDS_PLAYED = ["GOAT", "PUPPY", "MONKEY", "CAT", "WHALES", "IGUANA"] + HIGH_SCORE_TEST = [200] + + # TEST 1 + it "Player is an object we have access to" do + Player.wont_be_nil + end + + # TEST 2 + it "should return a name when entered" do + fran = Player.new("Fran") + assert_equal "Fran", fran.name_return + end + + # TEST 3 + it "should allow the player to play a word" do + fran = Player.new("Fran") + assert_equal [8], fran.play("word") + end + + # TEST 4 + it "should return an array of words played" do + fran = Player.new("Fran") + fran.play("goat") + fran.play("puppy") + fran.play("monkey") + fran.play("cat") + fran.play("whales") + fran.play("iguana") + assert_equal WORDS_PLAYED, fran.plays + end + + # TEST 5 + it "return false if player plays when score is >= 100" do + chacha = Player.new("ChaCha", HIGH_SCORE_TEST) + assert_equal false, chacha.play("word") + end + + # TEST 6 + it "should return true for winning" do + chacha = Player.new("ChaCha", HIGH_SCORE_TEST) + assert true, chacha.won? + end + + # TEST 7 + it "should return total score of words played so far" do + fran = Player.new("Fran") + fran.play("goat") + fran.play("puppy") + assert_equal 19, fran.total_score + end + # TEST 8 + it "should return highest scoring word played" do + fran = Player.new("Fran") + fran.play("goat") + fran.play("puppy") + assert_equal "PUPPY", fran.highest_scoring_word + end + # TEST 9 + it "should return highest word score" do + fran = Player.new("Fran") + fran.play("goat") + fran.play("puppy") + assert_equal 14, fran.highest_word_score + end + # TEST 10 + it "returns the score of a word played" do + fran = Player.new("Fran") + assert_equal [14], fran.play("puppy") + end + # TEST 11 + it "player class accepts one argument" do + assert_raises(ArgumentError) {fran = Player.new} + end + + # TEST 12 + it "raises an error if too many tiles are drawn" do + fran = Player.new("Fran") + assert_raises(ArgumentError) {fran.tiles(10)} + end + + # TEST 13 + it "returns a number of tiles when drawn" do + fran = Player.new("Fran") + refute_equal nil, fran.draw_tiles(7) + end +end + diff --git a/specs/scoring_spec.rb b/specs/scoring_spec.rb new file mode 100644 index 00000000..da93d083 --- /dev/null +++ b/specs/scoring_spec.rb @@ -0,0 +1,53 @@ +require_relative './spec_helper' +require_relative '../lib/scoring' + +describe Scoring do + # Test 5 + HIGH_SCORE = ["dog", "bird", "quiz", "bug"] + # Test 6 + FIFTY_POINT_HIGH_SCORE = ["dog", "bird", "quiz", "require"] + # Test 7 + RETURN_FEWEST_LETTERS_TIE = ["ale", "hi", "zinc", "cat", "squad", "butts"] + # Test 8 + RETURN_FIRST_WORD_TIE = ["ale", "hi", "zaps", "cat", "squad", "butts", "zinc"] + + # TEST 1 + it "Scoring is an object we have access to" do + Scoring.wont_be_nil + end + # TEST 2 + it "is a class method we have access to" do + Scoring.score("test").wont_be_nil + end + # TEST 3 + it "validates score method returns correct score" do + Scoring.score("pig") + return 6 + end + # TEST 4 + it "50-point bonus is applied to words >= 7 letters" do + Scoring.score("require") + return 66 + end + # TEST 5 + it "returns the highest scoring word" do + Scoring.highest_score_from(HIGH_SCORE) + return "quiz" + end + # TEST 6 + it "returns highest scoring word with 50 point bonus" do + Scoring.highest_score_from(FIFTY_POINT_HIGH_SCORE) + return "require" + end + # TEST 7 + it "returns the word with the fewest letters during a tie" do + Scoring.highest_score_from(RETURN_FEWEST_LETTERS_TIE) + return "zinc" + end + # TEST 8 + # for highest score and fewest letters + it "returns first given word during a tie" do + Scoring.highest_score_from(RETURN_FIRST_WORD_TIE) + return "zaps" + end +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 00000000..051f75e3 --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,10 @@ +require 'simplecov' +SimpleCov.start + +require 'minitest' +require 'minitest/spec' +require 'minitest/autorun' +require 'minitest/reporters' + +#give us some really pretty output :) +Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new diff --git a/specs/tilebag_spec.rb b/specs/tilebag_spec.rb new file mode 100644 index 00000000..2aa0b602 --- /dev/null +++ b/specs/tilebag_spec.rb @@ -0,0 +1,35 @@ +require_relative './spec_helper' +require_relative '../lib/tilebag' + +describe TileBag do + + # TEST 1 + it "is an object we have access to" do + TileBag.wont_be_nil + end + + # TEST 2 + it "draw tiles accepts an argument" do + chacha = TileBag.new + chacha.draw_tiles(7).wont_be_nil + end + + # TEST 3 + it "draw tiles returns tiles drawn" do + chacha = TileBag.new + chacha.draw_tiles(7).wont_be_nil + end + + # TEST 4 + it "tiles remaining returns the length" do + chacha = TileBag.new + chacha.draw_tiles(7) + assert_equal 91, chacha.tiles_remaining + end + + # TEST 5 + it "errors when more than seven tiles are drawn" do + chacha = TileBag.new + assert_raises(ArgumentError) {chacha.draw_tiles(10)} + end +end