rth-studiogame 0.9
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.
- data/LICENSE +6 -0
- data/README.md +4 -0
- data/bin/players.csv +3 -0
- data/bin/rth-studiogame +39 -0
- data/lib/studio_game/auditable.rb +11 -0
- data/lib/studio_game/berserk_player.rb +51 -0
- data/lib/studio_game/clumsy_player.rb +44 -0
- data/lib/studio_game/game.rb +132 -0
- data/lib/studio_game/game_turn.rb +30 -0
- data/lib/studio_game/high_scores.txt +21 -0
- data/lib/studio_game/loaded_spinner.rb +19 -0
- data/lib/studio_game/moreplayers.csv +6 -0
- data/lib/studio_game/playable.rb +20 -0
- data/lib/studio_game/player.rb +79 -0
- data/lib/studio_game/spinner.rb +23 -0
- data/lib/studio_game/studio_game_initial.rb +55 -0
- data/lib/studio_game/treasure_trove.rb +21 -0
- data/spec/studio_game/berserk_player_spec.rb +32 -0
- data/spec/studio_game/clumsy_player_spec.rb +39 -0
- data/spec/studio_game/game_spec.rb +43 -0
- data/spec/studio_game/game_turn_spec.rb +20 -0
- data/spec/studio_game/player_spec.rb +101 -0
- data/spec/studio_game/spinner_spec.rb +19 -0
- data/spec/studio_game/treasure_trove_spec.rb +58 -0
- metadata +97 -0
data/LICENSE
ADDED
data/README.md
ADDED
data/bin/players.csv
ADDED
data/bin/rth-studiogame
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
require_relative '../lib/studio_game/player'
|
|
3
|
+
require_relative '../lib/studio_game/clumsy_player'
|
|
4
|
+
require_relative '../lib/studio_game/berserk_player'
|
|
5
|
+
require_relative '../lib/studio_game/game'
|
|
6
|
+
|
|
7
|
+
knuckleheads = StudioGame::Game.new("Knuckleheads")
|
|
8
|
+
|
|
9
|
+
playerfile = ARGV.shift
|
|
10
|
+
puts "\nThe program will use the #{playerfile} file.\n"
|
|
11
|
+
|
|
12
|
+
default_player_file = File.join(File.dirname(__FILE__), 'players.csv')
|
|
13
|
+
knuckleheads.load_players(ARGV.shift || default_player_file)
|
|
14
|
+
|
|
15
|
+
player4 = StudioGame::ClumsyPlayer.new("klutz",105,5)
|
|
16
|
+
player5 = StudioGame::BerserkPlayer.new("berserker",50)
|
|
17
|
+
knuckleheads.add_player(player4)
|
|
18
|
+
knuckleheads.add_player(player5)
|
|
19
|
+
|
|
20
|
+
loop do
|
|
21
|
+
puts "\nSTARTING THE GAME...\nHow many rounds do you want to play?"
|
|
22
|
+
answer = gets.chomp.downcase
|
|
23
|
+
|
|
24
|
+
if answer == 'quit' || answer == 'exit'
|
|
25
|
+
break
|
|
26
|
+
elsif answer.to_i > 0
|
|
27
|
+
answer = answer.to_i
|
|
28
|
+
puts "Enjoy your #{answer} rounds!"
|
|
29
|
+
knuckleheads.play(answer)
|
|
30
|
+
else
|
|
31
|
+
puts "Please enter an integer, 'quit', or 'exit'."
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
knuckleheads.show_game_status
|
|
37
|
+
knuckleheads.print_stats
|
|
38
|
+
knuckleheads.print_high_scores
|
|
39
|
+
knuckleheads.save_high_scores
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require_relative 'player'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
|
|
5
|
+
class BerserkPlayer < Player
|
|
6
|
+
|
|
7
|
+
def initialize(name,initial_health)
|
|
8
|
+
super(name,initial_health)
|
|
9
|
+
@w00t_count = 0
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def berserk?
|
|
13
|
+
if @w00t_count > 5
|
|
14
|
+
true
|
|
15
|
+
else
|
|
16
|
+
false
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def w00t
|
|
21
|
+
super
|
|
22
|
+
@w00t_count += 1
|
|
23
|
+
|
|
24
|
+
if self.berserk?
|
|
25
|
+
puts "I am berserk #{self.name} and you are only making it worse!!!\n\n"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def blam
|
|
31
|
+
if self.berserk?
|
|
32
|
+
w00t
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if __FILE__ == $0
|
|
40
|
+
berserker = BerserkPlayer.new("berserker", 50)
|
|
41
|
+
6.times { berserker.w00t }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if __FILE__ == $0
|
|
45
|
+
berserker = BerserkPlayer.new("berserker", 50)
|
|
46
|
+
6.times { berserker.w00t }
|
|
47
|
+
2.times { berserker.blam }
|
|
48
|
+
puts berserker.health
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require_relative 'player'
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
module StudioGame
|
|
5
|
+
|
|
6
|
+
class ClumsyPlayer < Player
|
|
7
|
+
|
|
8
|
+
def initialize(name, health, boost_factor)
|
|
9
|
+
super(name, health)
|
|
10
|
+
@boost_factor = boost_factor
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def found_treasure(treasure = TreasureTrove::TREASURES.sample)
|
|
14
|
+
damaged_treasure = Treasure.new(treasure.name, treasure.points/2)
|
|
15
|
+
super(damaged_treasure)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def w00t
|
|
19
|
+
@boost_factor.times {super}
|
|
20
|
+
puts "#{self.name}'s health is #{@health}"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
if __FILE__ == $0
|
|
26
|
+
clumsy = ClumsyPlayer.new("klutz",100,10)
|
|
27
|
+
|
|
28
|
+
hammer = Treasure.new(:hammer, 50)
|
|
29
|
+
clumsy.found_treasure(hammer)
|
|
30
|
+
clumsy.found_treasure(hammer)
|
|
31
|
+
clumsy.found_treasure(hammer)
|
|
32
|
+
|
|
33
|
+
crowbar = Treasure.new(:crowbar, 400)
|
|
34
|
+
clumsy.found_treasure(crowbar)
|
|
35
|
+
|
|
36
|
+
clumsy.each_found_treasure do |treasure|
|
|
37
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
|
38
|
+
end
|
|
39
|
+
puts "#{clumsy.points} grand total points"
|
|
40
|
+
|
|
41
|
+
clumsy.w00t
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Checking git health after fresh installation on Mountain Lion
|
|
2
|
+
require_relative './spinner'
|
|
3
|
+
require_relative './player'
|
|
4
|
+
require_relative './game_turn'
|
|
5
|
+
require_relative './treasure_trove'
|
|
6
|
+
|
|
7
|
+
module StudioGame
|
|
8
|
+
|
|
9
|
+
class Game
|
|
10
|
+
|
|
11
|
+
attr_reader :title
|
|
12
|
+
attr_accessor :total_game_points
|
|
13
|
+
|
|
14
|
+
def initialize(title)
|
|
15
|
+
@title = title.capitalize
|
|
16
|
+
@players = []
|
|
17
|
+
@treasure = TreasureTrove::TREASURES
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def add_player(player)
|
|
21
|
+
@players << player
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def show_players
|
|
25
|
+
puts @players
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def play(rounds=5)
|
|
29
|
+
print_treasures
|
|
30
|
+
1.upto(rounds) do |round|
|
|
31
|
+
|
|
32
|
+
yield if block_given?
|
|
33
|
+
|
|
34
|
+
puts "\n\nSTARTING ROUND #{round}"
|
|
35
|
+
@players.each do |player|
|
|
36
|
+
GameTurn.take_turn(player)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def show_game_status
|
|
42
|
+
puts "\n\nGAME STATUS\nThere are #{@players.size} players in #{self.title}:"
|
|
43
|
+
show_players
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def print_stats
|
|
47
|
+
strong_players, weak_players = @players.partition {|player| player.strong?}
|
|
48
|
+
|
|
49
|
+
puts "\nReport on Player Health"
|
|
50
|
+
puts "\n#{strong_players.size} strong players\n"
|
|
51
|
+
strong_players.each do |player|
|
|
52
|
+
print_name_and_health(player)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
puts "\n#{weak_players.size} weak players\n"
|
|
56
|
+
weak_players.each do |player|
|
|
57
|
+
print_name_and_health(player)
|
|
58
|
+
end
|
|
59
|
+
puts "\n\n"
|
|
60
|
+
|
|
61
|
+
puts "\nPoint Totals With a Custom Iterator\n"
|
|
62
|
+
@players.each do |player|
|
|
63
|
+
puts "\n#{player.name}\'s point totals:"
|
|
64
|
+
player.each_found_treasure do |treasure|
|
|
65
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def print_high_scores
|
|
71
|
+
sorted_players = @players.sort
|
|
72
|
+
puts "\n\n"
|
|
73
|
+
puts "Scores in Descending Order"
|
|
74
|
+
sorted_players.each do |player|
|
|
75
|
+
print_name_and_score(player)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def print_name_and_score(player)
|
|
80
|
+
puts "#{player.name} #{player.score.to_s.rjust(20,'.')}"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def print_name_and_health(player)
|
|
84
|
+
puts "#{player.name} #{player.health.to_s.rjust(20,'.')}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def print_treasures
|
|
88
|
+
puts "There are #{@treasure.size} treasures to be found:"
|
|
89
|
+
@treasure.each do |treasure|
|
|
90
|
+
puts "A #{treasure.name} is worth #{treasure.points} points"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def total_game_points
|
|
95
|
+
|
|
96
|
+
total = 0
|
|
97
|
+
|
|
98
|
+
@players.each do |player|
|
|
99
|
+
total += player.points
|
|
100
|
+
end
|
|
101
|
+
return total
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def load_players(csvfile = 'players.csv')
|
|
105
|
+
puts "\ncsvfile = #{csvfile}\n"
|
|
106
|
+
|
|
107
|
+
filehandle = File.open(csvfile)
|
|
108
|
+
players = []
|
|
109
|
+
index = 0
|
|
110
|
+
|
|
111
|
+
loop do
|
|
112
|
+
currentline = filehandle.gets
|
|
113
|
+
break if currentline == nil
|
|
114
|
+
players[index] = currentline.chomp
|
|
115
|
+
index += 1
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
players.each do |player|
|
|
119
|
+
temparray = player.split(',')
|
|
120
|
+
entrant = Player.new(temparray[0].to_s,temparray[1].to_i)
|
|
121
|
+
add_player(entrant)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def save_high_scores(highfile = 'high_scores.txt')
|
|
127
|
+
target = File.open(highfile, 'w') {|f| f.write(print_high_scores)}
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require_relative './spinner'
|
|
2
|
+
# require_relative './loaded_spinner'
|
|
3
|
+
require_relative './player'
|
|
4
|
+
|
|
5
|
+
module StudioGame
|
|
6
|
+
|
|
7
|
+
module GameTurn
|
|
8
|
+
|
|
9
|
+
def self.take_turn(player)
|
|
10
|
+
number_spun = Spinner.new.spin
|
|
11
|
+
# number_spun = LoadedSpinner.new.spin
|
|
12
|
+
if number_spun >= 5
|
|
13
|
+
player.w00t
|
|
14
|
+
elsif number_spun <= 2
|
|
15
|
+
player.blam
|
|
16
|
+
else
|
|
17
|
+
puts "\n*** #{player.name} was skipped."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
player.found_treasure
|
|
21
|
+
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.found_treasure(player)
|
|
25
|
+
@treasure = TreasureTrove::TREASURES.sample
|
|
26
|
+
puts "Treasure selected in \'get_treasure\' method: #{@treasure.name}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[I'm Klutz with a health of 20335 and a 20340 score.
|
|
2
|
+
Klutz's treasure bag contains {:bottle=>2100, :broomstick=>17800, :crowbar=>29200, :pie=>314, :hammer=>4275, :skillet=>8650}.
|
|
3
|
+
Klutz's Grand Total Points = 0
|
|
4
|
+
|
|
5
|
+
, I'm Berserker with a health of 9770 and a 9779 score.
|
|
6
|
+
Berserker's treasure bag contains {:bottle=>4675, :crowbar=>63600, :hammer=>7250, :pie=>960, :skillet=>16100, :broomstick=>31200}.
|
|
7
|
+
Berserker's Grand Total Points = 0
|
|
8
|
+
|
|
9
|
+
, I'm Alvin with a health of 1760 and a 1765 score.
|
|
10
|
+
Alvin's treasure bag contains {:crowbar=>72400, :skillet=>14700, :bottle=>3775, :broomstick=>36200, :pie=>860, :hammer=>8400}.
|
|
11
|
+
Alvin's Grand Total Points = 0
|
|
12
|
+
|
|
13
|
+
, I'm Simon with a health of 1710 and a 1715 score.
|
|
14
|
+
Simon's treasure bag contains {:bottle=>4325, :hammer=>8500, :skillet=>17800, :broomstick=>29800, :crowbar=>66000, :pie=>825}.
|
|
15
|
+
Simon's Grand Total Points = 0
|
|
16
|
+
|
|
17
|
+
, I'm Theodore with a health of 1455 and a 1463 score.
|
|
18
|
+
Theodore's treasure bag contains {:broomstick=>34400, :skillet=>16400, :pie=>840, :bottle=>4200, :hammer=>8400, :crowbar=>64000}.
|
|
19
|
+
Theodore's Grand Total Points = 0
|
|
20
|
+
|
|
21
|
+
]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module StudioGame
|
|
2
|
+
|
|
3
|
+
module Playable
|
|
4
|
+
|
|
5
|
+
def w00t
|
|
6
|
+
puts "\n#{name} got w00ted!"
|
|
7
|
+
self.health += 15
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def blam
|
|
11
|
+
puts "\n#{name} got blammed!"
|
|
12
|
+
self.health -= 10
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def strong? # RSpec allows some syntactic sugar w/predicate methods.
|
|
16
|
+
self.health > 100
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
require_relative './treasure_trove'
|
|
2
|
+
require_relative 'playable'
|
|
3
|
+
|
|
4
|
+
module StudioGame
|
|
5
|
+
class Player
|
|
6
|
+
|
|
7
|
+
include Playable
|
|
8
|
+
|
|
9
|
+
attr_accessor :name, :health
|
|
10
|
+
attr_reader :show, :score
|
|
11
|
+
|
|
12
|
+
def initialize(name, health=100)
|
|
13
|
+
@name = name.capitalize
|
|
14
|
+
@health = health
|
|
15
|
+
@points = 0
|
|
16
|
+
@found_treasure = Hash.new(0)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def score
|
|
20
|
+
@score = @health + @name.length
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def to_s
|
|
24
|
+
return "I\'m #{@name} with a health of #{@health} and a #{score} score.\n#{@name}'s treasure bag contains #{treasure_bag}.\n#{@name}'s Grand Total Points = #{@points}\n\n"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def <=>(other_player)
|
|
28
|
+
other_player.score <=> @score
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def found_treasure(treasure = TreasureTrove::TREASURES.sample)
|
|
32
|
+
|
|
33
|
+
if !@found_treasure
|
|
34
|
+
@found_treasure = Hash.new(0)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
@found_treasure[treasure.name.to_sym] += treasure.points
|
|
38
|
+
puts "Treasure selected in \'found_treasure\' method: #{treasure.name}"
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def treasure_bag
|
|
43
|
+
return "no treasure in this bag" if !@found_treasure
|
|
44
|
+
@found_treasure
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def points
|
|
48
|
+
return 0 if @found_treasure.size == 0
|
|
49
|
+
@points = @found_treasure.values.reduce(:+)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def random_stuff
|
|
53
|
+
0
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def each_found_treasure
|
|
57
|
+
|
|
58
|
+
@found_treasure.each do |key, value|
|
|
59
|
+
yield Treasure.new(key, value)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if __FILE__ == $0
|
|
66
|
+
player1 = Player.new("moe")
|
|
67
|
+
player2 = Player.new("larry", 600)
|
|
68
|
+
player3 = Player.new("curly", 1295)
|
|
69
|
+
|
|
70
|
+
puts player1
|
|
71
|
+
puts player2
|
|
72
|
+
puts player3
|
|
73
|
+
|
|
74
|
+
puts "#{player1.name}'s found treasure: #{player1.found_treasure}"
|
|
75
|
+
puts "#{player1.name}'s points: #{player1.points}"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_relative 'auditable'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
|
|
5
|
+
class Spinner
|
|
6
|
+
|
|
7
|
+
include Auditable
|
|
8
|
+
|
|
9
|
+
attr_reader :number
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
spin
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def spin
|
|
16
|
+
@number = rand(1..6)
|
|
17
|
+
audit
|
|
18
|
+
@number
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
puts "\n**** Let's keep 'em separated. ****\n\n"
|
|
2
|
+
player1 = "larry"
|
|
3
|
+
player2 = "curly"
|
|
4
|
+
player3 = "moe"
|
|
5
|
+
player4 = "shemp"
|
|
6
|
+
|
|
7
|
+
health1 = 60
|
|
8
|
+
health2 = 125
|
|
9
|
+
health3 = 100
|
|
10
|
+
health4 = 90
|
|
11
|
+
|
|
12
|
+
start_time = Time.new
|
|
13
|
+
|
|
14
|
+
puts "#{player1.capitalize} has a health of #{health1}."
|
|
15
|
+
puts "#{player2.upcase} has a health of #{health2}."
|
|
16
|
+
puts "#{player3.capitalize} has a health of #{health3}.".center(50,'*')
|
|
17
|
+
puts "#{player4.capitalize.ljust(40,'.')} #{health4} health"
|
|
18
|
+
|
|
19
|
+
puts "\n\nThe game started on #{start_time.strftime("%A %m/%d/%Y at%l:%M%p")}"
|
|
20
|
+
|
|
21
|
+
puts "\n**** Let's keep 'em separated. ****\n"
|
|
22
|
+
def fmt_time
|
|
23
|
+
current_time = Time.new
|
|
24
|
+
formatted_time = current_time.strftime("%H:%M:%S")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def say_hello(name="generic", health = 100)
|
|
28
|
+
"I'm #{name.capitalize} with a health of #{health} as of #{fmt_time}."
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
puts say_hello("larry", 60)
|
|
32
|
+
puts say_hello("curly", 125)
|
|
33
|
+
puts say_hello("moe")
|
|
34
|
+
puts say_hello("shemp", 90)
|
|
35
|
+
|
|
36
|
+
puts "\n**** Let's keep 'em separated. ****\n"
|
|
37
|
+
|
|
38
|
+
player = %w["larry", "curly", "moe"]
|
|
39
|
+
health = %w[60, 85, 129]
|
|
40
|
+
|
|
41
|
+
player1health = 60
|
|
42
|
+
|
|
43
|
+
puts "#{player[1]}\'s health is #{health[1]}"
|
|
44
|
+
|
|
45
|
+
player.each do |this_one|
|
|
46
|
+
puts "#{this_one}\'s health is #{health[1]}"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
puts "Now, let's triple #{player1}\'s health."
|
|
50
|
+
|
|
51
|
+
player1health *= 3
|
|
52
|
+
|
|
53
|
+
puts "#{player1}\'s health is #{player1health}"
|
|
54
|
+
|
|
55
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module StudioGame
|
|
2
|
+
|
|
3
|
+
Treasure = Struct.new(:name, :points)
|
|
4
|
+
|
|
5
|
+
module TreasureTrove
|
|
6
|
+
|
|
7
|
+
TREASURES = [
|
|
8
|
+
Treasure.new(:pie, 5),
|
|
9
|
+
Treasure.new(:bottle, 25),
|
|
10
|
+
Treasure.new(:hammer, 50),
|
|
11
|
+
Treasure.new(:skillet, 100),
|
|
12
|
+
Treasure.new(:broomstick, 200),
|
|
13
|
+
Treasure.new(:crowbar, 400)]
|
|
14
|
+
|
|
15
|
+
def self.random
|
|
16
|
+
TREASURES.sample
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require 'studio_game/berserk_player'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
|
|
5
|
+
describe BerserkPlayer do
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
@initial_health = 50
|
|
9
|
+
@player = BerserkPlayer.new("berserker", @initial_health)
|
|
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_false
|
|
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_true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "gets w00ted instead of blammed when it's gone berserk" do
|
|
25
|
+
1.upto(6) { @player.w00t }
|
|
26
|
+
1.upto(2) { @player.blam }
|
|
27
|
+
|
|
28
|
+
@player.health.should == @initial_health + (8 * 15)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
require 'studio_game/clumsy_player'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
|
|
5
|
+
describe ClumsyPlayer do
|
|
6
|
+
before do
|
|
7
|
+
@player = ClumsyPlayer.new("klutz",100,10)
|
|
8
|
+
end
|
|
9
|
+
|
|
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
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
yielded.should == [Treasure.new(:hammer, 75), Treasure.new(:crowbar, 200)]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "applies the boost factor as expected" do
|
|
34
|
+
@player.w00t
|
|
35
|
+
@player.health.should == 250
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# instead of Die and roll, use Spinner and spin
|
|
2
|
+
#
|
|
3
|
+
require 'studio_game/game'
|
|
4
|
+
|
|
5
|
+
module StudioGame
|
|
6
|
+
|
|
7
|
+
describe Game do
|
|
8
|
+
context "high number from the spinner" do
|
|
9
|
+
|
|
10
|
+
before do
|
|
11
|
+
@game = Game.new("streetracer")
|
|
12
|
+
|
|
13
|
+
@initial_health = 100
|
|
14
|
+
@player = Player.new("moe", @initial_health)
|
|
15
|
+
@number_of_rounds = 2
|
|
16
|
+
|
|
17
|
+
@game.add_player(@player)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "w00ts the player when a high number is spun" do
|
|
21
|
+
@spinner = Spinner.any_instance.stub(:spin).and_return(5)
|
|
22
|
+
@game.play(@number_of_rounds)
|
|
23
|
+
@player.health.should == @initial_health + (15 * @number_of_rounds)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "does nothing when a medium number is spun" do
|
|
27
|
+
@spinner = Spinner.any_instance.stub(:spin).and_return(4)
|
|
28
|
+
@game.play(@number_of_rounds)
|
|
29
|
+
@player.health.should == @initial_health
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it "blams the player when a low number is spun" do
|
|
33
|
+
@spinner = Spinner.any_instance.stub(:spin).and_return(2)
|
|
34
|
+
@game.play(@number_of_rounds)
|
|
35
|
+
@player.health.should == @initial_health - (10 * @number_of_rounds)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "runs guard when another spec is added"
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'studio_game/game_turn.rb'
|
|
2
|
+
|
|
3
|
+
# Is it overkill to have this file when other files are covering the GameTurn module with tests?
|
|
4
|
+
#
|
|
5
|
+
module StudioGame
|
|
6
|
+
|
|
7
|
+
describe GameTurn do
|
|
8
|
+
|
|
9
|
+
before do
|
|
10
|
+
@player = Player.new("Kirk",100)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'should take a turn'
|
|
14
|
+
|
|
15
|
+
# it 'should grab a treasure item' do
|
|
16
|
+
# @treasure.name.should_not == nil
|
|
17
|
+
# end
|
|
18
|
+
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require 'studio_game/player'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
|
|
5
|
+
describe Player do
|
|
6
|
+
|
|
7
|
+
context "strong player" do
|
|
8
|
+
before do
|
|
9
|
+
@player = Player.new("hercules", 150)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# RSpec allows some syntactic sugar w/predicate methods. strong?
|
|
13
|
+
it "should be a player with strong health" do
|
|
14
|
+
@player.should be_strong
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
context "weak player" do
|
|
19
|
+
before do
|
|
20
|
+
@player = Player.new("junior", 100)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should be a player with weak health" do
|
|
24
|
+
@player.should_not be_strong
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
context "general player" do
|
|
29
|
+
|
|
30
|
+
before do
|
|
31
|
+
@player = Player.new("geronimo", 200)
|
|
32
|
+
@initial_health = @player.health
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "has an inital health" do
|
|
36
|
+
@player.health.should_not == nil
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "computes a score as the sum of its health and length of name" do
|
|
40
|
+
@player.score.should == @player.health + @player.name.length
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "increases health by 15 when w00ted" do
|
|
44
|
+
w00ted_health = @initial_health + 15
|
|
45
|
+
@player.w00t
|
|
46
|
+
@player.health.should == w00ted_health
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "decreases health by 10 when blammed" do
|
|
50
|
+
blammed_health = @initial_health - 10
|
|
51
|
+
@player.blam
|
|
52
|
+
@player.health.should == blammed_health
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "treasure tracking" do
|
|
57
|
+
before do
|
|
58
|
+
@player = Player.new("alexander", 150)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it "starts with a treasure point total of 0" do
|
|
62
|
+
player = Player.new("bartholemew")
|
|
63
|
+
player.points.should == 0
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "yields each found treasure and its total points" do
|
|
67
|
+
@player.found_treasure(Treasure.new(:skillet, 100))
|
|
68
|
+
@player.found_treasure(Treasure.new(:skillet, 100))
|
|
69
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
|
70
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
|
71
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
|
72
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
|
73
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
|
74
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
|
75
|
+
|
|
76
|
+
yielded = []
|
|
77
|
+
@player.each_found_treasure do |treasure|
|
|
78
|
+
yielded << treasure
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
puts "\n\n+++++++ We are in player_spec.rb ++++++\n"
|
|
82
|
+
# yielded.should == [{:skillet=>200, :hammer=>50, :bottle=>25}]
|
|
83
|
+
|
|
84
|
+
yielded.should == [
|
|
85
|
+
Treasure.new(:skillet, 200),
|
|
86
|
+
Treasure.new(:hammer, 50),
|
|
87
|
+
Treasure.new(:bottle, 25)
|
|
88
|
+
]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "adds to found treasure and computes resulting points"
|
|
92
|
+
|
|
93
|
+
it "adds new treasure, creating keys where needed"
|
|
94
|
+
|
|
95
|
+
it "adds another item to the found treasurer"
|
|
96
|
+
|
|
97
|
+
it "runs another spec specified by RTH"
|
|
98
|
+
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'studio_game/spinner'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
|
|
5
|
+
describe Spinner do
|
|
6
|
+
before do
|
|
7
|
+
@spinner = Spinner.new
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'should spin an integer greater than or equal to one' do
|
|
11
|
+
@spinner.spin.should >= 1
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'should spin an integer less than or equal to six' do
|
|
15
|
+
@spinner.spin.should <= 6
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'studio_game/treasure_trove'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
|
|
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
|
+
|
|
21
|
+
describe TreasureTrove do
|
|
22
|
+
|
|
23
|
+
it "has six treasures" do
|
|
24
|
+
TreasureTrove::TREASURES.size.should == 6
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "has a pie worth 5 points" do
|
|
28
|
+
TreasureTrove::TREASURES[0].should == Treasure.new(:pie, 5)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "has a bottle worth 25 points" do
|
|
32
|
+
TreasureTrove::TREASURES[1].should == Treasure.new(:bottle, 25)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "has a hammer worth 50 points" do
|
|
36
|
+
TreasureTrove::TREASURES[2].should == Treasure.new(:hammer, 50)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "has a skillet worth 100 points" do
|
|
40
|
+
TreasureTrove::TREASURES[3].should == Treasure.new(:skillet, 100)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "has a broomstick worth 200 points" do
|
|
44
|
+
TreasureTrove::TREASURES[4].should == Treasure.new(:broomstick, 200)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "has a crowbar worth 400 points" do
|
|
48
|
+
TreasureTrove::TREASURES[5].should == Treasure.new(:crowbar, 400)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "returns a random treasure" do
|
|
52
|
+
treasure = TreasureTrove.random
|
|
53
|
+
|
|
54
|
+
TreasureTrove::TREASURES.should include(treasure)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rth-studiogame
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: '0.9'
|
|
5
|
+
prerelease:
|
|
6
|
+
platform: ruby
|
|
7
|
+
authors:
|
|
8
|
+
- Raymond T. Hightower
|
|
9
|
+
autorequire:
|
|
10
|
+
bindir: bin
|
|
11
|
+
cert_chain: []
|
|
12
|
+
date: 2012-08-09 00:00:00.000000000 Z
|
|
13
|
+
dependencies:
|
|
14
|
+
- !ruby/object:Gem::Dependency
|
|
15
|
+
name: rspec
|
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
|
17
|
+
none: false
|
|
18
|
+
requirements:
|
|
19
|
+
- - ! '>='
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '0'
|
|
22
|
+
type: :development
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
none: false
|
|
26
|
+
requirements:
|
|
27
|
+
- - ! '>='
|
|
28
|
+
- !ruby/object:Gem::Version
|
|
29
|
+
version: '0'
|
|
30
|
+
description: ! 'pragruby
|
|
31
|
+
|
|
32
|
+
========
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
Ruby immersion as part of RubyMotion learning.'
|
|
36
|
+
email: rth@wisdomgroup.com
|
|
37
|
+
executables:
|
|
38
|
+
- rth-studiogame
|
|
39
|
+
extensions: []
|
|
40
|
+
extra_rdoc_files: []
|
|
41
|
+
files:
|
|
42
|
+
- bin/players.csv
|
|
43
|
+
- bin/rth-studiogame
|
|
44
|
+
- lib/studio_game/auditable.rb
|
|
45
|
+
- lib/studio_game/berserk_player.rb
|
|
46
|
+
- lib/studio_game/clumsy_player.rb
|
|
47
|
+
- lib/studio_game/game.rb
|
|
48
|
+
- lib/studio_game/game_turn.rb
|
|
49
|
+
- lib/studio_game/high_scores.txt
|
|
50
|
+
- lib/studio_game/loaded_spinner.rb
|
|
51
|
+
- lib/studio_game/moreplayers.csv
|
|
52
|
+
- lib/studio_game/playable.rb
|
|
53
|
+
- lib/studio_game/player.rb
|
|
54
|
+
- lib/studio_game/spinner.rb
|
|
55
|
+
- lib/studio_game/studio_game_initial.rb
|
|
56
|
+
- lib/studio_game/treasure_trove.rb
|
|
57
|
+
- spec/studio_game/berserk_player_spec.rb
|
|
58
|
+
- spec/studio_game/clumsy_player_spec.rb
|
|
59
|
+
- spec/studio_game/game_spec.rb
|
|
60
|
+
- spec/studio_game/game_turn_spec.rb
|
|
61
|
+
- spec/studio_game/player_spec.rb
|
|
62
|
+
- spec/studio_game/spinner_spec.rb
|
|
63
|
+
- spec/studio_game/treasure_trove_spec.rb
|
|
64
|
+
- LICENSE
|
|
65
|
+
- README.md
|
|
66
|
+
homepage: http://wisdomgroup.com
|
|
67
|
+
licenses: []
|
|
68
|
+
post_install_message:
|
|
69
|
+
rdoc_options: []
|
|
70
|
+
require_paths:
|
|
71
|
+
- lib
|
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
73
|
+
none: false
|
|
74
|
+
requirements:
|
|
75
|
+
- - ! '>='
|
|
76
|
+
- !ruby/object:Gem::Version
|
|
77
|
+
version: '1.9'
|
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
|
+
none: false
|
|
80
|
+
requirements:
|
|
81
|
+
- - ! '>='
|
|
82
|
+
- !ruby/object:Gem::Version
|
|
83
|
+
version: '0'
|
|
84
|
+
requirements: []
|
|
85
|
+
rubyforge_project:
|
|
86
|
+
rubygems_version: 1.8.24
|
|
87
|
+
signing_key:
|
|
88
|
+
specification_version: 3
|
|
89
|
+
summary: Gem created during the PragProg online Ruby course
|
|
90
|
+
test_files:
|
|
91
|
+
- spec/studio_game/berserk_player_spec.rb
|
|
92
|
+
- spec/studio_game/clumsy_player_spec.rb
|
|
93
|
+
- spec/studio_game/game_spec.rb
|
|
94
|
+
- spec/studio_game/game_turn_spec.rb
|
|
95
|
+
- spec/studio_game/player_spec.rb
|
|
96
|
+
- spec/studio_game/spinner_spec.rb
|
|
97
|
+
- spec/studio_game/treasure_trove_spec.rb
|