dcaba_studio_game 0.1.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.
- checksums.yaml +7 -0
- data/LICENSE +1 -0
- data/README +1 -0
- data/bin/Game with tens of players.out +112 -0
- data/bin/csv game!.out +6 -0
- data/bin/dani_players.csv +3 -0
- data/bin/myGame!.out +7 -0
- data/bin/players.csv +3 -0
- data/bin/studio_game +134 -0
- data/lib/studio_game/auditable.rb +7 -0
- data/lib/studio_game/berserk_player.rb +30 -0
- data/lib/studio_game/clumsy_player.rb +28 -0
- data/lib/studio_game/die.rb +16 -0
- data/lib/studio_game/game.rb +150 -0
- data/lib/studio_game/game_turn.rb +25 -0
- data/lib/studio_game/loaded_die.rb +14 -0
- data/lib/studio_game/playable.rb +17 -0
- data/lib/studio_game/player.rb +64 -0
- data/lib/studio_game/treasure_trove.rb +22 -0
- data/spec/studio_game/berserk_player_spec.rb +32 -0
- data/spec/studio_game/clumsy_player_spec.rb +32 -0
- data/spec/studio_game/game_spec.rb +118 -0
- data/spec/studio_game/game_spec_players.csv +3 -0
- data/spec/studio_game/game_spec_save.out +3 -0
- data/spec/studio_game/player_spec.rb +126 -0
- data/spec/studio_game/treasure_trove_spec.rb +59 -0
- metadata +90 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 1aa8a6e47aa0d82d4b96ba0489fbd186e5abd16e
|
4
|
+
data.tar.gz: 200c6818f74ff56b74a5eefa36ac84f557045434
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9251f0dea9509472f10f85d2d37fdaa171ceae37348d725239a7ada753630b9ee5c841a3353b0dc70067b8ffaa54dddbc94652521091e9fd7ceae1eaa26995f2
|
7
|
+
data.tar.gz: e9cc07a85615eeeb919acfdedc421d3709e5063c0fa9492390dcd0c77f863d3ee7725667fe06fdbb3960e1a15948296638c5e17d875d13afe4f1b15a33f8e467
|
data/LICENSE
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
MIT license
|
data/README
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Code developed to follow Pragmatic Studio's Ruby training!!
|
@@ -0,0 +1,112 @@
|
|
1
|
+
Game with tens of players High Scores:
|
2
|
+
Jv5gniw............. 597
|
3
|
+
Lulysic............. 563
|
4
|
+
Fgh4dlo............. 529
|
5
|
+
Ypjcfec............. 529
|
6
|
+
Ffyowbg............. 516
|
7
|
+
Gi2ivsc............. 508
|
8
|
+
13fgszu............. 493
|
9
|
+
+2.................. 490
|
10
|
+
84poqcm............. 469
|
11
|
+
9lao69e............. 463
|
12
|
+
V24ecce............. 444
|
13
|
+
G9xp7c4............. 444
|
14
|
+
7sywho0............. 432
|
15
|
+
Hx0es7k............. 429
|
16
|
+
Ddbgs0o............. 420
|
17
|
+
Qzg_qh8............. 409
|
18
|
+
Zuazbsc............. 403
|
19
|
+
2zotsf0............. 402
|
20
|
+
_kfcqr4............. 402
|
21
|
+
7bqplqk............. 383
|
22
|
+
Wlfd0bq............. 378
|
23
|
+
Aa-r9hk............. 363
|
24
|
+
Fhd7fvs............. 360
|
25
|
+
Aivp2c0............. 346
|
26
|
+
T3mznqy............. 342
|
27
|
+
Qnh8fxk............. 333
|
28
|
+
Ji3am_g............. 333
|
29
|
+
J11z9xm............. 331
|
30
|
+
Rrtpjvi............. 327
|
31
|
+
-3.................. 317.0
|
32
|
+
Qxmnjha............. 308
|
33
|
+
Tiz84zs............. 301
|
34
|
+
+4.................. 300
|
35
|
+
Bb2kehw............. 299
|
36
|
+
Gxc9xsi............. 295
|
37
|
+
Sb0zx2e............. 290
|
38
|
+
Jewyw9o............. 289
|
39
|
+
9isl8no............. 279
|
40
|
+
R9qaw3m............. 278
|
41
|
+
Ivlzplw............. 273
|
42
|
+
Rd1-vyc............. 235
|
43
|
+
Udz8dhs............. 226
|
44
|
+
8i_3abu............. 216
|
45
|
+
0qxluvu............. 216
|
46
|
+
Jz4s-_c............. 215
|
47
|
+
Mswzvks............. 204
|
48
|
+
I-mprni............. 203
|
49
|
+
Lmchzha............. 201
|
50
|
+
+5.................. 200
|
51
|
+
Oxxe2eo............. 198
|
52
|
+
Tmfxzdm............. 191
|
53
|
+
Njj8u4c............. 189
|
54
|
+
5qk7xhu............. 189
|
55
|
+
W5yg8ik............. 187
|
56
|
+
Fc0hana............. 185
|
57
|
+
-jaafx4............. 182
|
58
|
+
Ujl3y98............. 171
|
59
|
+
Cpyu9tm............. 164
|
60
|
+
Ydzoefi............. 163
|
61
|
+
2niwwvw............. 163
|
62
|
+
1vcqosm............. 163
|
63
|
+
0mtdya0............. 162
|
64
|
+
M-uunri............. 162
|
65
|
+
Onuepjs............. 161
|
66
|
+
Y96bt10............. 159
|
67
|
+
-5.................. 156.0
|
68
|
+
Fty8k1w............. 152
|
69
|
+
Kv8bjc8............. 152
|
70
|
+
Aebsxq4............. 146
|
71
|
+
H92wrm0............. 145
|
72
|
+
-0.................. 144.0
|
73
|
+
Yquhwba............. 143
|
74
|
+
+0.................. 140
|
75
|
+
Dv-pwxw............. 139
|
76
|
+
0isguj8............. 135
|
77
|
+
G2_jjas............. 134
|
78
|
+
-6.................. 132.0
|
79
|
+
I_nehz8............. 128
|
80
|
+
Iflxvrs............. 128
|
81
|
+
O_2g_7m............. 127
|
82
|
+
Wrizwvu............. 127
|
83
|
+
7vrrt6u............. 124
|
84
|
+
P_kcu9w............. 124
|
85
|
+
H1r9z94............. 124
|
86
|
+
+1.................. 120
|
87
|
+
+3.................. 120
|
88
|
+
Epgvzt0............. 119
|
89
|
+
Iqrq2d8............. 114
|
90
|
+
-4.................. 109.5
|
91
|
+
Unpkw8y............. 99
|
92
|
+
6gzpoo4............. 98
|
93
|
+
Cxglm3y............. 98
|
94
|
+
Chmscfw............. 98
|
95
|
+
Tuiczdu............. 88
|
96
|
+
1ijfucm............. 84
|
97
|
+
Pi6nqje............. 83
|
98
|
+
Vnofs7i............. 80
|
99
|
+
Whohc_c............. 79
|
100
|
+
7b_bsts............. 74
|
101
|
+
Atf-oom............. 63
|
102
|
+
X2hff-k............. 61
|
103
|
+
-2.................. 55.5
|
104
|
+
Ty1lcni............. 51
|
105
|
+
Um3urzc............. 50
|
106
|
+
D6bqb_c............. 49
|
107
|
+
Pog04xu............. 42
|
108
|
+
Yap0c10............. 41
|
109
|
+
Imzzw0m............. 41
|
110
|
+
Crhnwja............. 33
|
111
|
+
Epa5trc............. 12
|
112
|
+
-1.................. -2.5
|
data/bin/csv game!.out
ADDED
data/bin/myGame!.out
ADDED
data/bin/players.csv
ADDED
data/bin/studio_game
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/studio_game/player'
|
4
|
+
require_relative '../lib/studio_game/clumsy_player'
|
5
|
+
require_relative '../lib/studio_game/berserk_player'
|
6
|
+
require_relative '../lib/studio_game/game'
|
7
|
+
|
8
|
+
def play_games
|
9
|
+
$games << game1($rounds)
|
10
|
+
$games << game2($rounds)
|
11
|
+
$games << game3($rounds,$csv_param)
|
12
|
+
end
|
13
|
+
|
14
|
+
def user_interact()
|
15
|
+
loop do
|
16
|
+
puts "How many game rounds? ('quit' to exit)"
|
17
|
+
answer = gets.chomp.downcase
|
18
|
+
case answer
|
19
|
+
when /^\d+$/
|
20
|
+
$rounds = answer.to_i
|
21
|
+
play_games
|
22
|
+
when "quit","exit","q"
|
23
|
+
break
|
24
|
+
else
|
25
|
+
puts "Please enter a number or 'quit'"
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def initialize_program()
|
32
|
+
$init_time = Time.now
|
33
|
+
$parms = ARGV.size
|
34
|
+
$csv_param = (ARGV.shift || File.join(File.dirname(__FILE__),"players.csv"))
|
35
|
+
$rounds = (ARGV.shift.to_i || 1)
|
36
|
+
$games = Array.new
|
37
|
+
welcome_message="Game starting at #{time} - invoked with #{$csv_param} and rounds #{$rounds}"
|
38
|
+
puts "".center(80,"#")
|
39
|
+
puts welcome_message.center(80,"#")
|
40
|
+
puts "".center(80,"#")
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def finish_program
|
45
|
+
bye_message="Game finished at #{time}...saving stats"
|
46
|
+
puts "".center(80,"#")
|
47
|
+
puts bye_message.center(80,"#")
|
48
|
+
puts "".center(80,"#")
|
49
|
+
$games.each {|game| game.save_high_scores File.join(File.dirname(__FILE__),"#{game.title}.out")}
|
50
|
+
puts "stats saved"
|
51
|
+
puts "EXECUTION TIME: #{((Time.now - $init_time)*1000000).to_i} micro-seconds"
|
52
|
+
end
|
53
|
+
|
54
|
+
def time
|
55
|
+
Time.now.strftime "%H:%M:%S"
|
56
|
+
end
|
57
|
+
|
58
|
+
def game1_players
|
59
|
+
players_data=[["larry",60],["curly",120],["moe",100],["shemp",90],["dani"]]
|
60
|
+
players = Array.new
|
61
|
+
|
62
|
+
players_data.each do |name,health|
|
63
|
+
player = StudioGame::Player.new(name,health)
|
64
|
+
players << player
|
65
|
+
puts "player has been processed: #{player}"
|
66
|
+
end
|
67
|
+
return players
|
68
|
+
end
|
69
|
+
|
70
|
+
def game1(rounds=1)
|
71
|
+
my_game = StudioGame::Game.new "myGame!"
|
72
|
+
players = game1_players
|
73
|
+
my_game.load_players(players)
|
74
|
+
puts "Players have been imported. There are #{my_game.players.size} players in the game"
|
75
|
+
|
76
|
+
puts "Adding a random player"
|
77
|
+
my_game.add_player(StudioGame::Player.new)
|
78
|
+
puts "Done"
|
79
|
+
|
80
|
+
puts "Game title: #{my_game.title}"
|
81
|
+
my_game.print_players
|
82
|
+
my_game.print_players("health")
|
83
|
+
|
84
|
+
my_game.play rounds
|
85
|
+
|
86
|
+
puts "The winner of #{my_game.title} was... #{my_game.winner}".center(160,"*")
|
87
|
+
return my_game
|
88
|
+
end
|
89
|
+
|
90
|
+
def game2(rounds=1)
|
91
|
+
my_game2 = StudioGame::Game.new "Game with tens of players"
|
92
|
+
|
93
|
+
puts "Adding random players"
|
94
|
+
rand(50..150).times do
|
95
|
+
my_game2.add_player
|
96
|
+
end
|
97
|
+
rand(1..10).times { |time| my_game2.add_player(StudioGame::ClumsyPlayer.new("-#{time}")) }
|
98
|
+
rand(1..10).times { |time| my_game2.add_player(StudioGame::BerserkPlayer.new("+#{time}")) }
|
99
|
+
puts ".. Done"
|
100
|
+
|
101
|
+
puts "Game title: #{my_game2.title}"
|
102
|
+
my_game2.print_players
|
103
|
+
my_game2.play rounds
|
104
|
+
puts "The winner of #{my_game2.title} was... #{my_game2.winner}".center(160,"*")
|
105
|
+
return my_game2
|
106
|
+
end
|
107
|
+
|
108
|
+
def game3(rounds=1,player_file)
|
109
|
+
my_game = StudioGame::Game.new "csv game!"
|
110
|
+
my_game.load_players(player_file)
|
111
|
+
my_game.add_player(StudioGame::ClumsyPlayer.new("-clumsy"))
|
112
|
+
my_game.add_player(StudioGame::BerserkPlayer.new("+berserk"))
|
113
|
+
puts "Players have been imported. There are #{my_game.players.size} players in the game"
|
114
|
+
|
115
|
+
puts "Game title: #{my_game.title}"
|
116
|
+
my_game.print_players
|
117
|
+
|
118
|
+
my_game.play rounds
|
119
|
+
|
120
|
+
puts "The winner of #{my_game.title} was... #{my_game.winner}".center(160,"*")
|
121
|
+
return my_game
|
122
|
+
end
|
123
|
+
|
124
|
+
#
|
125
|
+
# MAIN
|
126
|
+
#
|
127
|
+
initialize_program()
|
128
|
+
case $parms
|
129
|
+
when 2
|
130
|
+
play_games
|
131
|
+
else
|
132
|
+
user_interact()
|
133
|
+
end
|
134
|
+
finish_program
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
|
5
|
+
BERSERK_THRESHOLD = 5
|
6
|
+
|
7
|
+
class BerserkPlayer < Player
|
8
|
+
def initialize(name,health=100)
|
9
|
+
@w00t_count=0
|
10
|
+
super(name,health)
|
11
|
+
end
|
12
|
+
def berserk?
|
13
|
+
return @w00t_count > BERSERK_THRESHOLD
|
14
|
+
end
|
15
|
+
def w00t
|
16
|
+
@w00t_count += 1
|
17
|
+
puts "#{@name} becaming berserk!!!!" if @w00t_count == BERSERK_THRESHOLD+1
|
18
|
+
super
|
19
|
+
end
|
20
|
+
def blam
|
21
|
+
berserk? ? w00t : super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
if __FILE__ == $0
|
25
|
+
berserker = BerserkPlayer.new("berserker", 50)
|
26
|
+
6.times { berserker.w00t }
|
27
|
+
2.times { berserker.blam }
|
28
|
+
puts berserker.health
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
require_relative 'treasure_trove'
|
3
|
+
|
4
|
+
module StudioGame
|
5
|
+
|
6
|
+
class ClumsyPlayer < Player
|
7
|
+
def found_treasure(treasure)
|
8
|
+
super Treasure.new(treasure.name,treasure.points/2.0)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
if __FILE__ == $0
|
13
|
+
clumsy = ClumsyPlayer.new("klutz")
|
14
|
+
|
15
|
+
hammer = Treasure.new(:hammer, 50)
|
16
|
+
clumsy.found_treasure(hammer)
|
17
|
+
clumsy.found_treasure(hammer)
|
18
|
+
clumsy.found_treasure(hammer)
|
19
|
+
|
20
|
+
crowbar = Treasure.new(:crowbar, 400)
|
21
|
+
clumsy.found_treasure(crowbar)
|
22
|
+
|
23
|
+
clumsy.each_found_treasure do |treasure|
|
24
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
25
|
+
end
|
26
|
+
puts "#{clumsy.points} grand total points"
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
require_relative 'game_turn'
|
3
|
+
require_relative 'treasure_trove'
|
4
|
+
|
5
|
+
module StudioGame
|
6
|
+
class Game
|
7
|
+
attr_accessor :players,:title
|
8
|
+
|
9
|
+
def initialize(name)
|
10
|
+
@title = name
|
11
|
+
@players = Array.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_player(player=Player.new)
|
15
|
+
@players << player
|
16
|
+
end
|
17
|
+
|
18
|
+
def load_players(players_import)
|
19
|
+
case players_import
|
20
|
+
when Array
|
21
|
+
@players = players_import.clone
|
22
|
+
when String
|
23
|
+
File.open(players_import) do |file|
|
24
|
+
file.each_line {|line| add_player(Player.from_csv(line))}
|
25
|
+
end
|
26
|
+
else
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_player_by_name(name)
|
31
|
+
players_with_name = @players.select {|player| player.name.downcase == name.downcase}
|
32
|
+
players_with_name.first
|
33
|
+
end
|
34
|
+
|
35
|
+
def winner
|
36
|
+
@players.sort {|x,y| y.score <=> x.score}.first
|
37
|
+
end
|
38
|
+
|
39
|
+
def print_players(scope="all")
|
40
|
+
case scope
|
41
|
+
when "all"
|
42
|
+
puts "Players information".center(80,"*")
|
43
|
+
@players.each do |player|
|
44
|
+
case player.name.downcase
|
45
|
+
when "larry"
|
46
|
+
puts "\t #{player.name.capitalize} has a health of #{player.health}."
|
47
|
+
when "curly"
|
48
|
+
puts "\t #{player.name.upcase} has a health of #{player.health}."
|
49
|
+
when "moe"
|
50
|
+
puts "\t "+"#{player.name.capitalize} has a health of #{player.health}.".center(40,"*")
|
51
|
+
when "shemp"
|
52
|
+
puts "\t #{player.name.capitalize.ljust(20,".")} health #{player.health}."
|
53
|
+
else
|
54
|
+
puts "\t #{player.name} \n"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
when "health"
|
58
|
+
puts report_health
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def report_health
|
63
|
+
message = "Health report".center(80,"*") + "\n"
|
64
|
+
@players.each do |player|
|
65
|
+
message << "\t#{player.health}\n"
|
66
|
+
end
|
67
|
+
return message
|
68
|
+
end
|
69
|
+
private :report_health
|
70
|
+
|
71
|
+
def print_player_for_report(player,param=:health)
|
72
|
+
"\t"+"#{player.name}".ljust(20,".")+" #{player.public_send(param)}\n"
|
73
|
+
end
|
74
|
+
private :print_player_for_report
|
75
|
+
|
76
|
+
def report_strong_wimpy
|
77
|
+
message="#{@title} Statistics:\n"
|
78
|
+
strong,wimpy=@players.partition{|x| x.strong?}
|
79
|
+
message << "\n#{strong.size} strong players:\n"
|
80
|
+
strong.each {|player| message << print_player_for_report(player,:health)}
|
81
|
+
message << "\n#{wimpy.size} wimpy players:\n"
|
82
|
+
wimpy.each {|player| message << print_player_for_report(player,:health)}
|
83
|
+
return message
|
84
|
+
end
|
85
|
+
def report_high_scores
|
86
|
+
message="#{@title} High Scores:\n"
|
87
|
+
players.sort.each {|player| message << print_player_for_report(player,:score)}
|
88
|
+
return message
|
89
|
+
end
|
90
|
+
def report_per_treasure_points(player)
|
91
|
+
message = String.new
|
92
|
+
player.each_found_treasure do |treasure|
|
93
|
+
message << "#{treasure.name} total #{treasure.points} points\n"
|
94
|
+
end
|
95
|
+
return message
|
96
|
+
end
|
97
|
+
def report_total_points
|
98
|
+
message="#{@title} Total points:\n"
|
99
|
+
@players.each { |player|
|
100
|
+
message << "\t#{player.name}'s point totals:\n"
|
101
|
+
rptr = report_per_treasure_points(player)
|
102
|
+
(rptr.lines.each { |line| message << "\t\t" + line}) unless rptr.size == 0
|
103
|
+
message << "\t\t#{player.points} grand total points\n"
|
104
|
+
}
|
105
|
+
return message
|
106
|
+
end
|
107
|
+
|
108
|
+
def print_stats
|
109
|
+
message = String.new
|
110
|
+
message << report_strong_wimpy
|
111
|
+
message << report_high_scores
|
112
|
+
message << report_total_points
|
113
|
+
return message
|
114
|
+
end
|
115
|
+
|
116
|
+
def save_high_scores(filename="high_scores.txt")
|
117
|
+
File.open(filename,'w') do |file|
|
118
|
+
file.puts report_high_scores
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def play(rounds=1)
|
123
|
+
puts "Starting to play!".center(80,"*")+"\n"
|
124
|
+
puts "Treasures recollection"
|
125
|
+
treasures=TreasureTrove::TREASURES
|
126
|
+
puts "Counting on the following #{treasures.size} treasures:"
|
127
|
+
treasures.each {|treasure| puts "\t#{treasure}"}
|
128
|
+
puts "Now we are playing with #{title} and #{players.size} players".center(80,"*")
|
129
|
+
rounds.times do |round|
|
130
|
+
puts "Round number: #{round+1}"
|
131
|
+
@players.each do |player|
|
132
|
+
puts "-Before playing: #{player}"
|
133
|
+
GameTurn.take_turn(player)
|
134
|
+
puts "-After playing: #{player}"
|
135
|
+
end
|
136
|
+
end
|
137
|
+
puts print_stats
|
138
|
+
puts "Play finished!".center(80,"*")+"\n"
|
139
|
+
end
|
140
|
+
|
141
|
+
end
|
142
|
+
|
143
|
+
if __FILE__ == $0
|
144
|
+
puts "Executing this class"
|
145
|
+
test_game = Game.new("test Game")
|
146
|
+
test_game.play
|
147
|
+
test_game.add_player(Player.new)
|
148
|
+
test_game.play
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative 'die'
|
2
|
+
#require_relative 'loaded_die'
|
3
|
+
require_relative 'player'
|
4
|
+
require_relative 'treasure_trove'
|
5
|
+
|
6
|
+
module StudioGame
|
7
|
+
module GameTurn
|
8
|
+
def self.take_turn(player)
|
9
|
+
die = Die.new
|
10
|
+
case die.roll
|
11
|
+
when 1..2
|
12
|
+
puts "\t"+player.blam
|
13
|
+
when 5..6
|
14
|
+
puts "\t"+player.w00t
|
15
|
+
else
|
16
|
+
puts "\tPlayer #{player.name} skipped"
|
17
|
+
end
|
18
|
+
treasure_mgmt(player)
|
19
|
+
end
|
20
|
+
def self.treasure_mgmt(player)
|
21
|
+
found_treasure = TreasureTrove::random
|
22
|
+
player.found_treasure(found_treasure)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require_relative 'treasure_trove'
|
3
|
+
require_relative 'playable'
|
4
|
+
|
5
|
+
module StudioGame
|
6
|
+
class Player
|
7
|
+
attr_reader :health
|
8
|
+
attr_accessor :name
|
9
|
+
include Playable
|
10
|
+
|
11
|
+
def initialize (name=SecureRandom.urlsafe_base64(5), health=rand(1..200))
|
12
|
+
@name = name.capitalize
|
13
|
+
@health = health
|
14
|
+
@health=rand(200) if health.nil? == true
|
15
|
+
@found_treasures = Hash.new(0)
|
16
|
+
end
|
17
|
+
def self.from_csv(line)
|
18
|
+
name,health=line.split(",")
|
19
|
+
new(name,Integer(health))
|
20
|
+
end
|
21
|
+
|
22
|
+
def found_treasure(treasure)
|
23
|
+
@found_treasures[treasure.name] += treasure.points
|
24
|
+
puts "#{name} found a #{treasure}"
|
25
|
+
puts "#{name} treasures:#{@found_treasures}"
|
26
|
+
end
|
27
|
+
def each_found_treasure
|
28
|
+
@found_treasures.each do |key,value|
|
29
|
+
yield Treasure.new(key,value)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def score
|
34
|
+
@health + points
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s()
|
38
|
+
"I'm #{@name} with health = #{@health}, points = #{points}, and score = #{score} as of #{StudioGame::time}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def <=>(x)
|
42
|
+
x.score <=> score
|
43
|
+
end
|
44
|
+
def points
|
45
|
+
@found_treasures.values.reduce(0,:+)
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.time
|
51
|
+
Time.now.strftime "%H:%M:%S"
|
52
|
+
end
|
53
|
+
|
54
|
+
if __FILE__ == $0
|
55
|
+
player = Player.new("moe")
|
56
|
+
puts player.name
|
57
|
+
puts player.health
|
58
|
+
player.w00t
|
59
|
+
puts player.health
|
60
|
+
player.blam
|
61
|
+
puts player.health
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module StudioGame
|
2
|
+
Treasure = Struct.new(:name,:points)
|
3
|
+
class Treasure
|
4
|
+
def to_s
|
5
|
+
"treasure #{name} worth #{points} points"
|
6
|
+
end
|
7
|
+
end
|
8
|
+
module TreasureTrove
|
9
|
+
TREASURES = [
|
10
|
+
Treasure.new(:pie,5),
|
11
|
+
Treasure.new(:bottle,25),
|
12
|
+
Treasure.new(:hammer,50),
|
13
|
+
Treasure.new(:skillet,100),
|
14
|
+
Treasure.new(:broomstick,200),
|
15
|
+
Treasure.new(:crowbar,400)
|
16
|
+
]
|
17
|
+
def self.random
|
18
|
+
TREASURES.sample
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'studio_game/berserk_player'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
describe BerserkPlayer do
|
5
|
+
|
6
|
+
before do
|
7
|
+
$stdout = StringIO.new
|
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
|
+
expect(@player).not_to be_berserk
|
16
|
+
end
|
17
|
+
|
18
|
+
it "goes berserk when w00ted more than 5 times" do
|
19
|
+
1.upto(6) { @player.w00t }
|
20
|
+
|
21
|
+
expect(@player).to be_berserk
|
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
|
+
expect(@player.health).to be == @initial_health + (8 * 15)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'studio_game/clumsy_player'
|
2
|
+
|
3
|
+
module StudioGame
|
4
|
+
describe ClumsyPlayer do
|
5
|
+
before do
|
6
|
+
@player = ClumsyPlayer.new("klutz")
|
7
|
+
$stdout = StringIO.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "only gets half the point value for each treasure" do
|
11
|
+
expect(@player.points).to be == 0
|
12
|
+
|
13
|
+
hammer = Treasure.new(:hammer, 50)
|
14
|
+
3.times { @player.found_treasure(hammer) }
|
15
|
+
|
16
|
+
expect(@player.points).to be == 75
|
17
|
+
|
18
|
+
crowbar = Treasure.new(:crowbar, 400)
|
19
|
+
@player.found_treasure(crowbar)
|
20
|
+
|
21
|
+
expect(@player.points).to be == 275
|
22
|
+
|
23
|
+
yielded = []
|
24
|
+
@player.each_found_treasure do |treasure|
|
25
|
+
yielded << treasure
|
26
|
+
end
|
27
|
+
|
28
|
+
expect(yielded).to be == [Treasure.new(:hammer, 75), Treasure.new(:crowbar, 200)]
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'studio_game/game'
|
2
|
+
require 'studio_game/player'
|
3
|
+
require 'studio_game/die'
|
4
|
+
|
5
|
+
module StudioGame
|
6
|
+
describe Game do
|
7
|
+
before do
|
8
|
+
$stdout = StringIO.new
|
9
|
+
@game = Game.new("Knuckleheads")
|
10
|
+
|
11
|
+
@initial_health = 100
|
12
|
+
@tested_player_name = "moe"
|
13
|
+
@game.add_player
|
14
|
+
@game.add_player(Player.new(@tested_player_name, @initial_health))
|
15
|
+
@game.add_player
|
16
|
+
end
|
17
|
+
|
18
|
+
it "contains the expected player" do
|
19
|
+
expect(@game.get_player_by_name("moe").name).to be == "Moe"
|
20
|
+
end
|
21
|
+
|
22
|
+
it "increases the health when rolling a high number" do
|
23
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(5)
|
24
|
+
@game.play
|
25
|
+
tested_player = @game.get_player_by_name("moe")
|
26
|
+
expect(tested_player.health).to be == @initial_health + 15
|
27
|
+
end
|
28
|
+
|
29
|
+
it "decreases the health when rolling low number" do
|
30
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(2)
|
31
|
+
@game.play
|
32
|
+
tested_player = @game.get_player_by_name("moe")
|
33
|
+
expect(tested_player.health).to be == @initial_health - 10
|
34
|
+
end
|
35
|
+
it "keeps the health when rolling a mid number" do
|
36
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(4)
|
37
|
+
@game.play
|
38
|
+
tested_player = @game.get_player_by_name("moe")
|
39
|
+
expect(tested_player.health).to be == @initial_health
|
40
|
+
end
|
41
|
+
|
42
|
+
it "also introduces the changes properly in a multiround game" do
|
43
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(5)
|
44
|
+
@game.play 2
|
45
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(1)
|
46
|
+
@game.play 2
|
47
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(3)
|
48
|
+
@game.play 4
|
49
|
+
tested_player = @game.get_player_by_name("moe")
|
50
|
+
expect(tested_player.health).to be == @initial_health + 15*2 - 10*2
|
51
|
+
end
|
52
|
+
it "assigns a treasure for points during a player's turn" do
|
53
|
+
game = Game.new("Knuckleheads")
|
54
|
+
player = Player.new("moe")
|
55
|
+
|
56
|
+
game.add_player(player)
|
57
|
+
|
58
|
+
game.play(1)
|
59
|
+
|
60
|
+
expect(player.points).not_to be_zero
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
context "with an strong and wimpy player" do
|
65
|
+
before do
|
66
|
+
@game = Game.new("Tongo game")
|
67
|
+
@game.add_player(Player.new("Winner", 2000))
|
68
|
+
@game.add_player(Player.new("Loser", 1))
|
69
|
+
@game_output_file=File.join(File.dirname(__FILE__),"game_spec_save.out")
|
70
|
+
end
|
71
|
+
|
72
|
+
it "prints the winner properly" do
|
73
|
+
expect(@game.winner.name.downcase).to be == "winner"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "prints the status properly" do
|
77
|
+
expected_stats="Tongo game Statistics:\n\n1 strong players:\n\tWinner.............. 2000\n\n1 wimpy players:\n\tLoser............... 1\n"
|
78
|
+
expected_stats << "Tongo game High Scores:\n\tWinner.............. 2000\n\tLoser............... 1\n"
|
79
|
+
expected_stats << "Tongo game Total points:\n\tWinner's point totals:\n\t\t0 grand total points\n\tLoser's point totals:\n\t\t0 grand total points\n"
|
80
|
+
expect(@game.print_stats).to be == expected_stats
|
81
|
+
end
|
82
|
+
|
83
|
+
it "saves the high scores to a file" do
|
84
|
+
expected_stats = "Tongo game High Scores:\n\tWinner.............. 2000\n\tLoser............... 1\n"
|
85
|
+
@game.save_high_scores @game_output_file
|
86
|
+
expect(`cat #{@game_output_file}`).to be == expected_stats
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context "from an imported array of players" do
|
91
|
+
before do
|
92
|
+
@players_data=[["larry",60],["curly",120],["moe",100],["shemp",90],["dani"]]
|
93
|
+
players = Array.new
|
94
|
+
@players_data.each do |name,health|
|
95
|
+
player = Player.new(name,health)
|
96
|
+
players << player
|
97
|
+
end
|
98
|
+
@game = Game.new "test game"
|
99
|
+
@game.load_players(players)
|
100
|
+
end
|
101
|
+
it "should contain the expected number of players" do
|
102
|
+
expect(@game.players.size).to be == @players_data.size
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "from an imported csv of players" do
|
107
|
+
before do
|
108
|
+
@player_file=File.join(File.dirname(__FILE__),"game_spec_players.csv")
|
109
|
+
@game = Game.new("csv game")
|
110
|
+
@game.load_players(@player_file)
|
111
|
+
end
|
112
|
+
it "should contain the expected number of players" do
|
113
|
+
expect(@game.players.size).to be == `cat #{@player_file} | wc -l`.to_i
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'studio_game/player'
|
2
|
+
require 'studio_game/treasure_trove'
|
3
|
+
|
4
|
+
module StudioGame
|
5
|
+
describe Player do
|
6
|
+
context "with auto health" do
|
7
|
+
before do
|
8
|
+
@player = Player.new("dani")
|
9
|
+
@health = @player.health
|
10
|
+
end
|
11
|
+
|
12
|
+
it "has a capitalized name" do
|
13
|
+
expect(@player.name).to be == "Dani"
|
14
|
+
end
|
15
|
+
|
16
|
+
it "has an initial health" do
|
17
|
+
expect(@player.health).to be > 0
|
18
|
+
end
|
19
|
+
|
20
|
+
it "has a string representation" do
|
21
|
+
expect(@player.to_s).not_to be nil
|
22
|
+
end
|
23
|
+
it "has a proper string representation" do
|
24
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
25
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
26
|
+
expect(@player.to_s).to include "I'm Dani with health = #{@health}, points = 100, and score = #{@health+100}"
|
27
|
+
end
|
28
|
+
it "yields each found treasure and its total points" do
|
29
|
+
@player.found_treasure(Treasure.new(:skillet, 100))
|
30
|
+
@player.found_treasure(Treasure.new(:skillet, 100))
|
31
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
32
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
33
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
34
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
35
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
36
|
+
@player.found_treasure(Treasure.new(:bottle, 5))
|
37
|
+
|
38
|
+
yielded = []
|
39
|
+
@player.each_found_treasure do |treasure|
|
40
|
+
yielded << treasure
|
41
|
+
end
|
42
|
+
|
43
|
+
expect(yielded).to be == [
|
44
|
+
Treasure.new(:skillet, 200),
|
45
|
+
Treasure.new(:hammer, 50),
|
46
|
+
Treasure.new(:bottle, 25)
|
47
|
+
]
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
context "with a high static health" do
|
52
|
+
before do
|
53
|
+
@initial_health=150
|
54
|
+
@player = Player.new("dani",@initial_health)
|
55
|
+
end
|
56
|
+
it "computes a score as the sum of its health and points" do
|
57
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
58
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
59
|
+
expect(@player.score).to be == @initial_health + 100
|
60
|
+
end
|
61
|
+
|
62
|
+
it "increases health by 15 when w00ted" do
|
63
|
+
@player.w00t
|
64
|
+
expect(@player.health).to be == @initial_health+15
|
65
|
+
end
|
66
|
+
|
67
|
+
it "decreases health by 10 when blammed" do
|
68
|
+
@player.blam
|
69
|
+
expect(@player.health).to be == @initial_health-10
|
70
|
+
end
|
71
|
+
it "is strong" do
|
72
|
+
expect(@player).to be_strong
|
73
|
+
end
|
74
|
+
it "computes points as the sum of all treasure points" do
|
75
|
+
expect(@player.points).to be == 0
|
76
|
+
|
77
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
78
|
+
|
79
|
+
expect(@player.points).to be == 50
|
80
|
+
|
81
|
+
@player.found_treasure(Treasure.new(:crowbar, 400))
|
82
|
+
|
83
|
+
expect(@player.points).to be == 450
|
84
|
+
|
85
|
+
@player.found_treasure(Treasure.new(:hammer, 50))
|
86
|
+
|
87
|
+
expect(@player.points).to be == 500
|
88
|
+
end
|
89
|
+
end
|
90
|
+
context "with a low static health" do
|
91
|
+
before do
|
92
|
+
@initial_health=50
|
93
|
+
@player = Player.new("dani",@initial_health)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "is wimpy" do
|
97
|
+
expect(@player).not_to be_strong
|
98
|
+
end
|
99
|
+
end
|
100
|
+
context "created from a csv" do
|
101
|
+
before do
|
102
|
+
@player = Player.from_csv("dani,10")
|
103
|
+
end
|
104
|
+
|
105
|
+
it "has a capitalized name" do
|
106
|
+
expect(@player.name).to be == "Dani"
|
107
|
+
end
|
108
|
+
it "has an initial health" do
|
109
|
+
expect(@player.health).to be == 10
|
110
|
+
end
|
111
|
+
end
|
112
|
+
context "in a collection of players" do
|
113
|
+
before do
|
114
|
+
@player1 = Player.new("moe", 100)
|
115
|
+
@player2 = Player.new("larry", 200)
|
116
|
+
@player3 = Player.new("curly", 300)
|
117
|
+
|
118
|
+
@players = [@player1, @player2, @player3]
|
119
|
+
end
|
120
|
+
|
121
|
+
it "is sorted by decreasing score" do
|
122
|
+
expect(@players.sort).to be == [@player3, @player2, @player1]
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'studio_game/treasure_trove'
|
2
|
+
module StudioGame
|
3
|
+
describe Treasure do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@treasure = Treasure.new(:hammer, 50)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "has a name attribute" do
|
10
|
+
expect(@treasure.name).to be == :hammer
|
11
|
+
end
|
12
|
+
|
13
|
+
it "has a points attribute" do
|
14
|
+
expect(@treasure.points).to be == 50
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can be printed" do
|
18
|
+
expect(@treasure.to_s).to be == "treasure hammer worth 50 points"
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe TreasureTrove do
|
24
|
+
|
25
|
+
it "has six treasures" do
|
26
|
+
expect(TreasureTrove::TREASURES.size).to be == 6
|
27
|
+
end
|
28
|
+
|
29
|
+
it "has a pie worth 5 points" do
|
30
|
+
expect(TreasureTrove::TREASURES[0]).to be == Treasure.new(:pie, 5)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "has a bottle worth 25 points" do
|
34
|
+
expect(TreasureTrove::TREASURES[1]).to be == Treasure.new(:bottle, 25)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "has a hammer worth 50 points" do
|
38
|
+
expect(TreasureTrove::TREASURES[2]).to be == Treasure.new(:hammer, 50)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "has a skillet worth 100 points" do
|
42
|
+
expect(TreasureTrove::TREASURES[3]).to be == Treasure.new(:skillet, 100)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "has a broomstick worth 200 points" do
|
46
|
+
expect(TreasureTrove::TREASURES[4]).to be == Treasure.new(:broomstick, 200)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "has a crowbar worth 400 points" do
|
50
|
+
expect(TreasureTrove::TREASURES[5]).to be == Treasure.new(:crowbar, 400)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "returns a random treasure" do
|
54
|
+
treasure = TreasureTrove.random
|
55
|
+
expect(TreasureTrove::TREASURES).to include(treasure)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dcaba_studio_game
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Caballero
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-01-11 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: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description: "Code developed to follow Pragmatic Studio's Ruby training!! \n"
|
28
|
+
email: dcaba@github.com
|
29
|
+
executables:
|
30
|
+
- studio_game
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- LICENSE
|
35
|
+
- README
|
36
|
+
- bin/Game with tens of players.out
|
37
|
+
- bin/csv game!.out
|
38
|
+
- bin/dani_players.csv
|
39
|
+
- bin/myGame!.out
|
40
|
+
- bin/players.csv
|
41
|
+
- bin/studio_game
|
42
|
+
- lib/studio_game/auditable.rb
|
43
|
+
- lib/studio_game/berserk_player.rb
|
44
|
+
- lib/studio_game/clumsy_player.rb
|
45
|
+
- lib/studio_game/die.rb
|
46
|
+
- lib/studio_game/game.rb
|
47
|
+
- lib/studio_game/game_turn.rb
|
48
|
+
- lib/studio_game/loaded_die.rb
|
49
|
+
- lib/studio_game/playable.rb
|
50
|
+
- lib/studio_game/player.rb
|
51
|
+
- lib/studio_game/treasure_trove.rb
|
52
|
+
- spec/studio_game/berserk_player_spec.rb
|
53
|
+
- spec/studio_game/clumsy_player_spec.rb
|
54
|
+
- spec/studio_game/game_spec.rb
|
55
|
+
- spec/studio_game/game_spec_players.csv
|
56
|
+
- spec/studio_game/game_spec_save.out
|
57
|
+
- spec/studio_game/player_spec.rb
|
58
|
+
- spec/studio_game/treasure_trove_spec.rb
|
59
|
+
homepage: http://www.odenum.com
|
60
|
+
licenses:
|
61
|
+
- MIT
|
62
|
+
metadata: {}
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '1.9'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubyforge_project:
|
79
|
+
rubygems_version: 2.4.8
|
80
|
+
signing_key:
|
81
|
+
specification_version: 4
|
82
|
+
summary: Ruby trainig exercise for pragmatic studio
|
83
|
+
test_files:
|
84
|
+
- spec/studio_game/treasure_trove_spec.rb
|
85
|
+
- spec/studio_game/game_spec_save.out
|
86
|
+
- spec/studio_game/game_spec_players.csv
|
87
|
+
- spec/studio_game/game_spec.rb
|
88
|
+
- spec/studio_game/clumsy_player_spec.rb
|
89
|
+
- spec/studio_game/player_spec.rb
|
90
|
+
- spec/studio_game/berserk_player_spec.rb
|