-
Notifications
You must be signed in to change notification settings - Fork 26
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
Brittany and Maddie #25
base: master
Are you sure you want to change the base?
Changes from all commits
c370171
c126eef
59c89ec
1c34c12
5b871aa
6a53e74
4d0a192
c0b7f76
8eb7063
afa7ae8
63a2c99
7d3276e
15f5ac5
a16c896
43a5bec
f452d97
833fa32
5fbeeb4
00a7a6f
0cd9e18
ffc2370
80e9503
6ea3159
8283fcf
3c29292
27299a0
da40316
6627204
de18f72
6d9183b
1a85d97
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
require_relative "scoring" | ||
|
||
# The constructor for Scrabble::Player should take exactly one argument: the player's name. Instances of the class should respond to the following messages: | ||
# | ||
# #play(word): Adds the input word to the plays Array | ||
# Returns false if player has already won | ||
# Otherwise returns the score of the word | ||
|
||
# #total_score: Returns the sum of scores of played words | ||
# #won?: If the player has over 100 points, returns true, otherwise returns false | ||
# #highest_scoring_word: Returns the highest scoring played word | ||
# #highest_word_score: Returns the highest_scoring_word score | ||
require 'minitest/autorun' | ||
require 'minitest/reporters' | ||
|
||
|
||
module Scrabble | ||
class Player | ||
|
||
attr_accessor :name, :plays, :total_score, :tiles | ||
|
||
def initialize(name) | ||
@name = name | ||
# #name: returns the value of the @name instance variable | ||
@plays = [] | ||
# #plays: returns an Array of the words played by the player | ||
@total_score = 0 | ||
@tiles=[] | ||
|
||
end | ||
|
||
def winner | ||
return @total_score > 100 | ||
end | ||
|
||
def play(word) | ||
if winner == false | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method is supposed to return the score of the word played, or false if the player has already won. |
||
@plays << word | ||
@total_score += Scoring.score(word) | ||
else | ||
return false | ||
end | ||
end | ||
|
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
|
||
|
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,81 @@ | ||
|
||
LETTER_VALUES = { | ||
"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 | ||
} | ||
|
||
module Scrabble | ||
class Scoring | ||
|
||
def self.score(word) | ||
|
||
word = word.upcase | ||
letters = word.split("") | ||
character_check = LETTER_VALUES.keys | ||
values_of_letters = [] | ||
|
||
letters.each do |character| | ||
|
||
# Checking if character input is a valid letter or not | ||
# First part is splitting the hash into an array of the | ||
# key values 'A-Z' and then we are checking if any characters | ||
# are outside that range (This includes blank or nothing). | ||
# If so, automatically return nil | ||
# | ||
# Else, if all the characters are valid letters, take the value | ||
# associated with the key and put that in an array of integers | ||
|
||
|
||
if !character_check.include?(character) || letters.length == 0 || letters.length > 7 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This |
||
return nil | ||
|
||
else | ||
values_of_letters << LETTER_VALUES.fetch(character) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of using values_of_letters << LETTER_VALUES[character] |
||
|
||
end | ||
end | ||
|
||
score = values_of_letters.sum | ||
|
||
return letters.length == 7 ? score + 50 : score | ||
|
||
end | ||
|
||
def self.highest_score_from(array_of_words) | ||
|
||
all_scores = {} | ||
|
||
return nil if array_of_words.length == 0 | ||
|
||
if array_of_words.length == 1 | ||
winning_word = array_of_words.first | ||
|
||
elsif array_of_words.length > 1 | ||
array_of_words.each do |word| | ||
all_scores[word] = score(word) | ||
|
||
max_score_words = all_scores.delete_if { |word, score| score != all_scores.values.max }.keys | ||
|
||
if max_score_words.any? { |word| word.length == 7 } | ||
winning_word = max_score_words.max_by(&:length) | ||
|
||
elsif max_score_words.all? { |word| word.length == word.length } | ||
winning_word = max_score_words[0] | ||
|
||
else | ||
winning_word = max_score_words.min_by(&:length) | ||
|
||
end | ||
end | ||
|
||
return winning_word | ||
|
||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
module Scrabble | ||
class TileBag | ||
#player can see letters | ||
attr_reader :letter_quantity | ||
|
||
|
||
# Creating an instance of letter quantity to be used though class tilebag. | ||
def initialize | ||
@default_set = {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} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a problem with this structure. It gives each letter an equal chance of being drawn despite the fact that there are 2 "M" tiles and 9 "A" tiles. Uh oh! |
||
end | ||
|
||
# Define tiles remaining method to be used in the method for drawing the tiles. | ||
def tiles_remaining | ||
# still not sure why or how this is working. TODO: may take out later | ||
total_num_tiles = @default_set.inject(0) { |letter, letter_quantity| letter += letter_quantity[1] } | ||
p "++++TEST++++" | ||
p total_num_tiles | ||
return total_num_tiles | ||
end | ||
# Define draw tiles, put the tiles into array. | ||
def draw_tiles(num) | ||
player_hand = [] | ||
# array will return tiles to player. Needs much refactoring. | ||
return nil if num > tiles_remaining | ||
#to account for test, returns nil if more tiles are drawn than tiles remain. | ||
while player_hand.length != num | ||
new_tile = rand(@default_set.size) | ||
starting_hand = 0 | ||
|
||
@default_set.each do |letter, letter_quantity| | ||
#Need to continue working on, this is becoming harder to read. TODO: REFACTOR! | ||
# if the amount of tiles drawn(starting at 0) is the same as the amount of new tiles drawn, | ||
if starting_hand == new_tile && letter_quantity != 0 | ||
#if the condition above, and the total tiles isnt 0, add the new tile (letter), to all of the tiles (player_hand array) | ||
# if letter_quantity != 0 | ||
player_hand << letter | ||
#Then subtract the letter from the tilebag, reducing the total amount of tiles by 1, and reducing the letter by one specifically from the letters. | ||
@default_set[letter] = letter_quantity - 1 | ||
else | ||
new_tile = rand(@default_set.size) | ||
|
||
end | ||
#increases the amount of tiles had by player plus one, each time a tile is drawn | ||
starting_hand += 1 | ||
end | ||
end | ||
#returns array of all tiles to player | ||
return player_hand | ||
end | ||
|
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
require 'minitest/autorun' | ||
require 'minitest/reporters' | ||
require 'minitest/skip_dsl' | ||
|
||
require_relative '../lib/player' | ||
|
||
describe 'player' do | ||
before do | ||
@player = Scrabble::Player.new("Maddie") | ||
end | ||
|
||
describe "initialize" do | ||
|
||
it "must be an instance of player class" do | ||
@player.must_be_instance_of Scrabble::Player | ||
end | ||
|
||
it "must returns the value of the @name instance variable" do | ||
@player.name.must_equal "Maddie" | ||
end | ||
|
||
describe "plays" do | ||
#TODO: Need to test for 100 points.. | ||
it "must return an array" do | ||
@player.plays.must_be_kind_of Array | ||
end | ||
end | ||
|
||
|
||
|
||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,54 +9,66 @@ | |
|
||
describe 'Scoring' do | ||
describe 'score' do | ||
it 'correctly scores simple words' do | ||
xit 'correctly scores simple words' do | ||
Scrabble::Scoring.score('dog').must_equal 5 | ||
Scrabble::Scoring.score('cat').must_equal 5 | ||
Scrabble::Scoring.score('pig').must_equal 6 | ||
end | ||
|
||
it 'adds 50 points for a 7-letter word' do | ||
xit 'adds 50 points for a 7-letter word' do | ||
Scrabble::Scoring.score('academy').must_equal 65 | ||
end | ||
|
||
it 'handles all upper- and lower-case letters' do | ||
xit 'handles all upper- and lower-case letters' do | ||
Scrabble::Scoring.score('dog').must_equal 5 | ||
Scrabble::Scoring.score('DOG').must_equal 5 | ||
Scrabble::Scoring.score('DoG').must_equal 5 | ||
end | ||
|
||
it 'returns nil for strings containing bad characters' do | ||
xit 'returns nil for strings containing bad characters' do | ||
Scrabble::Scoring.score('#$%^').must_be_nil | ||
Scrabble::Scoring.score('char^').must_be_nil | ||
Scrabble::Scoring.score(' ').must_be_nil | ||
end | ||
|
||
it 'returns nil for words > 7 letters' do | ||
xit 'returns nil for words > 7 letters' do | ||
Scrabble::Scoring.score('abcdefgh').must_be_nil | ||
end | ||
|
||
it 'returns nil for empty words' do | ||
xit 'returns nil for empty words' do | ||
Scrabble::Scoring.score('').must_be_nil | ||
end | ||
end | ||
|
||
describe 'highest_score_from' do | ||
it 'returns nil if no words were passed' do | ||
array_of_words = [] | ||
Scrabble::Scoring.highest_score_from(array_of_words).must_be_nil | ||
end | ||
|
||
it 'returns the only word in a length-1 array' do | ||
array_of_words = ['one'] | ||
Scrabble::Scoring.highest_score_from(array_of_words).must_equal('one') | ||
end | ||
|
||
it 'returns the highest word if there are two words' do | ||
array_of_words = ["zebra", "zebras"] | ||
Scrabble::Scoring.highest_score_from(array_of_words).must_equal("zebras") | ||
end | ||
|
||
it 'if tied, prefer a word with 7 letters' do | ||
array_of_words = ["ww", "bananas"] | ||
Scrabble::Scoring.highest_score_from(array_of_words).must_equal("bananas") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's also important to vary the order here, just in case order played a role. |
||
end | ||
|
||
it 'if tied and no word has 7 letters, prefers the word with fewer letters' do | ||
array_of_words = ["x", "brasas"] | ||
Scrabble::Scoring.highest_score_from(array_of_words).must_equal("x") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as above |
||
end | ||
|
||
it 'returns the first word of a tie with same letter count' do | ||
array_of_words = ["zebraa", "zebras"] | ||
Scrabble::Scoring.highest_score_from(array_of_words).must_equal("zebraa") | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
require_relative '../lib/tilebag' | ||
#With this, i wont have to retype scrabble::tilebag.new so many times. | ||
describe "tilebag" do | ||
before do | ||
@tile_bag = Scrabble::TileBag.new | ||
end | ||
|
||
describe "tile bag can be created/initialized" do | ||
it "creates instance of tilebag with a collection of all tiles" do | ||
@tile_bag.must_be_instance_of Scrabble::TileBag | ||
end | ||
end | ||
#testing for edge cases of drawing tiles, like drawing more than are in the tilebag, or drawing no tiles. | ||
describe "draw tiles" do | ||
it "returns nil if input is more than tiles in tilebag" do | ||
@tile_bag.draw_tiles(50000).must_be_nil true | ||
end | ||
#in between case | ||
# Making sure drawn tiles will be returned to player | ||
it "returns tiles to user in array" do | ||
@tile_bag.draw_tiles(5).must_be_kind_of Array | ||
end | ||
# Testing for an edge case. | ||
it "returns an empty array of tiles to user" do | ||
@tile_bag.draw_tiles(0).must_be_empty Array | ||
end | ||
end | ||
|
||
describe "tiles left in tilebag" do | ||
it "takes a tile away from total letter quantity and returns num of remaining | ||
tiles in tilebag" do | ||
@tile_bag.draw_tiles(7) | ||
@tile_bag.tiles_remaining.must_equal 91 | ||
end | ||
it "returns the total letter quantity when no tile(s) is drawn" do | ||
@tile_bag.draw_tiles(0) | ||
@tile_bag.tiles_remaining.must_equal 98 | ||
# Wont need to test for edge case if all the tiles are drawn with return of 0, because we already did this in previous draw tile test. | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix your indentation!
Also this method should be named:
won?