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

Brittany and Maddie #25

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c370171
fixed typo
brittanyrjones Feb 20, 2018
c126eef
method name correction
madaleines Feb 20, 2018
59c89ec
Merge branch 'master' of https://github.com/brittanyrjones/Scrabble
madaleines Feb 20, 2018
1c34c12
Starting code for scoring.rb
brittanyrjones Feb 20, 2018
5b871aa
merge
brittanyrjones Feb 20, 2018
6a53e74
Return 5, Pass a test
madaleines Feb 20, 2018
4d0a192
modifying for one test at a time
madaleines Feb 20, 2018
c0b7f76
Notes on how to find score
madaleines Feb 20, 2018
8eb7063
split word in array
madaleines Feb 21, 2018
afa7ae8
correctly scores simple words
madaleines Feb 21, 2018
63a2c99
Add 50 for >7 length
madaleines Feb 21, 2018
7d3276e
Return nil for invalid characters
madaleines Feb 21, 2018
15f5ac5
return nil for word lenght > 7
madaleines Feb 21, 2018
a16c896
highest score, length == 0 & length == 1
madaleines Feb 22, 2018
43a5bec
score two words, return highest one
madaleines Feb 22, 2018
f452d97
Refactored high score with hash to find ties
madaleines Feb 22, 2018
833fa32
refactoring
madaleines Feb 23, 2018
5fbeeb4
if/elsif for tie
madaleines Feb 23, 2018
00a7a6f
wave 1 complete w/ edits
madaleines Feb 23, 2018
0cd9e18
edit wave 1
madaleines Feb 23, 2018
ffc2370
initiate payer.rb
madaleines Feb 23, 2018
80e9503
adding tilebag file, and spec.creating new class tilebag and initiali…
brittanyrjones Feb 23, 2018
6ea3159
creating tilebag
brittanyrjones Feb 23, 2018
8283fcf
added code for tilebag, and tile_bag spec. all tests passing. added p…
brittanyrjones Feb 23, 2018
3c29292
starting player spec, initialized passes test.
brittanyrjones Feb 23, 2018
27299a0
#name: returns the value of the @name instance variable
brittanyrjones Feb 23, 2018
da40316
returns array of words played by player, tests passing
brittanyrjones Feb 23, 2018
6627204
CONSTANT VARIABLE - for letter
madaleines Feb 23, 2018
de18f72
Refactoring
madaleines Feb 23, 2018
6d9183b
change variable names
madaleines Feb 23, 2018
1a85d97
Change var names/refactoring
madaleines Feb 23, 2018
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
50 changes: 50 additions & 0 deletions lib/player.rb
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

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?


def play(word)
if winner == false

Choose a reason for hiding this comment

The 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


Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

highest_word_score???

highest_scoring_word????




end
end
72 changes: 72 additions & 0 deletions lib/scoring.rb
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

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This if doesn't need to be in the loop, at least the checks for the length of the array.

return nil

else
values_of_letters << LETTER_VALUES.fetch(character)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using fetch you could just

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
52 changes: 52 additions & 0 deletions lib/tilebag.rb
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}

Choose a reason for hiding this comment

The 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
32 changes: 32 additions & 0 deletions specs/player_spec.rb
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
24 changes: 18 additions & 6 deletions specs/scoring_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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")

Choose a reason for hiding this comment

The 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")

Choose a reason for hiding this comment

The 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
41 changes: 41 additions & 0 deletions specs/tilebag_spec.rb
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
2 changes: 1 addition & 1 deletion wave-1-game.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def print_score(word)
end

def conclude
highest_word = Scrabble::Scoring.highest_score_from_array(@words)
highest_word = Scrabble::Scoring.highest_score_from(@words)
puts "The final highest scoring word is #{ highest_word }"
end
end
Expand Down