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

Suzannah and Guinevere's Scrabble game #15

Open
wants to merge 30 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
793c949
Added folder stucture with Rakefile, spec_helper, test file, and clas…
guineveresaenger Aug 29, 2016
f6c0b2e
Here is our first official red failed test.
sckirk Aug 29, 2016
b3a3409
created a score table hash as a constant--we will comment the constan…
sckirk Aug 29, 2016
e81db03
Added tests for the constant
guineveresaenger Aug 30, 2016
51e70f5
created our score class method and a test that confirms alpha charact…
sckirk Aug 30, 2016
601edbe
Added length testing method, and wrote test for ArgumentError in case…
guineveresaenger Aug 30, 2016
084f57f
Added word test for fox and also implemented scoring functionality.
guineveresaenger Aug 30, 2016
2b0f33a
Successfully tested and wrote code to complete the score class method
sckirk Aug 30, 2016
2b45fbb
began testing brainstorming and writing out highest score class method:
sckirk Aug 30, 2016
f9c4499
Got all the ties out of the scores hash
guineveresaenger Aug 31, 2016
1286d48
completed highest score from class methodthat passes our test choosin…
sckirk Aug 31, 2016
c699adb
All tests pass, but use of hash may affect their validity
guineveresaenger Aug 31, 2016
7bc4830
Used parallel arrays with shared index instead of hash
guineveresaenger Aug 31, 2016
37dda73
We successfully refactored our highest score from array class method …
sckirk Aug 31, 2016
e67ced9
Added Simplecov to spec_helper
guineveresaenger Aug 31, 2016
a16d0f7
Rename scrabble_spec.rb to scoring_spec.rb
sckirk Aug 31, 2016
65687f4
We have created our player_spec file and player class file, complete …
sckirk Aug 31, 2016
6171d31
created a test to check for a play(word) method
sckirk Aug 31, 2016
26b8053
Added edge case tests for total score
guineveresaenger Aug 31, 2016
990dc77
Contains highest score/words methods; cleaned up some tests
guineveresaenger Aug 31, 2016
7991387
All primary requirements met for wave two, added two tests per Kari's…
sckirk Aug 31, 2016
96c2f63
simplified highest score method to remove the winners length array
sckirk Sep 1, 2016
99ef5e7
Used enumerable instead of extra storage array
guineveresaenger Sep 1, 2016
e2109b6
Commented out some bad tests for possible future fix
guineveresaenger Sep 1, 2016
dc31d75
We created three tests and the corresponding code within the initiali…
sckirk Sep 1, 2016
eb004b0
Added tests to complete draw_tiles method
guineveresaenger Sep 1, 2016
cac64bf
wrote tests to create our draw tiles method within the player class--…
sckirk Sep 1, 2016
ea72559
changed ArgumentError tests
guineveresaenger Sep 1, 2016
dae59cc
we started our optionals--seeing if the word played is in the player'…
sckirk Sep 2, 2016
2397ae3
Updating tile removal and valid word check
guineveresaenger 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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
testing_scoring.rb

*.gem
*.rbc
/.config
Expand All @@ -8,6 +10,7 @@
/test/tmp/
/test/version_tmp/
/tmp/
coverage/

## 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
88 changes: 88 additions & 0 deletions player.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
require_relative 'scoring'
require_relative 'tile_bag'

module Scrabble
class Player
attr_reader :name, :plays, :total_score, :tiles

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

def play(word)
if won?
return false
end
# if !valid_word?(word)
# raise ArgumentError.new("Oops, you don't have tiles to play this word--please try another word.")
# return false
# end
result = Scoring.score(word)
@plays << word
@total_score += result
remove_tiles(word)
return result
end

def valid_word?(word)
temporary_tiles = @tiles.clone
word.chars.each do |ch|
if temporary_tiles.include?(ch)
temporary_tiles.slice!(temporary_tiles.index(ch))

else
return false
end
end
return true
end

def remove_tiles(word)
word.chars.each do |ch|
@tiles.delete(ch)
end
end

def won?
return @total_score > 100
end

def highest_scoring_word
if @plays == []
raise ArgumentError.new("Oops! You haven't played anything")
end
return Scoring.highest_score_from(@plays)
end

def highest_word_score
return Scoring.score(highest_scoring_word)
end

def draw_tiles(bag)
num = 7 - @tiles.length
@tiles.concat(bag.draw_tiles(num))
end
end
end
#
# c = Scrabble::Player.new("me")
#
# print c.tiles.concat(%w(g p e n u i n))
# c.valid_word?("penguin")
#

# current_bag = Scrabble::TileBag.new
# c.draw_tiles(current_bag)
# puts "Here's our tiles #{c.tiles.to_s}."
# c.play("penguin")

# c.play("it")
# puts c.play("do")
#
# puts "foo"
# print c.plays
# puts "bar"
# puts c.highest_scoring_word
79 changes: 79 additions & 0 deletions scoring.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
module Scrabble
class Scoring
SCORE_TABLE = {
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 => ["K"],
8 => %w(J X),
10 => %w(Q Z)
}

def self.valid_length?(word)
return word.length <= 7 && word.length > 0
end

def self.is_alpha?(word)
letter_array(word).each do |ch|
if !("A".."Z").include?(ch)
return false
end
end
return true
end

def self.letter_array(word)
return word.upcase.chars
end

def self.score(word)
if !is_alpha?(word)
raise ArgumentError.new("Oops, letters only please")
end

if !valid_length?(word)
raise ArgumentError.new("Your word must be 1-7 letters.")
end

score = 0
letter_array(word).each do |ch|
SCORE_TABLE.each do |k, v|
if v.include?(ch)
score += k
end
end
end

if letter_array(word).length == 7
score += 50
end
return score
end

def self.highest_score_from(words_array)
scores = []

words_array.each do |word|
scores << score(word)
end

greatest_val = scores.max

winners = words_array.find_all {|word| score(word) == greatest_val}

if winners.length == 1
return winners[0]
else
seven_letters = winners.find {|word| word.length == 7}
if seven_letters != nil
return seven_letters
else
return winners.min_by { |word| word.length}
end
end
end
end
end

# puts Scrabble::Scoring.highest_score_from(["tag", "rats", "tag", "aei"])
137 changes: 137 additions & 0 deletions specs/player_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
require_relative 'spec_helper'
require_relative '../player'

describe Scrabble::Player do
let(:player_test) {Scrabble::Player.new("InuYasha")}
# let(:bag_test) {Scrabble::TileBag.new}
describe "#initialize" do
it "can create a new instance of Player" do
player_test.must_be_instance_of(Scrabble::Player)
end

it "has a name" do
player_test.name.must_equal("InuYasha")
end

it "has a collection of tiles" do
player_test.must_respond_to(:tiles)
end

it "has an array containing words played" do
player_test.must_respond_to(:plays)
end

it "has a total score" do
player_test.must_respond_to(:total_score)
end
end

describe "#won?" do
it "returns false if total score is less than 100" do

player_test.won?.must_equal(false)
end

it "returns false if total score is 100" do
player_test.play("penguin")
player_test.play("check")
player_test.play("week")
player_test.play("it")
player_test.play("hook")

player_test.won?.must_equal(false)

end

it "returns true if total score is greater than 100" do
player_test.play("penguin")
player_test.play("sunrise")
player_test.won?.must_equal(true)

end
end

describe "#valid_word?(word)" do
it "returns false if the word is not in the player's tile set" do
current_bag = Scrabble::TileBag.new
player_test.draw_tiles(current_bag)
player_test.valid_word?("fizz").must_equal(false)
end

it "returns true if the word is in the tile set" do
player_test.tiles.concat(%w(p e n g u i n))
player_test.valid_word?("penguin").must_equal(true)
end


end

describe "#play(word)" do
it "returns the score of a word before winning" do
player_test.play("check").must_equal(16)
end

it "must take one argument" do
proc {player_test.play()}.must_raise(ArgumentError)
end

it "cannot take nil" do
proc {player_test.play(nil)}.must_raise(NoMethodError)
end

it "will append to the plays array the most recently played word" do
player_test.play("check")
player_test.plays.must_equal(["check"])
player_test.play("apple")
player_test.plays.last.must_equal("apple")
player_test.plays.first.must_equal("check")
end

it "will return false if score is over 100" do
player_test.play("penguin")
player_test.play("sunrise")
player_test.play("week").must_equal(false)
end
#
# it "will raise an ArgumentError if the word is invalid, not in the player's tiles" do
# proc {player_test.draw_tiles(Scrabble::TileBag.new)
# player_test.play("fizz")}.must_raise(ArgumentError)
# end
end

describe "#highest_scoring_word" do
it "returns the highest scoring word" do

player_test.play("penguin")
player_test.play("it")
player_test.play("week")
player_test.highest_scoring_word.must_equal("penguin")
end

it "will raise an ArgumentError if no words have been played" do
proc {player_test.highest_scoring_word}.must_raise(ArgumentError)
end

end

describe "#highest_word_score" do
it "returns the highest scoring word's score" do

player_test.play("penguin")
player_test.play("it")
player_test.play("week")
player_test.highest_word_score.must_equal(60)
end

it "will raise an ArgumentError if no words have been played" do
proc {player_test.highest_word_score}.must_raise(ArgumentError)
end
end

describe "#draw_tiles(TileBag)" do
it "must modify the tile array until it's length is 7" do
player_test.draw_tiles(Scrabble::TileBag.new)
player_test.tiles.length.must_equal(7)
end
end
end
65 changes: 65 additions & 0 deletions specs/scoring_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
require_relative 'spec_helper'
require_relative '../scoring'

describe Scrabble::Scoring do
it "has a constant that is a hash" do
Scrabble::Scoring::SCORE_TABLE.must_be_instance_of(Hash)
end
it "letters are assigned to scores" do
Scrabble::Scoring::SCORE_TABLE[10].must_equal(["Q", "Z"])
Scrabble::Scoring::SCORE_TABLE[1].must_equal(%w(A E I O U L N R S T))
Scrabble::Scoring::SCORE_TABLE[2].must_equal(%w(D G))
Scrabble::Scoring::SCORE_TABLE[3].must_equal(%w(B C M P))
Scrabble::Scoring::SCORE_TABLE[4].must_equal(%w(F H V W Y))
Scrabble::Scoring::SCORE_TABLE[5].must_equal(["K"])
Scrabble::Scoring::SCORE_TABLE[8].must_equal(["J", "X"])
end
describe "#initialize" do
let(:score) {Scrabble::Scoring.new}
it "can create a new instance of Scoring" do
score.must_be_instance_of(Scrabble::Scoring)
end
end

describe "score(word)" do
it "ought to throw an Argument Error if the parameter contains non-letters" do
proc { Scrabble::Scoring.score("1")}.must_raise(ArgumentError)
end

it "must throw an ArgumentError if word is not 1-7 characters long" do
proc { Scrabble::Scoring.score("California")}.must_raise(ArgumentError)
proc { Scrabble::Scoring.score("")}.must_raise(ArgumentError)
end

it "must score words properly" do
Scrabble::Scoring.score("fox").must_equal(13)
end

it "will add 50 point bonus for a seven letter word" do
Scrabble::Scoring.score("ghesrso").must_equal(61)
end
end

describe "highest_score_from(words_array)" do
it "will return a String" do
Scrabble::Scoring.highest_score_from(["cat"]).must_be_instance_of(String)
end

it "will return the highest score word if no ties" do
Scrabble::Scoring.highest_score_from(["cat", "soup"]).must_equal("soup")
end

it "will return the word with fewer letters in case of a tied score of words less than seven letters" do
Scrabble::Scoring.highest_score_from(["rats", "tag"]).must_equal("tag")
end

it "returns seven letter word if tied with non-seven-letter word" do
Scrabble::Scoring.highest_score_from(["zqzqzq", "penguin"]).must_equal("penguin")
end

it "returns first word in supplied list in case of tied score and length" do
Scrabble::Scoring.highest_score_from(["tags", "rags", "legs", "at"]).must_equal("tags")
end
end

end
Loading