studio_game_dilip 1.0.0
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 +20 -0
- data/README +18 -0
- data/bin/high_scores.txt +6 -0
- data/bin/my_favorite_players.csv +3 -0
- data/bin/players.csv +3 -0
- data/bin/studio_game +51 -0
- data/bin/studio_game.rb~ +16 -0
- data/lib/studio_game/auditable.rb +8 -0
- data/lib/studio_game/berserk_player.rb +33 -0
- data/lib/studio_game/clumsy_player.rb +38 -0
- data/lib/studio_game/die.rb +19 -0
- data/lib/studio_game/game.rb +121 -0
- data/lib/studio_game/game.rb~ +35 -0
- data/lib/studio_game/game_turn.rb +26 -0
- data/lib/studio_game/loaded_die.rb +16 -0
- data/lib/studio_game/playable.rb +33 -0
- data/lib/studio_game/player.rb +64 -0
- data/lib/studio_game/player.rb~ +37 -0
- data/lib/studio_game/treasure_trove.rb +27 -0
- data/spec/studio_game/berserk_player_spec.rb +30 -0
- data/spec/studio_game/clumsy_player_spec.rb +51 -0
- data/spec/studio_game/game_spec.rb +62 -0
- data/spec/studio_game/high_scores.txt +6 -0
- data/spec/studio_game/player_spec.rb +127 -0
- data/spec/studio_game/player_spec.rb~ +7 -0
- data/spec/studio_game/treasure_trove_spec.rb +56 -0
- metadata +103 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (C) 2012 Dr. Dilip Deodhar
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
17
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
18
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
19
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
20
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
This a simple game where virtual players compete to find treasures.
|
2
|
+
Health of the players is importatnt. The players may get blammed
|
3
|
+
or get w00ted.
|
4
|
+
|
5
|
+
- To start the game on command line:
|
6
|
+
studiogame.rb <csv file, containing a list of players>
|
7
|
+
if the optional csv file is not provided, the game will use the
|
8
|
+
default file called 'players.csv'.
|
9
|
+
- Example of csv list of players (name & health):
|
10
|
+
Alvin,100
|
11
|
+
Simon,60
|
12
|
+
Theo,125
|
13
|
+
|
14
|
+
- The game will ask, how many game rounds to play.
|
15
|
+
Enter the number of rounds or enter 'quit' or 'exit' to stop the game.
|
16
|
+
|
17
|
+
- The game, at the end, will print out the game statistics and high scores.
|
18
|
+
It will also create a file containing the high scores.
|
data/bin/high_scores.txt
ADDED
data/bin/players.csv
ADDED
data/bin/studio_game
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/studio_game/game'
|
4
|
+
#require_relative 'players'
|
5
|
+
|
6
|
+
game = StudioGame::Game.new("Knuckleheads")
|
7
|
+
|
8
|
+
default_player_file = File.join(File.dirname(__FILE__), 'players.csv')
|
9
|
+
game.load_players(ARGV.shift || default_player_file)
|
10
|
+
|
11
|
+
game.add_player(StudioGame::ClumsyPlayer.new("klutz", 105, 5))
|
12
|
+
game.add_player(StudioGame::BerserkPlayer.new("berserker", 50))
|
13
|
+
|
14
|
+
#knuckleheads.add_player(Player.new("moe"))
|
15
|
+
#knuckleheads.add_player(Player.new("larry", 60))
|
16
|
+
#knuckleheads.add_player(Player.new("curly", 125))
|
17
|
+
|
18
|
+
loop do
|
19
|
+
puts "\nHow many game rounds? ('quit' to exit)"
|
20
|
+
answer = gets.chomp.downcase
|
21
|
+
case answer
|
22
|
+
when /^\d+$/
|
23
|
+
game.play(answer.to_i)
|
24
|
+
when "q", "e", "quit", "exit"
|
25
|
+
game.print_stats
|
26
|
+
game.save_high_scores
|
27
|
+
break
|
28
|
+
else
|
29
|
+
puts "Please enter a number or 'quit' to exit"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
#stoneheads = Game.new("Stoneheads")
|
41
|
+
#stoneheads.add_player(Player.new("sh1", 70))
|
42
|
+
#stoneheads.add_player(Player.new("sh2", 80))
|
43
|
+
#stoneheads.add_player(Player.new("sh3", 90))
|
44
|
+
#stoneheads.add_player(Player.new("sh4", 100))
|
45
|
+
#
|
46
|
+
#stoneheads.play(10) do
|
47
|
+
# stoneheads.total_points >= 1500
|
48
|
+
#end
|
49
|
+
#
|
50
|
+
#stoneheads.print_stats
|
51
|
+
#
|
data/bin/studio_game.rb~
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#require_relative 'game'
|
2
|
+
|
3
|
+
knuckleheads = Game.new("Knuckleheads")
|
4
|
+
knuckleheads.add_player(Player.new("moe"))
|
5
|
+
knuckleheads.add_player(Player.new("larry", 60))
|
6
|
+
knuckleheads.add_player(Player.new("curly", 125))
|
7
|
+
knuckleheads.play
|
8
|
+
|
9
|
+
game20 = Game.new("Game20")
|
10
|
+
game20.add_player(Player.new("B1", 70))
|
11
|
+
game20.add_player(Player.new("B2", 80))
|
12
|
+
game20.add_player(Player.new("B3", 90))
|
13
|
+
game20.add_player(Player.new("B4", 100))
|
14
|
+
game20.play
|
15
|
+
|
16
|
+
#
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
class BerserkPlayer < Player
|
5
|
+
|
6
|
+
def initialize (name, health=100)
|
7
|
+
super(name, health)
|
8
|
+
@w00t_count = 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def berserk?
|
12
|
+
@w00t_count > 5
|
13
|
+
end
|
14
|
+
|
15
|
+
def w00t
|
16
|
+
super
|
17
|
+
@w00t_count +=1
|
18
|
+
puts "#{@name} is berserk!" if berserk?
|
19
|
+
end
|
20
|
+
|
21
|
+
def blam
|
22
|
+
berserk? ? w00t : super
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if __FILE__ == $0
|
29
|
+
berserker = StudioGame::BerserkPlayer.new("berserker", 50)
|
30
|
+
6.times { berserker.w00t }
|
31
|
+
2.times { berserker.blam }
|
32
|
+
puts berserker.health
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
class ClumsyPlayer < Player
|
5
|
+
attr_reader :boost_factor
|
6
|
+
|
7
|
+
def initialize (name, health=100, boost_factor=1)
|
8
|
+
super(name, health)
|
9
|
+
@boost_factor = boost_factor
|
10
|
+
end
|
11
|
+
|
12
|
+
def w00t
|
13
|
+
boost_factor.times{super}
|
14
|
+
end
|
15
|
+
|
16
|
+
def found_treasure(treasure)
|
17
|
+
damaged_treasure = Treasure.new(treasure.name, treasure.points / 2)
|
18
|
+
super(damaged_treasure)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
if __FILE__ == $0
|
24
|
+
clumsy = StudioGame::ClumsyPlayer.new("klutz", 105, 3)
|
25
|
+
|
26
|
+
hammer = StudioGame::Treasure.new(:hammer, 50)
|
27
|
+
clumsy.found_treasure(hammer)
|
28
|
+
clumsy.found_treasure(hammer)
|
29
|
+
clumsy.found_treasure(hammer)
|
30
|
+
|
31
|
+
crowbar = StudioGame::Treasure.new(:crowbar, 400)
|
32
|
+
clumsy.found_treasure(crowbar)
|
33
|
+
|
34
|
+
clumsy.each_found_treasure do |treasure|
|
35
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
36
|
+
end
|
37
|
+
puts "#{clumsy.points} grand total points"
|
38
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
require_relative 'clumsy_player'
|
3
|
+
require_relative 'berserk_player'
|
4
|
+
require_relative 'die'
|
5
|
+
require_relative 'treasure_trove'
|
6
|
+
require_relative 'game_turn'
|
7
|
+
require 'csv'
|
8
|
+
|
9
|
+
module StudioGame
|
10
|
+
class Game
|
11
|
+
attr_reader :title
|
12
|
+
attr_accessor :players
|
13
|
+
def initialize(title)
|
14
|
+
@title = title.capitalize
|
15
|
+
@players = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def save_high_scores(to_file="high_scores.txt")
|
19
|
+
File.open(to_file, "w") do |file|
|
20
|
+
file.puts "#{@title} High Scores"
|
21
|
+
@players.sort.each do |pl|
|
22
|
+
file.puts(high_score_entry(pl))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def high_score_entry(player)
|
28
|
+
formatted_name = player.name.ljust(20, '.')
|
29
|
+
"#{formatted_name} #{player.score}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_players(from_file)
|
33
|
+
CSV.foreach(from_file) do |row|
|
34
|
+
player = Player.new(row[0], row[1].to_i)
|
35
|
+
add_player(player)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_s
|
40
|
+
"\n\n**** There are #{@players.size} players in #{@title} ****\n"
|
41
|
+
end
|
42
|
+
|
43
|
+
def add_player(player)
|
44
|
+
@players << player
|
45
|
+
end
|
46
|
+
|
47
|
+
def play(rounds)
|
48
|
+
puts self
|
49
|
+
@players.each {|pl| puts pl}
|
50
|
+
TreasureTrove.print_treasures
|
51
|
+
|
52
|
+
1.upto(rounds) do |round|
|
53
|
+
if block_given?
|
54
|
+
#yielded = yield total_points # longer
|
55
|
+
#break if yielded
|
56
|
+
break if yield total_points # more elegent
|
57
|
+
end
|
58
|
+
|
59
|
+
puts "\nRound: #{round}:"
|
60
|
+
@players.each do |pl|
|
61
|
+
GameTurn.take_turn(pl)
|
62
|
+
puts pl
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def total_points
|
68
|
+
@players.reduce(0){ |sum, pl| sum + pl.points }
|
69
|
+
end
|
70
|
+
|
71
|
+
def print_stats_sub_title(pls, str_or_wmp_text)
|
72
|
+
pls.size == 1 ? (plural_text = "player") : (plural_text = "players")
|
73
|
+
pls.size == 0 ? (colon_text = ".") : (colon_text = ":")
|
74
|
+
puts "\n#{pls.size} #{str_or_wmp_text} #{plural_text}#{colon_text}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def print_name_and_health(player)
|
78
|
+
puts "#{player.name} (#{player.health})\n"
|
79
|
+
end
|
80
|
+
|
81
|
+
def print_stats
|
82
|
+
puts "\n#{title} Statistics:\n"
|
83
|
+
strong_players, wimpy_players = @players.partition {|pl| pl.strong?}
|
84
|
+
|
85
|
+
print_stats_sub_title(strong_players, 'strong')
|
86
|
+
strong_players.sort! {|x, y| y.health <=> x.health}
|
87
|
+
strong_players.each { |player| print_name_and_health(player)}
|
88
|
+
|
89
|
+
print_stats_sub_title(wimpy_players, 'wimpy')
|
90
|
+
wimpy_players.sort! {|x, y| y.health <=> x.health}
|
91
|
+
wimpy_players.each { |player| print_name_and_health(player)}
|
92
|
+
|
93
|
+
puts "\n#{title} High Scores:\n"
|
94
|
+
@players.sort.each do |pl|
|
95
|
+
puts(high_score_entry(pl))
|
96
|
+
end
|
97
|
+
|
98
|
+
puts "\n#{total_points} total points from treasures found\n"
|
99
|
+
@players.each do |pl|
|
100
|
+
puts "\n#{pl.name}'s point totals:"
|
101
|
+
puts "#{pl.points} grand total points"
|
102
|
+
end
|
103
|
+
|
104
|
+
puts "\npoint totals"
|
105
|
+
@players.sort.each do |pl|
|
106
|
+
puts "\n#{pl.name}'s point totals per treasure:"
|
107
|
+
pl.each_found_treasure do |treasure|
|
108
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
109
|
+
end
|
110
|
+
puts "#{pl.points} grand total points"
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# --- This is run only if game.rb file us running by itself (e. for test) ---
|
118
|
+
|
119
|
+
if __FILE__ == $0
|
120
|
+
puts "*** You shouldn't see this output! ***"
|
121
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
|
3
|
+
class Game
|
4
|
+
attr_reader :name
|
5
|
+
attr_accessor :players
|
6
|
+
def initialize(name)
|
7
|
+
@name = name.capitalize
|
8
|
+
@players = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def to_s
|
12
|
+
"\nThere are #{@players.size} players in #{@name}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_player(player)
|
16
|
+
@players << player
|
17
|
+
end
|
18
|
+
|
19
|
+
def play
|
20
|
+
puts self
|
21
|
+
@players.each {|pl| puts pl}
|
22
|
+
@players.each do |pl|
|
23
|
+
pl.blam
|
24
|
+
pl.woot
|
25
|
+
pl.woot
|
26
|
+
puts pl
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# --- This is run only if player.rb file us running by itself (e. for test) ---
|
32
|
+
|
33
|
+
if __FILE__ == $0
|
34
|
+
puts "*** You shouldn't see this output! ***"
|
35
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
require_relative 'die'
|
3
|
+
#require_relative 'loaded_die' # sneaky
|
4
|
+
require_relative 'treasure_trove'
|
5
|
+
|
6
|
+
module StudioGame
|
7
|
+
module GameTurn
|
8
|
+
def self.take_turn(player)
|
9
|
+
die = Die.new
|
10
|
+
#die = LoadedDie.new # sneaky
|
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
|
+
# player.find_treasure
|
20
|
+
# treasure = player.find_treasure
|
21
|
+
# player.found_treasure(treasure)
|
22
|
+
treasure = TreasureTrove.random
|
23
|
+
player.found_treasure(treasure)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module StudioGame
|
2
|
+
module Playable
|
3
|
+
|
4
|
+
# good design practice: use attributes instead of
|
5
|
+
# instance variables (because they (iv) may change)
|
6
|
+
|
7
|
+
# In "health > 100", & "name"
|
8
|
+
# you can drop 'self.' because Ruby knows that
|
9
|
+
# "health" & "name"are readable attributes.
|
10
|
+
|
11
|
+
# So the rule is:
|
12
|
+
# If you assign to an attribute,
|
13
|
+
# i.e. attribute is on left-hand side of =,
|
14
|
+
# then you must use self.
|
15
|
+
|
16
|
+
def w00t
|
17
|
+
self.health += 15
|
18
|
+
puts "#{name} got w00ted"
|
19
|
+
health
|
20
|
+
end
|
21
|
+
|
22
|
+
def blam
|
23
|
+
self.health -= 10
|
24
|
+
puts "#{name} got blammed"
|
25
|
+
health
|
26
|
+
end
|
27
|
+
|
28
|
+
def strong?
|
29
|
+
health > 100
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require_relative 'treasure_trove'
|
2
|
+
require_relative 'playable.rb'
|
3
|
+
|
4
|
+
module StudioGame
|
5
|
+
class Player
|
6
|
+
include Playable
|
7
|
+
attr_accessor :name, :health
|
8
|
+
|
9
|
+
def initialize(name, health=100)
|
10
|
+
@name = name.capitalize
|
11
|
+
@health = health
|
12
|
+
@found_treasures = Hash.new(0)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_csv(string)
|
16
|
+
name, health = string.split(',')
|
17
|
+
new(name, Integer(health))
|
18
|
+
end
|
19
|
+
|
20
|
+
def each_found_treasure
|
21
|
+
@found_treasures.each do |name, points|
|
22
|
+
yield Treasure.new(name, points)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def found_treasure(treasure)
|
27
|
+
@found_treasures[treasure.name] += treasure.points
|
28
|
+
puts "#{@name} found a #{treasure.name} worth #{treasure.points} points"
|
29
|
+
puts "#{@name}'s treasures: #{@found_treasures}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def points
|
33
|
+
@found_treasures.values.reduce(0, :+)
|
34
|
+
end
|
35
|
+
|
36
|
+
def score
|
37
|
+
@health + points
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
"I'm #{@name} with health = #{@health}, points = #{points}, and score = #{score}."
|
42
|
+
end
|
43
|
+
|
44
|
+
def <=>(other) # sort in descending order
|
45
|
+
other.score <=> self.score
|
46
|
+
end
|
47
|
+
|
48
|
+
def find_treasure
|
49
|
+
treasure = TreasureTrove.random
|
50
|
+
puts "#{name} found a #{treasure.name} worth #{treasure.points}."
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
# --- Run only if this file (player.rb) is running by itself (eg for test) ----
|
55
|
+
if __FILE__ == $0
|
56
|
+
player = StudioGame::Player.new("moe")
|
57
|
+
puts player.name
|
58
|
+
puts player.health
|
59
|
+
player.w00t
|
60
|
+
puts player.health
|
61
|
+
player.blam
|
62
|
+
puts player.health
|
63
|
+
end
|
64
|
+
# -----
|
@@ -0,0 +1,37 @@
|
|
1
|
+
class Player
|
2
|
+
attr_accessor :name, :health
|
3
|
+
def initialize(name, health=100)
|
4
|
+
@name = name.capitalize
|
5
|
+
@health = health
|
6
|
+
end
|
7
|
+
|
8
|
+
def score
|
9
|
+
@health + @name.length
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_s
|
13
|
+
"I'm #{@name} with a health of #{@health} and a score of #{score}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def blam
|
17
|
+
@health -= 10
|
18
|
+
puts "#{@name} got blammed"
|
19
|
+
end
|
20
|
+
|
21
|
+
def woot
|
22
|
+
@health += 15
|
23
|
+
puts "#{@name} got wooted"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# --- run only if this file (player.rb) is running by itself (eg for test) ----
|
28
|
+
if __FILE__ == $0
|
29
|
+
player = Player.new("moe")
|
30
|
+
puts player.name
|
31
|
+
puts player.health
|
32
|
+
player.woot
|
33
|
+
puts player.health
|
34
|
+
player.blam
|
35
|
+
puts player.health
|
36
|
+
end
|
37
|
+
# -----
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module StudioGame
|
2
|
+
Treasure = Struct.new(:name, :points)
|
3
|
+
|
4
|
+
module TreasureTrove
|
5
|
+
TREASURES = [
|
6
|
+
Treasure.new(:pie, 5),
|
7
|
+
Treasure.new(:bottle, 25),
|
8
|
+
Treasure.new(:hammer, 50),
|
9
|
+
Treasure.new(:skillet, 100),
|
10
|
+
Treasure.new(:broomstick, 200),
|
11
|
+
Treasure.new(:crowbar, 400),
|
12
|
+
]
|
13
|
+
|
14
|
+
def TreasureTrove.print_treasures
|
15
|
+
puts "\nThere are #{TREASURES.size} treasures to be found:\n"
|
16
|
+
TREASURES.each do |tr|
|
17
|
+
puts "A #{tr.name} is worth #{tr.points} points."
|
18
|
+
# puts "A #{tr[0]} is worth #{tr[1]} points."
|
19
|
+
# .. tr.name & tr[0] are equivalent
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.random
|
24
|
+
TREASURES.sample
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'studio_game/berserk_player'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
describe BerserkPlayer do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@initial_health = 50
|
8
|
+
@player = BerserkPlayer.new("berserker", @initial_health)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "does not go berserk when w00ted up to 5 times" do
|
12
|
+
1.upto(5) { @player.w00t }
|
13
|
+
|
14
|
+
@player.berserk?.should be_false
|
15
|
+
end
|
16
|
+
|
17
|
+
it "goes berserk when w00ted more than 5 times" do
|
18
|
+
1.upto(6) { @player.w00t }
|
19
|
+
|
20
|
+
@player.berserk?.should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
it "gets w00ted instead of blammed when it's gone berserk" do
|
24
|
+
1.upto(6) { @player.w00t }
|
25
|
+
1.upto(2) { @player.blam }
|
26
|
+
|
27
|
+
@player.health.should == @initial_health + (8 * 15)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'studio_game/clumsy_player'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
describe ClumsyPlayer do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@player = ClumsyPlayer.new("klutz")
|
8
|
+
end
|
9
|
+
|
10
|
+
context "with a boost factor" do
|
11
|
+
before do
|
12
|
+
@initial_health = 100
|
13
|
+
@boost_factor = 5
|
14
|
+
@player = ClumsyPlayer.new("klutz", @initial_health, @boost_factor)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "has a boost factor" do
|
18
|
+
@player.boost_factor.should == 5
|
19
|
+
end
|
20
|
+
|
21
|
+
it "gets 'boost factor' number of w00ts when w00ted" do
|
22
|
+
@player.w00t
|
23
|
+
|
24
|
+
@player.health.should == @initial_health + (15 * @boost_factor)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "only gets half the point value for each treasure" do
|
29
|
+
@player.points.should == 0
|
30
|
+
|
31
|
+
hammer = Treasure.new(:hammer, 50)
|
32
|
+
@player.found_treasure(hammer)
|
33
|
+
@player.found_treasure(hammer)
|
34
|
+
@player.found_treasure(hammer)
|
35
|
+
|
36
|
+
@player.points.should == 75
|
37
|
+
|
38
|
+
crowbar = Treasure.new(:crowbar, 400)
|
39
|
+
@player.found_treasure(crowbar)
|
40
|
+
|
41
|
+
@player.points.should == 275
|
42
|
+
|
43
|
+
yielded = []
|
44
|
+
@player.each_found_treasure do |treasure|
|
45
|
+
yielded << treasure
|
46
|
+
end
|
47
|
+
|
48
|
+
yielded.should == [Treasure.new(:hammer, 75), Treasure.new(:crowbar, 200)]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'studio_game/game'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
describe Game do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@game = Game.new("Knuckleheads")
|
8
|
+
|
9
|
+
@initial_health = 100
|
10
|
+
@player = Player.new("moe", @initial_health)
|
11
|
+
|
12
|
+
@game.add_player(@player)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "computes total points as the sum of all player points" do
|
16
|
+
game = Game.new("Knuckleheads")
|
17
|
+
|
18
|
+
player1 = Player.new("moe")
|
19
|
+
player2 = Player.new("larry")
|
20
|
+
|
21
|
+
game.add_player(player1)
|
22
|
+
game.add_player(player2)
|
23
|
+
|
24
|
+
player1.found_treasure(Treasure.new(:hammer, 50))
|
25
|
+
player1.found_treasure(Treasure.new(:hammer, 50))
|
26
|
+
player2.found_treasure(Treasure.new(:crowbar, 400))
|
27
|
+
|
28
|
+
game.total_points.should == 500
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
it "assigns a treasure for points during a player's turn" do
|
33
|
+
@game.play(1)
|
34
|
+
|
35
|
+
@player.points.should_not be_zero
|
36
|
+
end
|
37
|
+
|
38
|
+
it "w00tes the player if high number is rolled" do
|
39
|
+
Die.any_instance.stub(:roll).and_return(5)
|
40
|
+
|
41
|
+
@game.play(2)
|
42
|
+
|
43
|
+
@player.health.should == @initial_health + (15 *2)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "skips the player if medium number is rolled" do
|
47
|
+
Die.any_instance.stub(:roll).and_return(3)
|
48
|
+
|
49
|
+
@game.play(2)
|
50
|
+
|
51
|
+
@player.health.should == @initial_health
|
52
|
+
end
|
53
|
+
|
54
|
+
it "blams the player if low number is rolled" do
|
55
|
+
Die.any_instance.stub(:roll).and_return(1)
|
56
|
+
|
57
|
+
@game.play(2)
|
58
|
+
|
59
|
+
@player.health.should == @initial_health - (10 *2)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'studio_game/player'
|
2
|
+
require 'studio_game/treasure_trove.rb'
|
3
|
+
|
4
|
+
module StudioGame
|
5
|
+
describe Player do
|
6
|
+
|
7
|
+
it "can be created from a csv string" do
|
8
|
+
player = Player.from_csv("Larry, 150")
|
9
|
+
|
10
|
+
player.name.should == "Larry"
|
11
|
+
player.health.should == 150
|
12
|
+
end
|
13
|
+
|
14
|
+
context "in a treasure hunt" do
|
15
|
+
before do
|
16
|
+
@player = Player.new("moe", 100)
|
17
|
+
end
|
18
|
+
it "computes points as the sum of all treasure points" do
|
19
|
+
@player.points.should == 0
|
20
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
21
|
+
@player.points.should == 50
|
22
|
+
@player.found_treasure(Treasure.new(:crowbar, 400))
|
23
|
+
@player.points.should == 450
|
24
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
25
|
+
@player.points.should == 500
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "in a collection of players" do
|
30
|
+
before do
|
31
|
+
@player1 = Player.new("moe", 100)
|
32
|
+
@player2 = Player.new("larry",100)
|
33
|
+
@player3 = Player.new("curly", 300)
|
34
|
+
|
35
|
+
@players = [@player1, @player2, @player3]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "is sorted by decreasing score" do
|
39
|
+
@players.sort.should == [@player3, @player2, @player1]
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with a health greater than 100" do
|
44
|
+
before do
|
45
|
+
@player = Player.new("larry", 150)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "is strong" do
|
49
|
+
@player.should be_strong
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "with a health of 100 or less" do
|
54
|
+
before do
|
55
|
+
@player = Player.new("larry", 100)
|
56
|
+
end
|
57
|
+
it "is wimpy" do
|
58
|
+
@player.should_not be_strong
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
before do
|
63
|
+
@initial_health = 150
|
64
|
+
@player = Player.new("larry", @initial_health)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "yields each found treasure and its total points" do
|
68
|
+
@player.found_treasure(Treasure.new(:skillet, 100))
|
69
|
+
@player.found_treasure(Treasure.new(:skillet, 100))
|
70
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
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
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
76
|
+
|
77
|
+
yielded = []
|
78
|
+
@player.each_found_treasure do |treasure|
|
79
|
+
yielded << treasure
|
80
|
+
end
|
81
|
+
|
82
|
+
yielded.should == [
|
83
|
+
Treasure.new(:skillet, 200),
|
84
|
+
Treasure.new(:hammer, 50),
|
85
|
+
Treasure.new(:bottle, 25)
|
86
|
+
]
|
87
|
+
end
|
88
|
+
|
89
|
+
it "has a capitalized name" do
|
90
|
+
@player.name.should == "Larry"
|
91
|
+
end
|
92
|
+
|
93
|
+
it "has a initial health" do
|
94
|
+
@player.health.should == 150
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
it "has default initial health of 100" do
|
99
|
+
@player = Player.new("larry")
|
100
|
+
@player.health.should == 100
|
101
|
+
end
|
102
|
+
|
103
|
+
it "has a string representation" do
|
104
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
105
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
106
|
+
|
107
|
+
@player.to_s.should == "I'm Larry with health = 150, points = 100, and score = 250."
|
108
|
+
end
|
109
|
+
|
110
|
+
it "computes a score as the sum of its health and points" do
|
111
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
112
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
113
|
+
|
114
|
+
@player.score.should == 250
|
115
|
+
end
|
116
|
+
|
117
|
+
it "increases health by 15 when w00ted" do
|
118
|
+
@player.w00t
|
119
|
+
@player.health.should == (@initial_health + 15)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "decreases health by 10 when blammed" do
|
123
|
+
@player.blam
|
124
|
+
@player.health.should == (@initial_health - 10)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'studio_game/treasure_trove'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
describe Treasure do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@treasure = Treasure.new(:hammer, 50)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "has a name attribute" do
|
11
|
+
@treasure.name.should == :hammer
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a points attribute" do
|
15
|
+
@treasure.points.should == 50
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
describe TreasureTrove do
|
21
|
+
|
22
|
+
it "returns a random treasure" do
|
23
|
+
treasure = TreasureTrove.random
|
24
|
+
|
25
|
+
TreasureTrove::TREASURES.should include(treasure)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "has six treasures" do
|
29
|
+
TreasureTrove::TREASURES.size.should == 6
|
30
|
+
end
|
31
|
+
|
32
|
+
it "has a pie worth 5 points" do
|
33
|
+
TreasureTrove::TREASURES[0].should == Treasure.new(:pie, 5)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "has a bottle worth 25 points" do
|
37
|
+
TreasureTrove::TREASURES[1].should == Treasure.new(:bottle, 25)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "has a hammer worth 50 points" do
|
41
|
+
TreasureTrove::TREASURES[2].should == Treasure.new(:hammer, 50)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "has a skillet worth 100 points" do
|
45
|
+
TreasureTrove::TREASURES[3].should == Treasure.new(:skillet, 100)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "has a broomstick worth 200 points" do
|
49
|
+
TreasureTrove::TREASURES[4].should == Treasure.new(:broomstick, 200)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "has a crowbar worth 400 points" do
|
53
|
+
TreasureTrove::TREASURES[5].should == Treasure.new(:crowbar, 400)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: studio_game_dilip
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dilip Deodhar
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-06-13 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: ! "This a simple game where virtual players compete to find treasures.
|
31
|
+
\nHealth of the players is importatnt. The players may get blammed \nor get w00ted.
|
32
|
+
\n\n- To start the game on command line: \n studiogame.rb <csv file, containing
|
33
|
+
a list of players>\n if the optional csv file is not provided, the game will use
|
34
|
+
the \n default file called 'players.csv'.\n- Example of csv list of players (name
|
35
|
+
& health): \nAlvin,100\nSimon,60\nTheo,125\n\n- The game will ask, how many game
|
36
|
+
rounds to play. \n Enter the number of rounds or enter 'quit' or 'exit' to stop
|
37
|
+
the game.\n\n- The game, at the end, will print out the game statistics and high
|
38
|
+
scores. \nIt will also create a file containing the high scores."
|
39
|
+
email: dilipd.US@gmail.com
|
40
|
+
executables:
|
41
|
+
- studio_game
|
42
|
+
extensions: []
|
43
|
+
extra_rdoc_files: []
|
44
|
+
files:
|
45
|
+
- bin/players.csv
|
46
|
+
- bin/high_scores.txt
|
47
|
+
- bin/studio_game
|
48
|
+
- bin/studio_game.rb~
|
49
|
+
- bin/my_favorite_players.csv
|
50
|
+
- lib/studio_game/game.rb~
|
51
|
+
- lib/studio_game/player.rb
|
52
|
+
- lib/studio_game/die.rb
|
53
|
+
- lib/studio_game/treasure_trove.rb
|
54
|
+
- lib/studio_game/berserk_player.rb
|
55
|
+
- lib/studio_game/playable.rb
|
56
|
+
- lib/studio_game/clumsy_player.rb
|
57
|
+
- lib/studio_game/game_turn.rb
|
58
|
+
- lib/studio_game/player.rb~
|
59
|
+
- lib/studio_game/game.rb
|
60
|
+
- lib/studio_game/auditable.rb
|
61
|
+
- lib/studio_game/loaded_die.rb
|
62
|
+
- spec/studio_game/player_spec.rb
|
63
|
+
- spec/studio_game/high_scores.txt
|
64
|
+
- spec/studio_game/berserk_player_spec.rb
|
65
|
+
- spec/studio_game/player_spec.rb~
|
66
|
+
- spec/studio_game/game_spec.rb
|
67
|
+
- spec/studio_game/clumsy_player_spec.rb
|
68
|
+
- spec/studio_game/treasure_trove_spec.rb
|
69
|
+
- LICENSE
|
70
|
+
- README
|
71
|
+
homepage: ''
|
72
|
+
licenses: []
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.9'
|
83
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ! '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.8.24
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: A game with traesure hunt
|
95
|
+
test_files:
|
96
|
+
- spec/studio_game/player_spec.rb
|
97
|
+
- spec/studio_game/high_scores.txt
|
98
|
+
- spec/studio_game/berserk_player_spec.rb
|
99
|
+
- spec/studio_game/player_spec.rb~
|
100
|
+
- spec/studio_game/game_spec.rb
|
101
|
+
- spec/studio_game/clumsy_player_spec.rb
|
102
|
+
- spec/studio_game/treasure_trove_spec.rb
|
103
|
+
has_rdoc:
|