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

Kate Shaffer & Kelly Tran - the mighty K&K pair #11

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
31f046f
created 4 new files: Rakefile, scoring.rb, scoring_spec.rb and spec_h…
KellyPT Aug 29, 2016
c5c1bcb
Began implementation of self.score method
brookseakate Aug 30, 2016
eb3b20d
built the self.score method and made 4 tests for this method
KellyPT Aug 30, 2016
0ca951d
added highest_scoring_method and created 5 new tests
KellyPT Aug 31, 2016
3af7e08
Updated self.highest_score_from to pass tests for arrays passed in wi…
brookseakate Aug 31, 2016
efd8d83
Finished the remaining tests for the second method. Completed the Wav…
KellyPT Aug 31, 2016
67a7421
Updated scoring.rb with Kari's feedback -- better ternary in bonus_sc…
brookseakate Aug 31, 2016
3980bd8
created 2 new files player.rb and player_spec.rb. Passed 2 tests for …
KellyPT Aug 31, 2016
bc450be
modified .gitignore and spec_helper.rb
KellyPT Aug 31, 2016
0314a72
Created tests
KellyPT Aug 31, 2016
acf9a0d
commit the .gitignore
KellyPT Aug 31, 2016
abf092f
Updated scoring.rb to accept lowercase input
brookseakate Aug 31, 2016
31b20df
Finished #play(word) method & its tests
brookseakate Aug 31, 2016
76ec5ce
created total_score and won? method. wrote the tests for these methods
KellyPT Aug 31, 2016
a22a9d3
Implemented highest_scoring_word & highest_word_score methods & their…
brookseakate Aug 31, 2016
81d0d6b
Minor cleanup
brookseakate Aug 31, 2016
6c02ee8
Kari raised a question: what happened to highest_scoring_word method …
KellyPT Sep 1, 2016
9f0c00c
Successfully handled Kari's question after a lot of mind-mapping and …
KellyPT Sep 1, 2016
3f975e6
Began implementation of TileBag class & tests. Completed #initialize.
brookseakate Sep 1, 2016
45b212c
created 2 methods: draw_tiles(num) and tile_remaining. created tests …
KellyPT Sep 1, 2016
fd55903
Updated player.rb & its tests to implement draw_tiles method.
brookseakate Sep 2, 2016
700d364
Successfully implemented optional requirement: removes tiles played f…
KellyPT Sep 2, 2016
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/test/tmp/
/test/version_tmp/
/tmp/
.DS_Store

## Specific to RubyMotion:
.dat*
Expand Down
7 changes: 7 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'rake/testtask'

Rake::TestTask.new do |t|
t.test_files = FileList['specs/*_spec.rb']
end

task default: :test
96 changes: 96 additions & 0 deletions player.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# create the Player class

require_relative 'scoring'
require_relative 'tile_bag'

module Scrabble
class Player
attr_accessor :name, :plays, :won, :total_score, :tiles

def initialize(name)
@name = name
@plays = []
@tiles = []
@won = false
@total_score = 0

if !name.is_a?(String)
raise ArgumentError, "Invalid input. Please give us a string."
end
end

def play(word)
if !word.is_a?(String)
raise ArgumentError, "Invalid input. Please give us a string."
end

# verify if the played word is in the tiles array, and remove the letters in word from tiles array
played_letter = word.upcase.split("")

clone_tiles = @tiles.clone
played_letter.each do |letter|
index = clone_tiles.find_index(letter)
if index.is_a?(Fixnum)
clone_tiles.delete_at(index)
else
puts "This word is not calling from your tiles!"
return nil
end
end

@tiles = clone_tiles

# add new word to @plays instance variable
@plays << word.upcase

# if won, return false. if not won, return word score
return @won == true ? false : Scrabble::Scoring.score(word)
end # play(word)

def total_score
@plays.each do |word|
word_score = Scrabble::Scoring.score(word)
@total_score += word_score
end
return @total_score
end

def won?
return @total_score > 100 ? true : false
end

def highest_scoring_word
if @plays.length == 0
puts "This player hasn't played yet."
return nil
else
return Scrabble::Scoring.highest_score_from(@plays)
end
end

def highest_word_score
if highest_scoring_word == nil
puts "He/she has no score!"
return nil
else
return Scrabble::Scoring.score(highest_scoring_word)
end
end

def draw_tiles(tile_bag)
if !tile_bag.is_a?(Scrabble::TileBag)
raise ArgumentError, "Parameter should be an instance of the TileBag class"
end

if @tiles.length < 7
tiles_needed = 7 - @tiles.length
@tiles += tile_bag.draw_tiles(tiles_needed)
else
puts "This player cannot draw more tiles."
end

return @tiles
end # draw_tiles

end # Player class
end # Scrabble class
104 changes: 104 additions & 0 deletions scoring.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
module Scrabble
class Scoring
attr_reader

TILES ={
"1" => %w(A E I O U L N R S T),
"2" => %w(D G),
"3" => %w(B C M P),
"4" => %w(F H V W Y),
"5" => %w(K),
"8" => %w(J X),
"10" => %w(Q Z)
}

def initialize
end

def self.bonus(word)
# ternary -- assigns bonus_score 50 if length 7 or 0 if else
bonus_score = word.length == 7 ? 50 : 0
return bonus_score
end

def self.score(word)
if word.class != String
raise ArgumentError, "Invalid input"
end

arr = word.upcase.split('')

score = 0

arr.each do |i|
result = nil
TILES.each do |k, v|
if v.include?(i)
result = k.to_i
score += result
end
end
end

return score + self.bonus(word)
end # self.score method

def self.highest_score_from(array_of_words)
if array_of_words.class != Array
raise ArgumentError, "Invalid input"
elsif array_of_words.length == 0
raise ArgumentError, "Invalid input"
end

# create a hash that store the score-word(s) pairs
score_result = {}
winning_array = []

array_of_words.map do |word|
w = word.upcase
score = self.score(w)
if score_result.keys.include?(score)
score_result[score] += [w]
else
score_result[score] = [w]
end
end

# retrieve the highest score key in the hash
highest_score = score_result.keys.max
# @todo THIS IS WHERE WE HAVE NIL VALUE WHEN NOTHING IS PLAYED.

# retrieve the array value corresponding to the highest score key in the hash
winning_array = score_result[highest_score]
puts winning_array.class

# check whether winning array has 1 word or >1 word
if winning_array.length > 1
# now we consider the length of words inside the winning array
# create a hash that store the length-words pairs
winning_hash = {}
winning_array.map do |word|
len = word.length
if winning_hash.keys.include?(len)
winning_hash[len] += [word]
else
winning_hash[len] = [word]
end
end
# first check which word has 7 letters, then check for the letter with the shortest length. 'first' method on array will ensure we retrieve the letter who comes first in the original array input.
if winning_hash.keys.include?(7)
winning_word = winning_hash[7].first
else
winning_word = winning_hash[winning_hash.keys.min].first
end
elsif winning_array.length == 1
winning_word = winning_array.first
elsif winning_array.length == 0
winning_word = nil
end

return winning_word
end

end # Scoring class
end # Scrabble module
149 changes: 149 additions & 0 deletions specs/player_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
# test for Player class

require_relative '../player'
require_relative '../tile_bag'
require_relative 'spec_helper'

describe Scrabble::Player do
new_player = Scrabble::Player.new("Jasper")

describe "#initialize" do
it "must be an instance of the Player class" do
Scrabble::Player.new("Jasper").must_be_instance_of(Scrabble::Player)
end

it "should have the same value that we set" do
new_player.name.must_equal("Jasper")
end

it "should raise an error if a non-string parameter input is passed in" do
proc {Scrabble::Player.new(123)}.must_raise(ArgumentError)
end

it "should have a tiles property" do
new_player.must_respond_to(:tiles)
end
end

describe "#play(word)" do
it "must raise an error if a non-string parameter input is passed into the method (play(word))" do
proc {Scrabble::Player.new("Jasper").play(123)}.must_raise(ArgumentError)
end

it "@plays array should be different after calling the play(word) method" do
player_1 = Scrabble::Player.new("Yoyo")
player_1.tiles = %w(S H O W E R S)
original_array = player_1.plays.clone
player_1.play("SHOWERS")
player_1.plays.wont_equal(original_array)
end

it "the word passed in to play(word) method should be the last item in @plays array" do
player_2 = Scrabble::Player.new("Yaya")
player_2.tiles = %w(S H O W E R S)
player_2.play("SHOWERS")
player_2.plays.last.must_equal("SHOWERS")
end

it "should return the score of the string input if not won" do
another_player = Scrabble::Player.new("Kelly")
another_player.tiles = %w(L I O N E S S)
another_player.play("lioness").must_equal(57)
end

it "should return false if player already won" do
new_player.won = true
new_player.tiles = %w(L I O N E S S)
new_player.play("lioness").must_equal(false)
end

it "should raise an error when the played word is NOT in the @tile array" do
bad_player = Scrabble::Player.new("Maleficient")
bad_player.tiles = %w(A B C D E F G)
bad_player.play('XYZ').must_equal(nil)
end

it "should return an updated @tiles array after play(word) is called" do
another_bad_player = Scrabble::Player.new("Mustafa")
another_bad_player.tiles = %w(A B C D E F G)
copy_original_tiles = another_bad_player.tiles.clone
another_bad_player.play('ABC')
another_bad_player.tiles.wont_equal(copy_original_tiles)
end

it "should return the original @tiles array if the play(word) is called with letters which don't exist in the @tiles array" do
last_player = Scrabble::Player.new("Pikachu")
last_player.tiles = %w(P O K E M O N S)
copy_last_player_tiles = last_player.tiles.clone
last_player.play('POKER')
last_player.tiles.must_equal(copy_last_player_tiles)
end
end # play(word)

describe "#total_score" do
it "returns the sum of scores of played words" do
new_player.plays = ['CAT', 'DOG', 'COW']
new_player.total_score.must_equal(18)
end
end

describe "#won?" do
it "If the player has over 100 points, returns true" do
winner = Scrabble::Player.new("Karen")
winner.total_score = 150
winner.won?.must_equal(true)
end

it "If the player has 100 points or less, returns false" do
loser = Scrabble::Player.new("Samba")
loser.total_score = 80
loser.won?.must_equal(false)
end
end

describe "#highest_scoring_word" do
it "should return the highest scoring word from the @plays instance variable" do
score_player = Scrabble::Player.new("Jeremy")
score_player.plays = ['CAT', 'QQQQQJ', 'AAAAAAG']
score_player.highest_scoring_word.must_equal('AAAAAAG')
end

it "should return an argument error if no word has been played" do
# i.e. @plays array is empty
nil_player = Scrabble::Player.new("Jeremy")
nil_player.highest_scoring_word.must_equal(nil)
# proc {nil_player.highest_scoring_word}.must_raise(ArgumentError)
# @todo decide if we want to handle error or throw ArgumentError
# STUCK AT LINE 67 OF SCORING.RB
end
end # highest_scoring_word

describe "#highest_word_score" do
it "should return the highest_scoring_word score" do
more_player = Scrabble::Player.new("Dianne")
more_player.plays = ['CAT', 'COW', 'LIONESS']
more_player.highest_word_score.must_equal(57)
end
end

describe "#draw_tiles(tile_bag)" do
it "should raise an error if the parameter input is not an object of the TileBag class" do
proc { new_player.draw_tiles(123) }.must_raise(ArgumentError)
end

it "ensure the @tiles array has 7 letters after drawing tiles" do
yeni = Scrabble::Player.new("Yeni")
yenis_tile_bag = Scrabble::TileBag.new
yeni.draw_tiles(yenis_tile_bag)
yeni.tiles.length.must_equal(7)
end

it "should mutate the original @tiles array after drawing tiles" do
kelly = Scrabble::Player.new("Kelly")
kellys_tile_bag = Scrabble::TileBag.new
original_tiles = kelly.tiles.clone
kelly.draw_tiles(kellys_tile_bag)
kelly.tiles.wont_equal(original_tiles)
end
end
end
Loading