j_studio_game 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +1 -0
- data/README.txt +17 -0
- data/bin/game +40 -0
- data/bin/players.csv +3 -0
- data/bin/sideshow.csv +5 -0
- data/lib/auditable.rb +7 -0
- data/lib/berserk_player_class.rb +36 -0
- data/lib/clumsy_player_class.rb +32 -0
- data/lib/die.rb +26 -0
- data/lib/game_class.rb +121 -0
- data/lib/game_turn.rb +32 -0
- data/lib/loaded_die.rb +22 -0
- data/lib/playable_module.rb +18 -0
- data/lib/player_class.rb +61 -0
- data/lib/treasure_trove.rb +20 -0
- data/spec/berserk_player_spec.rb +32 -0
- data/spec/clumsy_player_spec.rb +34 -0
- data/spec/game_spec.rb +63 -0
- data/spec/player_spec.rb +139 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/treasure_trove_spec.rb +62 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e324e4bc2c5f5801d1b97bb0cf4ac6b2f8d6f965acde0d1a597d0e9668838aec
|
4
|
+
data.tar.gz: 5e84ec2a489fb3b6318945dff4b1089b39a286551e552fe8c32389c6ff3b506a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 73d84d9f020fb59f3497d60befc532bb47c4c99e388b365b1073e3339eaae5ae7663a6c5369b534dfab7a0bea5fc921cc11fdd300b6eb31c989ce95dd3773a8b
|
7
|
+
data.tar.gz: de28412ac8315b8c13e2427b7af5b1d3771a51df2c7c4621d7a2ce7c15cd7854552c2cc49cc44c834829aa498dcf78bf195a16ccf3b9bb3b113ceeab4c38b8a5
|
data/LICENSE.txt
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
|
data/README.txt
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
BASIC INSTRUCTIONS
|
2
|
+
|
3
|
+
INSTALLATION EXAMPLE (For older version of 1.0.1):
|
4
|
+
gem install jamies_studio_game-1.0.1.gem
|
5
|
+
|
6
|
+
TO RUN DEFAULT CSV SHEET PLAYERS:
|
7
|
+
ruby bin/game.rb
|
8
|
+
|
9
|
+
TO RUN A CUSTOM CSV FILE:
|
10
|
+
You can also drop your own game csv file with the name and health of players.
|
11
|
+
Have a csv file in your current directory.
|
12
|
+
FORMATTING
|
13
|
+
Column 1 for names and column 2 initial health values (integers only)
|
14
|
+
|
15
|
+
Call your own CSV file from cmd line like this:
|
16
|
+
ruby bin/game.rb yourfile.csv
|
17
|
+
Try running ruby bin/game.rb bin/sideshow.csv
|
data/bin/game
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative '../lib/game_class'
|
3
|
+
require_relative '../lib/clumsy_player_class'
|
4
|
+
require_relative '../lib/berserk_player_class'
|
5
|
+
|
6
|
+
# ************************************** Final Code ***************************************
|
7
|
+
#type 'ruby bin/game.rb' to start a game
|
8
|
+
|
9
|
+
game = StudioGame::Game.new("Three (Or More) Stooges")
|
10
|
+
# knuckleheads.load_players("players.csv")
|
11
|
+
# knuckleheads.load_players(ARGV.shift || "players.csv")
|
12
|
+
default_player_file = File.join(File.dirname(__FILE__), 'players.csv')
|
13
|
+
|
14
|
+
the_file_option = (ARGV.shift || default_player_file) #extracting the or statement to be its own variable
|
15
|
+
game.load_players(the_file_option) #subbing in the variable here
|
16
|
+
|
17
|
+
if the_file_option == default_player_file # if the variable takes the form of the default file (no user csv file is specified)
|
18
|
+
klutz = StudioGame::ClumsyPlayer.new("klutz", 105) #then a clumsy player "Klutz" will be added
|
19
|
+
game.add_player(klutz)
|
20
|
+
|
21
|
+
berserker = StudioGame::BerserkPlayer.new("berserker", 50) #and a berserker player "Klutz" will be added
|
22
|
+
game.add_player(berserker)
|
23
|
+
else # otherwise (if the user specifies their own csv file, berserker and klutz players will not interfere/be added!!)
|
24
|
+
end
|
25
|
+
|
26
|
+
loop do
|
27
|
+
puts "\nHow many rounds? (Type 'quit' or 'exit' to end the game.)"
|
28
|
+
answer = gets.chomp.downcase #gets takes user input from cmd (must run from cmd now). chomp removes line break caused by ENTER key.
|
29
|
+
case answer
|
30
|
+
when /^\d+$/
|
31
|
+
game.play(answer.to_i) #the line that starts the game (altered 11th commit)
|
32
|
+
when 'quit', 'exit', 'stop'
|
33
|
+
game.print_stats #the line that prints the stats (altered 11th commit)
|
34
|
+
break
|
35
|
+
else
|
36
|
+
puts "Please enter a number or type 'quit' to end the game."
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
game.save_high_scores #prints high scores to a .txt file
|
data/bin/players.csv
ADDED
data/bin/sideshow.csv
ADDED
data/lib/auditable.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative 'player_class'
|
2
|
+
module StudioGame
|
3
|
+
class BerserkPlayer < Player
|
4
|
+
def initialize(name, health=100) #overwrites the default method when Player.new is created! Default health is now 100.
|
5
|
+
super(name, health)
|
6
|
+
@w00t_count = 0
|
7
|
+
end
|
8
|
+
|
9
|
+
def berserk?
|
10
|
+
@w00t_count > 5
|
11
|
+
end
|
12
|
+
|
13
|
+
def w00t
|
14
|
+
super #kind of like "apply all" here where super calls and applies the whole regular Player w00t method.
|
15
|
+
@w00t_count +=1 #additional w00t method instructions specific to berserker subclass.
|
16
|
+
puts "#{@name} is berserk!" if berserk? #fancy if statement (prints a warning when statement is true!)
|
17
|
+
end
|
18
|
+
|
19
|
+
def blam
|
20
|
+
berserk? ? w00t : super #ternary operator rocks. woot if berserk is true, super if false
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
# let's get some visible output on how a BerserkPlayer behaves at this point
|
25
|
+
# if __FILE__ == $0
|
26
|
+
# berserker = BerserkPlayer.new("berserker", 50)
|
27
|
+
# 6.times { berserker.w00t }
|
28
|
+
# end
|
29
|
+
|
30
|
+
if __FILE__ == $0
|
31
|
+
berserker = BerserkPlayer.new("berserker", 50)
|
32
|
+
6.times { berserker.w00t }
|
33
|
+
2.times { berserker.blam }
|
34
|
+
puts berserker.health
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require_relative 'player_class'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
class ClumsyPlayer < Player
|
5
|
+
def found_treasure(treasure)
|
6
|
+
# points = treasure.points / 2.0 #the only difference that makes someone clumsy is that they get half the points
|
7
|
+
# @found_treasures[treasure.name] += treasure.points
|
8
|
+
# puts "#{@name} found a #{treasure.name} worth #{treasure.points} points."
|
9
|
+
|
10
|
+
damaged_treasure = Treasure.new(treasure.name, treasure.points / 2.0) #critical that this yields a floating point result/value!
|
11
|
+
super(damaged_treasure)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# let's get some visible output on how a ClumsyPlayer behaves at this point.
|
16
|
+
if __FILE__ == $0
|
17
|
+
clumsy = ClumsyPlayer.new("klutz")
|
18
|
+
|
19
|
+
hammer = Treasure.new(:hammer, 50)
|
20
|
+
clumsy.found_treasure(hammer)
|
21
|
+
clumsy.found_treasure(hammer)
|
22
|
+
clumsy.found_treasure(hammer)
|
23
|
+
|
24
|
+
crowbar = Treasure.new(:crowbar, 400)
|
25
|
+
clumsy.found_treasure(crowbar)
|
26
|
+
|
27
|
+
clumsy.each_found_treasure do |treasure|
|
28
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
29
|
+
end
|
30
|
+
puts "#{clumsy.points} grand total points"
|
31
|
+
end
|
32
|
+
end
|
data/lib/die.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'auditable'
|
2
|
+
module StudioGame
|
3
|
+
class Die
|
4
|
+
include Auditable
|
5
|
+
attr_reader :number #makes die remember the number it rolled
|
6
|
+
|
7
|
+
def roll
|
8
|
+
@number = rand(1..6)
|
9
|
+
audit
|
10
|
+
@number #Lastly, return the @number value as the last expression in the method since the game expects roll to return a number.
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
#my own code showing that the die contains a readable attribute, its number!
|
17
|
+
#all you have to do is tack on ".number" for the number of the die to come up.
|
18
|
+
#note that the number attribute is stored in / sourced from the @number instance variable.
|
19
|
+
|
20
|
+
if __FILE__ == $0
|
21
|
+
die = Die.new()
|
22
|
+
die.roll # displays "Rolled a # (Die)" because ROLL calls the audit as defined within the roll method
|
23
|
+
# note that this die.roll is also testing that the audit method (mixin) from the Auditable module works.
|
24
|
+
puts "\nThis is the number: #{die.number}" #with the die object, you can call the readable number attribute with .number
|
25
|
+
puts "This is the class: #{die.class}" #with the die object, you can call the object class with .class
|
26
|
+
end
|
data/lib/game_class.rb
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
# ****************** GAME CLASS ******************
|
2
|
+
require_relative 'player_class'
|
3
|
+
require_relative 'die'
|
4
|
+
require_relative 'game_turn'
|
5
|
+
require_relative 'treasure_trove'
|
6
|
+
require 'csv'
|
7
|
+
|
8
|
+
module StudioGame
|
9
|
+
class Game
|
10
|
+
attr_reader :title
|
11
|
+
|
12
|
+
def initialize(title)
|
13
|
+
@title = title
|
14
|
+
@players = []
|
15
|
+
end
|
16
|
+
|
17
|
+
# def load_players(from_file)
|
18
|
+
# File.readlines(from_file).each do |line|
|
19
|
+
# name, health = line.split(',')
|
20
|
+
# player = Player.new(name, Integer(health))
|
21
|
+
# add_player(player)
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
|
25
|
+
# *** easier approach than the solution above using Ruby's CSV library (MUST use require 'csv' at the top) ***
|
26
|
+
def load_players(from_file)
|
27
|
+
CSV.foreach(from_file) do |row|
|
28
|
+
player = Player.new(row[0], row[1].to_i) # immediately sends row[0] and row[1] values to local variables name and health (line 8 of player_class.rb)
|
29
|
+
add_player(player) # adds to the player array (stored in local variable @players)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def high_score_entry(player)
|
34
|
+
formatted_name = player.name.ljust(20, '.')
|
35
|
+
"#{formatted_name} #{player.score}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def save_high_scores(to_file="high_scores.txt")
|
39
|
+
File.open(to_file, "w") do |file|
|
40
|
+
file.puts Time.new.strftime("File updated/created on %m/%d/%Y at %I:%M %p.") #me printing the time!
|
41
|
+
file.puts "\n#{@title} High Scores:"
|
42
|
+
@players.sort.each do |player|
|
43
|
+
file.puts high_score_entry(player)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_player(a_player)
|
49
|
+
@players.push(a_player) #use @players since @players refers to the array u created in the initialize method
|
50
|
+
end
|
51
|
+
|
52
|
+
def total_points
|
53
|
+
@players.reduce(0) { |sum, player| sum + player.points }
|
54
|
+
end
|
55
|
+
|
56
|
+
def play(rounds)
|
57
|
+
puts "There are #{@players.size} players in the game '#{@title}': "
|
58
|
+
|
59
|
+
@players.each do |player|
|
60
|
+
puts player
|
61
|
+
end
|
62
|
+
|
63
|
+
treasures = TreasureTrove::TREASURES
|
64
|
+
puts "\nThere are #{treasures.size} treasures to be found:"
|
65
|
+
|
66
|
+
treasures.each do |treasure|
|
67
|
+
puts "A #{treasure.name} is worth #{treasure.points} points."
|
68
|
+
end
|
69
|
+
|
70
|
+
1.upto(rounds) do |round|
|
71
|
+
puts "\nRound #{round}:"
|
72
|
+
@players.each do |player|
|
73
|
+
GameTurn.take_turn(player)
|
74
|
+
puts player
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def print_name_and_health(player)
|
80
|
+
puts "#{player.name} (#{player.health})"
|
81
|
+
end
|
82
|
+
|
83
|
+
def print_stats
|
84
|
+
strong_players, wimpy_players = @players.partition { |player| player.strong? }
|
85
|
+
|
86
|
+
puts "\n#{title} Statistics:"
|
87
|
+
puts "\n#{strong_players.size} strong players:"
|
88
|
+
strong_players.each do |player|
|
89
|
+
print_name_and_health(player)
|
90
|
+
end
|
91
|
+
|
92
|
+
puts "\n#{wimpy_players.size} wimpy players:"
|
93
|
+
wimpy_players.each do |player|
|
94
|
+
print_name_and_health(player)
|
95
|
+
end
|
96
|
+
|
97
|
+
sorted_players = @players.sort{ |a, b| b.score <=> a.score}
|
98
|
+
puts "\n#{title} High Scores:"
|
99
|
+
sorted_players.each do |player|
|
100
|
+
puts high_score_entry(player)
|
101
|
+
end
|
102
|
+
puts "\n(High scores have been saved to 'high_scores.txt')"
|
103
|
+
|
104
|
+
@players.each do |player|
|
105
|
+
puts "\n#{player.name}'s point totals:"
|
106
|
+
puts "#{player.points} grand total points"
|
107
|
+
end
|
108
|
+
|
109
|
+
puts "\n#{total_points} total points from treasures found."
|
110
|
+
|
111
|
+
@players.sort.each do |player|
|
112
|
+
puts "\n#{player.name}'s point totals:"
|
113
|
+
player.each_found_treasure do |treasure|
|
114
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
115
|
+
end
|
116
|
+
puts "#{player.points} grand total points"
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/lib/game_turn.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# ****************** MODULE GAMETURN ************************
|
2
|
+
require_relative 'player_class'
|
3
|
+
require_relative 'die'
|
4
|
+
require_relative 'treasure_trove'
|
5
|
+
require_relative 'loaded_die'
|
6
|
+
|
7
|
+
module StudioGame
|
8
|
+
module GameTurn
|
9
|
+
def self.take_turn(player)
|
10
|
+
die = Die.new #replace Die with LoadedDie to see the loaded die exposed by its class! (since audit was implemented in the roll method)
|
11
|
+
case die.roll
|
12
|
+
when 1..2
|
13
|
+
player.blam
|
14
|
+
when 3..4
|
15
|
+
puts "#{player.name} was skipped."
|
16
|
+
else
|
17
|
+
player.w00t
|
18
|
+
end
|
19
|
+
treasure = TreasureTrove.random
|
20
|
+
player.found_treasure(treasure)
|
21
|
+
# puts "#{player.name} found a #{treasure.name} worth #{treasure.points} points."
|
22
|
+
end
|
23
|
+
|
24
|
+
# def self.take_turn(player)
|
25
|
+
# # code to roll die and w00t or blam
|
26
|
+
|
27
|
+
# treasure = TreasureTrove.random
|
28
|
+
# player.found_treasure(treasure)
|
29
|
+
# end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
data/lib/loaded_die.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# ********** LOADED DIE ******************
|
2
|
+
require_relative 'auditable'
|
3
|
+
module StudioGame
|
4
|
+
class LoadedDie
|
5
|
+
include Auditable
|
6
|
+
attr_reader :number
|
7
|
+
|
8
|
+
def roll
|
9
|
+
numbers = [1, 1, 2, 5, 6, 6]
|
10
|
+
@number = numbers.sample
|
11
|
+
audit
|
12
|
+
@number # Lastly, return the @number value as the last expression in the method since the game expects roll to return a number.
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
if __FILE__ == $0
|
17
|
+
die = LoadedDie.new()
|
18
|
+
die.roll # displays "Rolled a # (Die)" because ROLL calls the audit as defined within the roll method
|
19
|
+
# note that this die.roll is also testing that the audit method (mixin) from the Auditable module works.
|
20
|
+
puts "\nThis is the number: #{die.number}" #with the die object, you can call the readable number attribute with .number
|
21
|
+
puts "This is the class: #{die.class}" #with the die object, you can call the object class with .class
|
22
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
module StudioGame
|
3
|
+
module Playable #needs to write to health and read name
|
4
|
+
def blam
|
5
|
+
self.health -= 10 # the .self is REQUIRED on writable attributes (health)
|
6
|
+
puts "#{name} got blammed!" # the .self is optional on readable attributes (name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def w00t
|
10
|
+
self.health += 15
|
11
|
+
puts "#{name} got w00ted!"
|
12
|
+
end
|
13
|
+
|
14
|
+
def strong?
|
15
|
+
health > 100
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/player_class.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative 'treasure_trove'
|
2
|
+
require_relative 'playable_module'
|
3
|
+
|
4
|
+
module StudioGame
|
5
|
+
class Player
|
6
|
+
attr_accessor :health
|
7
|
+
attr_accessor :name
|
8
|
+
|
9
|
+
# or combine into one line like this...... attr_accessor :name, :health
|
10
|
+
|
11
|
+
include Playable
|
12
|
+
|
13
|
+
def initialize(name, health=100) #overwrites the default method when Player.new is created! Default health is now 100.
|
14
|
+
@name = name.capitalize
|
15
|
+
@health = health
|
16
|
+
@found_treasures = Hash.new(0)
|
17
|
+
end
|
18
|
+
|
19
|
+
def found_treasure(treasure)
|
20
|
+
@found_treasures[treasure.name] += treasure.points
|
21
|
+
puts "#{@name} found a #{treasure.name} worth #{treasure.points} points."
|
22
|
+
puts "#{@name}'s treasures: #{@found_treasures}"
|
23
|
+
end
|
24
|
+
# POINTS *********************
|
25
|
+
def points
|
26
|
+
@found_treasures.values.reduce(0, :+)
|
27
|
+
end
|
28
|
+
# SCORE *********************
|
29
|
+
def score
|
30
|
+
points + @health
|
31
|
+
end
|
32
|
+
|
33
|
+
def name=(new_name)
|
34
|
+
@name = new_name.capitalize
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s #to_s overwrites/defines the default method for PUTS.
|
38
|
+
"I'm #{@name} with health = #{@health}, points = #{points}, and score = #{score}."
|
39
|
+
end
|
40
|
+
|
41
|
+
def <=>(other) #this overrides default for whenever the compare <=> operator is used on player class object.
|
42
|
+
other.score <=> score
|
43
|
+
end
|
44
|
+
|
45
|
+
def each_found_treasure
|
46
|
+
@found_treasures.each do |name, points|
|
47
|
+
yield Treasure.new(name, points)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
if __FILE__ == $0
|
54
|
+
player = Player.new("moe")
|
55
|
+
puts player.name
|
56
|
+
puts player.health
|
57
|
+
player.w00t
|
58
|
+
puts player.health
|
59
|
+
player.blam
|
60
|
+
puts player.health
|
61
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
module StudioGame
|
3
|
+
Treasure = Struct.new(:name, :points)
|
4
|
+
|
5
|
+
module TreasureTrove
|
6
|
+
TREASURES = [
|
7
|
+
Treasure.new(:pie, 5),
|
8
|
+
Treasure.new(:bottle, 25),
|
9
|
+
Treasure.new(:hammer, 50),
|
10
|
+
Treasure.new(:skillet, 100),
|
11
|
+
Treasure.new(:broomstick, 200), #dont forget these commas after
|
12
|
+
Treasure.new(:crowbar, 400)
|
13
|
+
]
|
14
|
+
|
15
|
+
def self.random
|
16
|
+
TREASURES.sample
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'berserk_player_class'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
|
5
|
+
describe BerserkPlayer do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@ih = 50 #it was at initial_health not ih
|
9
|
+
@player = BerserkPlayer.new("berserker", @ih)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "does not go berserk when w00ted up to 5 times" do
|
13
|
+
1.upto(5) { @player.w00t }
|
14
|
+
|
15
|
+
@player.berserk?.should be_falsey #correct syntax 4 rspec 3.0
|
16
|
+
end
|
17
|
+
|
18
|
+
it "goes berserk when w00ted more than 5 times" do
|
19
|
+
1.upto(6) { @player.w00t }
|
20
|
+
|
21
|
+
@player.berserk?.should be_truthy #correct syntax 4 rspec 3.0
|
22
|
+
end
|
23
|
+
|
24
|
+
it "gets w00ted instead of blammed when it's gone berserk" do
|
25
|
+
1.upto(6) { @player.w00t } #6 woots
|
26
|
+
1.upto(2) { @player.blam } #2 blams
|
27
|
+
|
28
|
+
@player.health.should == @ih + (8 * 15)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'clumsy_player_class'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
|
5
|
+
describe ClumsyPlayer do
|
6
|
+
before do
|
7
|
+
@player = ClumsyPlayer.new("klutz")
|
8
|
+
end
|
9
|
+
#Upon creation and given found three hammers, one crowbar, point total should be 275.
|
10
|
+
it "only gets half the point value for each treasure" do
|
11
|
+
@player.points.should == 0
|
12
|
+
|
13
|
+
hammer = Treasure.new(:hammer, 50)
|
14
|
+
@player.found_treasure(hammer)
|
15
|
+
@player.found_treasure(hammer)
|
16
|
+
@player.found_treasure(hammer)
|
17
|
+
|
18
|
+
@player.points.should == 75
|
19
|
+
|
20
|
+
crowbar = Treasure.new(:crowbar, 400)
|
21
|
+
@player.found_treasure(crowbar)
|
22
|
+
|
23
|
+
@player.points.should == 275
|
24
|
+
|
25
|
+
yielded = []
|
26
|
+
@player.each_found_treasure do |treasure|
|
27
|
+
yielded << treasure #append?
|
28
|
+
end
|
29
|
+
|
30
|
+
yielded.should == [Treasure.new(:hammer, 75), Treasure.new(:crowbar, 200)]
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
data/spec/game_spec.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'game_class'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
describe Game do
|
5
|
+
before do
|
6
|
+
@game = Game.new("Knuckleheads")
|
7
|
+
|
8
|
+
@ih = 100 # literally my only mistake lmao
|
9
|
+
@player = Player.new("moe", @ih)
|
10
|
+
|
11
|
+
@game.add_player(@player)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "w00t for high die roll" do
|
15
|
+
Die.any_instance.stub(:roll).and_return(5)
|
16
|
+
@game.play(2)
|
17
|
+
@player.health.should == @ih + (15 * 2)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "skip for mid die roll" do
|
21
|
+
Die.any_instance.stub(:roll).and_return(3)
|
22
|
+
@game.play(2)
|
23
|
+
@player.health.should == @ih
|
24
|
+
end
|
25
|
+
|
26
|
+
it "blams for low die roll" do
|
27
|
+
Die.any_instance.stub(:roll).and_return(1)
|
28
|
+
@game.play(2)
|
29
|
+
@player.health.should == (@ih - 10 * 2)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "assigns a treasure for points during a player's turn" do
|
33
|
+
game = Game.new("Knuckleheads")
|
34
|
+
player = Player.new("moe")
|
35
|
+
|
36
|
+
game.add_player(player)
|
37
|
+
|
38
|
+
game.play(1)
|
39
|
+
|
40
|
+
player.points.should_not be_zero
|
41
|
+
|
42
|
+
# or use alternate expectation syntax:
|
43
|
+
# expect(player.points).not_to be_zero
|
44
|
+
end
|
45
|
+
|
46
|
+
it "computes total points as the sum of all player points" do
|
47
|
+
game = Game.new("Knuckleheads")
|
48
|
+
|
49
|
+
player1 = Player.new("moe")
|
50
|
+
player2 = Player.new("larry")
|
51
|
+
|
52
|
+
game.add_player(player1)
|
53
|
+
game.add_player(player2)
|
54
|
+
|
55
|
+
player1.found_treasure(Treasure.new(:hammer, 50))
|
56
|
+
player1.found_treasure(Treasure.new(:hammer, 50))
|
57
|
+
player2.found_treasure(Treasure.new(:crowbar, 400))
|
58
|
+
|
59
|
+
game.total_points.should == 500
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
data/spec/player_spec.rb
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'player_class'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'treasure_trove'
|
4
|
+
|
5
|
+
module StudioGame
|
6
|
+
describe Player do
|
7
|
+
before do
|
8
|
+
@ih = 150
|
9
|
+
@player = Player.new("larry", @ih)
|
10
|
+
end
|
11
|
+
# examples go here
|
12
|
+
it "has a capitalized name" do
|
13
|
+
|
14
|
+
@player.name.should == "Larry"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has an initial health" do
|
18
|
+
|
19
|
+
@player.health.should == 150
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
it "has a string representation" do
|
24
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
25
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
26
|
+
|
27
|
+
# @player.to_s.should == "I'm Larry with a health of 150 and a score of 250." #<<< this is the old printout format
|
28
|
+
@player.to_s.should == "I'm Larry with health = 150, points = 100, and score = 250."
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
it "computes a score as the sum of its health and length of name" do
|
33
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
34
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
35
|
+
|
36
|
+
@player.score.should == (250) #altered from 155 to 250 bc the way score has been defined was updated (health of 150 plus two hammers: 100points)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "increases health by 15 when w00ted" do
|
40
|
+
@ih = 150
|
41
|
+
@player.w00t
|
42
|
+
|
43
|
+
@player.health.should == (@ih + 15)
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
it "decreases health by 10 when blammed" do
|
48
|
+
@ih = 150
|
49
|
+
@player.blam
|
50
|
+
|
51
|
+
@player.health.should == (@ih - 10)
|
52
|
+
end
|
53
|
+
|
54
|
+
context "with health greater than 100" do
|
55
|
+
before do
|
56
|
+
@player = Player.new("larry", 150)
|
57
|
+
end
|
58
|
+
it "is strong" do
|
59
|
+
@player.should be_strong
|
60
|
+
end
|
61
|
+
end
|
62
|
+
context "with health less than / equal to 100" do
|
63
|
+
before do
|
64
|
+
@player = Player.new("larry", 100)
|
65
|
+
end
|
66
|
+
it "is wimpy" do
|
67
|
+
@player.should_not be_strong
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
context "in a collection of players" do
|
72
|
+
before do
|
73
|
+
@player1 = Player.new("moe", 100)
|
74
|
+
@player2 = Player.new("larry", 200)
|
75
|
+
@player3 = Player.new("curly", 300)
|
76
|
+
|
77
|
+
@players = [@player1, @player2, @player3]
|
78
|
+
end
|
79
|
+
|
80
|
+
it "is sorted by decreasing score" do
|
81
|
+
@players.sort.should == [@player3, @player2, @player1]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "computes points as the sum of all treasure points" do
|
86
|
+
@player.points.should == 0
|
87
|
+
|
88
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
89
|
+
|
90
|
+
@player.points.should == 50
|
91
|
+
|
92
|
+
@player.found_treasure(Treasure.new(:crowbar, 400))
|
93
|
+
|
94
|
+
@player.points.should == 450
|
95
|
+
|
96
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
97
|
+
|
98
|
+
@player.points.should == 500
|
99
|
+
end
|
100
|
+
|
101
|
+
it "computes a score as the sum of its health and points" do
|
102
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
103
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
104
|
+
|
105
|
+
@player.score.should == 250
|
106
|
+
end
|
107
|
+
|
108
|
+
it "yields each found treasure and its total points" do
|
109
|
+
@player.found_treasure(Treasure.new(:skillet, 100))
|
110
|
+
@player.found_treasure(Treasure.new(:skillet, 100))
|
111
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
112
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
113
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
114
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
115
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
116
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
117
|
+
|
118
|
+
yielded = []
|
119
|
+
@player.each_found_treasure do |treasure|
|
120
|
+
yielded << treasure
|
121
|
+
end
|
122
|
+
|
123
|
+
yielded.should == [
|
124
|
+
Treasure.new(:skillet, 200),
|
125
|
+
Treasure.new(:hammer, 50),
|
126
|
+
Treasure.new(:bottle, 25)
|
127
|
+
]
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
# expect(player.name).to eq("Larry") <<<<<< the new expectation line syntax
|
134
|
+
|
135
|
+
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
# ************** COPIED SPEC ************************
|
2
|
+
require 'treasure_trove'
|
3
|
+
|
4
|
+
module StudioGame
|
5
|
+
describe Treasure do
|
6
|
+
|
7
|
+
before do
|
8
|
+
@treasure = Treasure.new(:hammer, 50)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "has a name attribute" do
|
12
|
+
@treasure.name.should == :hammer
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has a points attribute" do
|
16
|
+
@treasure.points.should == 50
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module StudioGame
|
23
|
+
describe TreasureTrove do
|
24
|
+
|
25
|
+
it "has six treasures" do
|
26
|
+
TreasureTrove::TREASURES.size.should == 6
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has a pie worth 5 points" do
|
30
|
+
TreasureTrove::TREASURES[0].should == Treasure.new(:pie, 5)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "has a bottle worth 25 points" do
|
34
|
+
TreasureTrove::TREASURES[1].should == Treasure.new(:bottle, 25)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "has a hammer worth 50 points" do
|
38
|
+
TreasureTrove::TREASURES[2].should == Treasure.new(:hammer, 50)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has a skillet worth 100 points" do
|
42
|
+
TreasureTrove::TREASURES[3].should == Treasure.new(:skillet, 100)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has a broomstick worth 200 points" do
|
46
|
+
TreasureTrove::TREASURES[4].should == Treasure.new(:broomstick, 200)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "has a crowbar worth 400 points" do
|
50
|
+
TreasureTrove::TREASURES[5].should == Treasure.new(:crowbar, 400)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns a random treasure" do
|
54
|
+
treasure = TreasureTrove.random
|
55
|
+
|
56
|
+
TreasureTrove::TREASURES.should include(treasure)
|
57
|
+
|
58
|
+
# or use alternate expectation syntax:
|
59
|
+
# expect(TreasureTrove::TREASURES).to include(treasure)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: j_studio_game
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jamie Clark
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-06-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.8'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.8.0
|
23
|
+
type: :development
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '2.8'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 2.8.0
|
33
|
+
description: "BASIC INSTRUCTIONS \n\nINSTALLATION EXAMPLE (For older version of 1.0.1):\ngem
|
34
|
+
install jamies_studio_game-1.0.1.gem\n\nTO RUN DEFAULT CSV SHEET PLAYERS:\nruby
|
35
|
+
bin/game.rb\n\nTO RUN A CUSTOM CSV FILE:\nYou can also drop your own game csv file
|
36
|
+
with the name and health of players.\nHave a csv file in your current directory.
|
37
|
+
\nFORMATTING\nColumn 1 for names and column 2 initial health values (integers only)\n\nCall
|
38
|
+
your own CSV file from cmd line like this:\nruby bin/game.rb yourfile.csv\nTry running
|
39
|
+
ruby bin/game.rb bin/sideshow.csv\n"
|
40
|
+
email: clarkcjamie@gmail.com
|
41
|
+
executables:
|
42
|
+
- game
|
43
|
+
extensions: []
|
44
|
+
extra_rdoc_files: []
|
45
|
+
files:
|
46
|
+
- LICENSE.txt
|
47
|
+
- README.txt
|
48
|
+
- bin/game
|
49
|
+
- bin/players.csv
|
50
|
+
- bin/sideshow.csv
|
51
|
+
- lib/auditable.rb
|
52
|
+
- lib/berserk_player_class.rb
|
53
|
+
- lib/clumsy_player_class.rb
|
54
|
+
- lib/die.rb
|
55
|
+
- lib/game_class.rb
|
56
|
+
- lib/game_turn.rb
|
57
|
+
- lib/loaded_die.rb
|
58
|
+
- lib/playable_module.rb
|
59
|
+
- lib/player_class.rb
|
60
|
+
- lib/treasure_trove.rb
|
61
|
+
- spec/berserk_player_spec.rb
|
62
|
+
- spec/clumsy_player_spec.rb
|
63
|
+
- spec/game_spec.rb
|
64
|
+
- spec/player_spec.rb
|
65
|
+
- spec/spec_helper.rb
|
66
|
+
- spec/treasure_trove_spec.rb
|
67
|
+
homepage: http://pragmaticstudio.com
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '1.9'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubygems_version: 3.3.7
|
87
|
+
signing_key:
|
88
|
+
specification_version: 4
|
89
|
+
summary: Text based game with rounds and treasures
|
90
|
+
test_files:
|
91
|
+
- spec/berserk_player_spec.rb
|
92
|
+
- spec/clumsy_player_spec.rb
|
93
|
+
- spec/game_spec.rb
|
94
|
+
- spec/player_spec.rb
|
95
|
+
- spec/spec_helper.rb
|
96
|
+
- spec/treasure_trove_spec.rb
|