diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..679fda0d Binary files /dev/null and b/.DS_Store differ diff --git a/.ruby-gemset b/.ruby-gemset new file mode 100644 index 00000000..b0582e1f --- /dev/null +++ b/.ruby-gemset @@ -0,0 +1 @@ +Scrabble diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000..276cbf9e --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.3.0 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..4eb57ccb --- /dev/null +++ b/lib/player.rb @@ -0,0 +1,56 @@ +require_relative '../scrabble' +require_relative './scoring' + +class Scrabble::Player +attr_reader :name, :plays, :tiles +attr_accessor :total_score + + # set up with empty plays array and score as instance variable + def initialize(name, score = 0) + @name = name + @total_score = score + @plays = [] + @tiles = [] + end + + def play(word) + # requirement: return false if player's score > 100 + return false if won? + + # Adds the input word to the plays Array + self.plays << word + + # add score for word to @score + self.total_score += Scrabble::Scoring.score(word) + + # Returns the score of the word + Scrabble::Scoring.score(word) + end + + def won? + # If the player has over 100 points returns true + return true if self.total_score > 100 + end + + def highest_scoring_word(array_of_words) + highest_score = "" + array_of_words.each do |word| + highest_score = word if Scrabble::Scoring.score(word) > Scrabble::Scoring.score(highest_score) + end + return highest_score + end + + def highest_word_score + highest_score = "" + plays.each do |word| + highest_score = word if Scrabble::Scoring.score(word) > Scrabble::Scoring.score(highest_score) + end + return Scrabble::Scoring.score(highest_score) + end + + def draw_tiles(tile_bag) + tiles << tile_bag.draw_tiles(Scrabble::MAX_TILES - tiles.length) + tiles.flatten! + end + +end diff --git a/lib/scoring.rb b/lib/scoring.rb new file mode 100644 index 00000000..29c7223c --- /dev/null +++ b/lib/scoring.rb @@ -0,0 +1,68 @@ +# possibly require Scrabble module +# require 'enumerable' +require_relative '../scrabble' + +class Scrabble::Scoring # declare this as Scrabble::Scoring during cleanup. + +def self.score(word) + self.scoring_math(word) +end + +def self.highest_score_from(array_of_words) + highest_score = "" + array_of_words.each do |word| + if self.score(word) > self.score(highest_score) + highest_score = word + elsif self.score(word) == self.score(highest_score) + highest_score = word if word.length < highest_score.length + end + end + return highest_score +end + +private # hiding the mess even from ourselves!! + +def self.scoring_math(word) + # iterate over the letters in the word (after downcasing the word to ensure it matches up + # against our CONSTANT for checking) + # figure out what word[index] is worth + # add to running total + total_score = 0 + + word = word.downcase + + for index in 0..word.length - 1 + if Scrabble::LETTER_POINT_VALUES[1].include? word[index] + total_score += 1 + elsif Scrabble::LETTER_POINT_VALUES[2].include? word[index] + total_score += 2 + elsif Scrabble::LETTER_POINT_VALUES[3].include? word[index] + total_score += 3 + elsif Scrabble::LETTER_POINT_VALUES[4].include? word[index] + total_score += 4 + elsif Scrabble::LETTER_POINT_VALUES[5].include? word[index] + total_score += 5 + elsif Scrabble::LETTER_POINT_VALUES[8].include? word[index] + total_score += 8 + elsif Scrabble::LETTER_POINT_VALUES[10].include? word[index] + total_score += 10 + end + end + + # check if the word gets a bingo bonus + if self.bonus?(word) + total_score += 50 + end + + return total_score +end + +# this will check if the word gets a bingo bonus! +# it should be a huh? method +def self.bonus?(word) + if word.length >= 7 + return true + end +end + +end diff --git a/lib/tilebag.rb b/lib/tilebag.rb new file mode 100644 index 00000000..b8413a90 --- /dev/null +++ b/lib/tilebag.rb @@ -0,0 +1,20 @@ +require_relative '../scrabble' + +class Scrabble::Tilebag + attr_reader :tiles + + def initialize + @tiles = Scrabble::DEFAULT_TILES.shuffle + end + + def draw_tiles(num) + tiles_drawn = [] + tiles_drawn << tiles.pop until tiles_drawn.length == num + return tiles_drawn + end + + def tiles_remaining + tiles.length + end + +end diff --git a/scrabble.rb b/scrabble.rb new file mode 100644 index 00000000..758d57e6 --- /dev/null +++ b/scrabble.rb @@ -0,0 +1,43 @@ +# require_relative './lib/scoring' + +module Scrabble + +# fill in this array of hashes as a lookup table +LETTER_POINT_VALUES = { 1 => ["a", "e", "i", "o", "u", "l", "n", "r", "s", "t"], + 2 => ["d", "g"], + 3 => ["b", "c", "m", "p"], + 4 => ["f", "h", "v", "w", "y"], + 5 => ["k"], + 8 => ["j", "x"], + 10 => ["q", "z"]} + +DEFAULT_TILES = ["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"] + + MAX_TILES = 7 + +end diff --git a/specs/.DS_Store b/specs/.DS_Store new file mode 100644 index 00000000..53ee3d85 Binary files /dev/null and b/specs/.DS_Store differ diff --git a/specs/player_spec.rb b/specs/player_spec.rb new file mode 100644 index 00000000..bd23484c --- /dev/null +++ b/specs/player_spec.rb @@ -0,0 +1,80 @@ +require_relative './spec_helper' +require_relative '../scrabble' +require_relative '../lib/player' +require_relative '../lib/tilebag' + +describe Scrabble::Player do + before do + @testbag = Scrabble::Tilebag.new + + @jane = Scrabble::Player.new("Jane") + + + @bob = Scrabble::Player.new("bob") + @bob.total_score + + @fred = Scrabble::Player.new("fred") + @fred.play("cupcake") + @fred.play("abalone") + end + + + + it "exists" do + Scrabble::Player.wont_be_nil + end + + # this test works because a proc is an objct that holds the code and runs it at testing and returns the value + it "has a name" do + proc { Scrabble::Player.new() }.must_raise(ArgumentError) + end + + it "has a readable name instance variable" do + @jane.must_respond_to(:name) + end + + it "will return a value when total score is queried" do + @jane.must_respond_to(:total_score) + end + + it "will return the score when a play is made" do + @jane.play("cat").must_equal(Scrabble::Scoring.score("cat")) + end + + it "will increase total_score when a word is played" do + score = @jane.total_score + @jane.play("elephant") + @jane.total_score.must_equal(score + Scrabble::Scoring.score("elephant")) + end + + it "will push a word into the plays array" do + @jane.play("cat") + @jane.plays.must_include("cat") + end + + it "will return true if total score is >100" do + @fred.won?.must_equal(true) + end + + it "will return false if a winner tries to make a play" do + @fred.play("cat").must_equal(false) + end + + it "selects the highest value word in the array" do + @fred.highest_scoring_word(@fred.plays).must_equal("cupcake") + end + + it "selects the highest value word in the array and shows score value" do + @fred.highest_word_score.must_equal(Scrabble::Scoring.score(@fred.highest_scoring_word(@fred.plays))) + end + + it "will return the tiles when queried" do + @bob.must_respond_to(:tiles) + end + + it "will fill tiles when tiles are drawn" do + @bob.draw_tiles(@testbag) + @bob.tiles.length.must_equal(Scrabble::MAX_TILES) + end + +end diff --git a/specs/sandbox_player_spec.rb b/specs/sandbox_player_spec.rb new file mode 100644 index 00000000..e3b1f208 --- /dev/null +++ b/specs/sandbox_player_spec.rb @@ -0,0 +1,79 @@ +#require_relative './spec_helper' +#require_relative '../scrabble' +#require_relative '../lib/player' +# +#describe Scrabble::Player do +# let(:jane) { jane = Scrabble::Player.new("Jane") +# jane.play("cat") +# return jane +# } +# +# +# let(:bob) { Scrabble::Player.new("bob") +# } +# +# +# let(:fred) { Scrabble::Player.new("fred") +# # fred.play("cupcake") +# # fred.play("abalone") +# # return fred +# } +# +# +# +# +# +# +# it "exists" do +# Scrabble::Player.wont_be_nil +# end +# +# # this test works because a proc is an objct that holds the code and runs it at testing and returns the value +# it "has a name(sb)" do +# proc { Scrabble::Player.new() }.must_raise(ArgumentError) +# end +# +# it "(sb)returns the name when queried" do +# jane.name.must_equal("Jane") +# end +# +# it "(sb)will return a value when total score is queried" do +# jane.total_score.wont_be_nil +# end +# +# it "(sb)will return the score when a play is made" do +# jane.play("cat").must_equal(5) +# end +# +# it "(sb)will push a word into the plays array" do +# jane.play("sat") +# jane.plays.must_include("sat") +# end +# +# # this test is meaningful because it tests if the score increases. +# # we use a word we know the score of to test if the total_score increases by that much. +# it "(sb)will increase total_score when a word is played" do +# jane.total_score.must_equal(score + 5) +# end +# +# it "(sb)will return true if total score is > 100" do +# fred.won?.must_equal(true) +# end +# +# it "(sb)will return false if total score is < 100" do +# bob.won?.must_equal(false) +# end +# +# it "(sb)returns highest scoring word in an array" do +# fred.highest_scoring_word(fred.plays).must_equal("cupcake") +# end +# +# it "(sb)returns the score for highest scoring word" do +# fred.highest_word_score.must_equal(67) +# end +# +# it "(sb)will return false if a winner tries to make a play" do +# fred.play("cat").must_equal(false) +# end +#end +# \ No newline at end of file diff --git a/specs/scoring_spec.rb b/specs/scoring_spec.rb new file mode 100644 index 00000000..abec1224 --- /dev/null +++ b/specs/scoring_spec.rb @@ -0,0 +1,38 @@ +require_relative './spec_helper' +require_relative '../scrabble' +require_relative '../lib/scoring' + +describe Scrabble::Scoring do + it "exists" do + Scrabble::Scoring.wont_be_nil + end + + TEST_WORDS = { + "sat" => 3, + "hotdog" => 11, + "puppet" => 12, + "cupcake" => 67, + "queen" => 14, + "QUEEN" => 14, + "CupCaKe" => 67 + } + + TEST_WORDS.each do |word, score| + it "returns total score value for the word" do + Scrabble::Scoring.score(word).must_equal(score) + end + end + + TEST_ARRAYS = { + ["cat", "dog", "face", "data"] => "face", + ["talon", "cat", "pie", "dog"] => "cat", + ["jack", "benzol", "blazer", "cupcake"] => "cupcake" + } + + TEST_ARRAYS.each do |array, word| + it "selects the highest value word in the array" do + Scrabble::Scoring.highest_score_from(array).must_equal(word) + end + end + +end diff --git a/specs/spec_helper.rb b/specs/spec_helper.rb new file mode 100644 index 00000000..c0fc8196 --- /dev/null +++ b/specs/spec_helper.rb @@ -0,0 +1,9 @@ +require 'simplecov' +SimpleCov.start + +require 'minitest' +require 'minitest/spec' +require 'minitest/autorun' +require 'minitest/reporters' + +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..9310fbed --- /dev/null +++ b/specs/tilebag_spec.rb @@ -0,0 +1,35 @@ +require_relative './spec_helper' +require_relative '../scrabble' +require_relative '../lib/tilebag' + +describe Scrabble::Tilebag do + + before do + @tilebag = Scrabble::Tilebag.new + end + + it "exists" do + Scrabble::Tilebag.wont_be_nil + end + + it "has the correct letters" do + @tilebag.tiles.length.must_equal(Scrabble::DEFAULT_TILES.length) + end + + it "returns a tile when you draw one" do + Scrabble::DEFAULT_TILES.must_include(@tilebag.draw_tiles(1)[0]) + end + + TILE_DRAWS = [4, 6, 3, 1] + + TILE_DRAWS.each do |index| + it "returns same number of tiles as is drawn" do + @tilebag.draw_tiles(index).length.must_equal(index) + end + + it "returns the correct number of remaining tiles after a play" do + @tilebag.draw_tiles(index) + @tilebag.tiles_remaining.must_equal(Scrabble::DEFAULT_TILES.length - index) + end + end +end