oolivera-studio_game 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.
- checksums.yaml +7 -0
- data/README.md +7 -0
- data/bin/studio_game +33 -0
- data/doc/game/friends.csv +4 -0
- data/doc/game/game_players.csv +0 -0
- data/doc/game/game_results.csv +7 -0
- data/doc/game/players.csv +6 -0
- data/lib/studio_game/auditable.rb +5 -0
- data/lib/studio_game/berserk_player.rb +33 -0
- data/lib/studio_game/clumsy_player.rb +37 -0
- data/lib/studio_game/die.rb +16 -0
- data/lib/studio_game/game.rb +144 -0
- data/lib/studio_game/game_turn.rb +24 -0
- data/lib/studio_game/loaded_die.rb +11 -0
- data/lib/studio_game/namespace.rb +29 -0
- data/lib/studio_game/playable.rb +23 -0
- data/lib/studio_game/player.rb +57 -0
- data/lib/studio_game/treasure_trove.rb +18 -0
- data/specs/berserk_player_spec.rb +26 -0
- data/specs/clumsy_spec.rb +47 -0
- data/specs/game_spec.rb +50 -0
- data/specs/player_spec.rb +146 -0
- data/specs/treasure_trove_spec.rb +55 -0
- metadata +76 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 500cc124bdc1ab7e2112156fb120237f67b8c818cbfcf7477c525135a167e9ff
|
4
|
+
data.tar.gz: 3299133a7aff17db8fe8f40cc3a182da25661f3e1454e8d722ce898710d147f4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b5ca63499c8fcb3c0a1ddea129bf5e56ba8402298ddb7dd2f9063d4afca4fd725ad588e0c0014d066671e9f13d0acbfdc5836fd674088e9e3d195370c62d69d2
|
7
|
+
data.tar.gz: 5fee4bf54faa2d93f265af19c6bcc18163c734ee52b5c0addbdcea94486b630d5a2e057c1dbdceedb5f3a24dc2d5e6d4b18d56395608bf179bc8645267c301f0
|
data/README.md
ADDED
data/bin/studio_game
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative '../lib/studio_game/game'
|
3
|
+
require_relative '../lib/studio_game/die'
|
4
|
+
require_relative '../lib/studio_game/clumsy_player'
|
5
|
+
require_relative '../lib/studio_game/berserk_player'
|
6
|
+
require 'pry'
|
7
|
+
|
8
|
+
default_path = File.join( 'doc', 'game', 'players.csv')
|
9
|
+
knuckleheads = StudioGame::Game.new('Knuckleheads')
|
10
|
+
knuckleheads.load(ARGV.shift || default_path)
|
11
|
+
|
12
|
+
klutz = ClumsyPlayer.new('klutz', 105)
|
13
|
+
knuckleheads.add_player(klutz)
|
14
|
+
|
15
|
+
berserker = BerserkPlayer.new('berserker', 50)
|
16
|
+
knuckleheads.add_player(berserker)
|
17
|
+
|
18
|
+
loop do
|
19
|
+
puts "How many rounds? ('salir' para terminar)"
|
20
|
+
answer = gets.chomp.downcase
|
21
|
+
case answer
|
22
|
+
when /^\d+$/
|
23
|
+
puts "Enjoy your #{answer} games..."
|
24
|
+
knuckleheads.play(answer.to_i) { knuckleheads.total_points >= 200_000 }
|
25
|
+
when 'salir'
|
26
|
+
knuckleheads.print_stats
|
27
|
+
break
|
28
|
+
else
|
29
|
+
puts "'====> ... Por favor coloque un numero o escriba 'salir' para terminar. ... <==="
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
knuckleheads.save_high_scores
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Documentation
|
2
|
+
require 'pry'
|
3
|
+
require_relative 'player'
|
4
|
+
|
5
|
+
class BerserkPlayer < StudioGame::Player
|
6
|
+
def initialize(name, health)
|
7
|
+
super(name, health)
|
8
|
+
@w00ts = 0
|
9
|
+
end
|
10
|
+
|
11
|
+
def w00t
|
12
|
+
super
|
13
|
+
@w00ts += 1
|
14
|
+
puts "#{@name} is berserk!" if berserk?
|
15
|
+
end
|
16
|
+
|
17
|
+
def berserk?
|
18
|
+
@w00ts > 5
|
19
|
+
end
|
20
|
+
|
21
|
+
def blam
|
22
|
+
return super unless berserk?
|
23
|
+
|
24
|
+
w00t
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
if __FILE__ == $0
|
29
|
+
berserker = BerserkPlayer.new('berserker', 50)
|
30
|
+
6.times { berserker.w00t }
|
31
|
+
2.times { berserker.blam }
|
32
|
+
puts berserker.health
|
33
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Documentation
|
2
|
+
require 'pry'
|
3
|
+
require_relative 'player'
|
4
|
+
|
5
|
+
class ClumsyPlayer < StudioGame::Player
|
6
|
+
attr_reader :boost_factor
|
7
|
+
|
8
|
+
def initialize(name, health, boost_factor = 2)
|
9
|
+
super(name, health)
|
10
|
+
@boost_factor = boost_factor
|
11
|
+
end
|
12
|
+
|
13
|
+
def w00t
|
14
|
+
@boost_factor.times { super }
|
15
|
+
end
|
16
|
+
|
17
|
+
def found_treasure(treasure)
|
18
|
+
super Treasure.new(treasure.name, treasure.points / 2.0)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
if __FILE__ == $0
|
23
|
+
clumsy = ClumsyPlayer.new('klutz', 105, 3)
|
24
|
+
|
25
|
+
hammer = Treasure.new(:hammer, 50)
|
26
|
+
clumsy.found_treasure(hammer)
|
27
|
+
clumsy.found_treasure(hammer)
|
28
|
+
clumsy.found_treasure(hammer)
|
29
|
+
|
30
|
+
crowbar = Treasure.new(:crowbar, 400)
|
31
|
+
clumsy.found_treasure(crowbar)
|
32
|
+
|
33
|
+
clumsy.each_found_treasure do |treasure|
|
34
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
35
|
+
end
|
36
|
+
puts "#{clumsy.points} grand total points"
|
37
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
require_relative 'game_turn'
|
3
|
+
require_relative 'treasure_trove'
|
4
|
+
require 'pry'
|
5
|
+
|
6
|
+
# Documentation
|
7
|
+
module StudioGame
|
8
|
+
class Game
|
9
|
+
attr_reader :title
|
10
|
+
|
11
|
+
# Class constructor.
|
12
|
+
#
|
13
|
+
# @params 'title' [String] a name for the game.
|
14
|
+
# @return Game [Object] New instance of game.
|
15
|
+
# @example
|
16
|
+
# [
|
17
|
+
# #<Game:0x0000462ed36a1e0
|
18
|
+
# @title="Knuckeheads",
|
19
|
+
# @players=[]"
|
20
|
+
# >
|
21
|
+
# ]
|
22
|
+
#
|
23
|
+
def initialize(title)
|
24
|
+
@title = title
|
25
|
+
@players = []
|
26
|
+
end
|
27
|
+
|
28
|
+
# To read from a csv file to add players for a game,
|
29
|
+
# in order for that player(s) to play a game.
|
30
|
+
#
|
31
|
+
# @params 'from_file' [String] a directory path to access csv file.
|
32
|
+
# @return [void]
|
33
|
+
# @example
|
34
|
+
# csv:
|
35
|
+
# 1 moe,100
|
36
|
+
# 2 larry,
|
37
|
+
# 3 curly,65
|
38
|
+
#
|
39
|
+
def load(from_file)
|
40
|
+
File.readlines(from_file).each do |line|
|
41
|
+
add_player(Player.from_csv(line))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# To create a csv file with player(s) names and final game score,
|
46
|
+
# as the return of a game played.
|
47
|
+
#
|
48
|
+
# @params 'to_file' [String] a directory path to save the csv file created.
|
49
|
+
# @return [void]
|
50
|
+
# @example
|
51
|
+
# csv:
|
52
|
+
# 1 moe,850
|
53
|
+
# 2 larry,680,
|
54
|
+
# 3 curly,250
|
55
|
+
# @note Default path/file name: docs/game_results.csv
|
56
|
+
#
|
57
|
+
def save_high_scores(to_file = 'doc/game/game_results.csv')
|
58
|
+
File.open(to_file, 'w') do |file|
|
59
|
+
file.puts "#{@title} High Scores:"
|
60
|
+
@players.sort_by(&:points).reverse.each do |player|
|
61
|
+
file.puts high_score_entry(player)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# To include a player object into an instance array.
|
67
|
+
#
|
68
|
+
# @params 'player' [Object]
|
69
|
+
# @return [Array] a group of players objects inside an array.
|
70
|
+
# @example
|
71
|
+
# [
|
72
|
+
# #<Player:0x00005628d364f4e0
|
73
|
+
# @found_treasures={},
|
74
|
+
# @health=100,
|
75
|
+
# @name="Moe"
|
76
|
+
# >,
|
77
|
+
# #<Player:0x00005628d3335340
|
78
|
+
# @found_treasures={},
|
79
|
+
# @health=60,
|
80
|
+
# @name="Larry"
|
81
|
+
# >
|
82
|
+
# ]
|
83
|
+
#
|
84
|
+
def add_player(player)
|
85
|
+
@players << player
|
86
|
+
end
|
87
|
+
|
88
|
+
# To iterate each player in n-times to play a game.
|
89
|
+
#
|
90
|
+
# @params 'round' [Integer]
|
91
|
+
# @return [void]
|
92
|
+
# @note It prints the total point when finished
|
93
|
+
#
|
94
|
+
def play(rounds)
|
95
|
+
print_treasures
|
96
|
+
puts "This Game is up to #{rounds} round(s)"
|
97
|
+
1.upto(rounds).each do |round|
|
98
|
+
break if block_given? && yield
|
99
|
+
|
100
|
+
players_round(round)
|
101
|
+
end
|
102
|
+
puts "TOTAL Points #{total_points}"
|
103
|
+
end
|
104
|
+
|
105
|
+
# To iterate each over TreasureTrove::TREASURES to print its name and points.
|
106
|
+
#
|
107
|
+
# @return [void]
|
108
|
+
# @note It prints the total point when finished
|
109
|
+
#
|
110
|
+
def print_treasures
|
111
|
+
puts "There are #{TreasureTrove::TREASURES.size} treasures to be found:"
|
112
|
+
TreasureTrove::TREASURES.each do |treasure|
|
113
|
+
puts "A #{treasure.name} is worth #{treasure.points} points"
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def players_round(round)
|
118
|
+
puts ". . . . . . . . . . . . . . . . . --- *> Round# #{round} <* --- . . . . . . . . . . . . . . . . ."
|
119
|
+
@players.each do |player|
|
120
|
+
GameTurn.take_turn(player)
|
121
|
+
puts player
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def print_stats
|
126
|
+
@players.sort_by(&:points).reverse.each do |player|
|
127
|
+
puts player
|
128
|
+
player.each_found_treasure do |treasure|
|
129
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
130
|
+
end
|
131
|
+
puts high_score_entry(player)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def total_points
|
136
|
+
@players.reduce(0) { |sum, player| sum + player.points }
|
137
|
+
end
|
138
|
+
|
139
|
+
def high_score_entry(player)
|
140
|
+
formatted_name = player.name.ljust(20, '.')
|
141
|
+
"#{formatted_name} #{player.score}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative 'die'
|
2
|
+
require_relative 'loaded_die'
|
3
|
+
|
4
|
+
# Domumentation
|
5
|
+
module GameTurn
|
6
|
+
def self.take_turn(player)
|
7
|
+
die = Die.new
|
8
|
+
players_fate(player, die)
|
9
|
+
treasure = TreasureTrove.random
|
10
|
+
player.found_treasure(treasure)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.players_fate(player, die)
|
14
|
+
number_rolled = die.roll
|
15
|
+
case number_rolled
|
16
|
+
when (1..2)
|
17
|
+
player.blam
|
18
|
+
when (3..4)
|
19
|
+
puts "#{player.name} was skipped."
|
20
|
+
else
|
21
|
+
player.w00t
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module MovieSystem
|
2
|
+
VERSION = 1.0
|
3
|
+
|
4
|
+
def self.info
|
5
|
+
puts "Movie system version #{VERSION}"
|
6
|
+
end
|
7
|
+
|
8
|
+
class Player
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module GameSystem
|
13
|
+
VERSION = 2.0
|
14
|
+
|
15
|
+
def self.info
|
16
|
+
puts "Game system version #{VERSION}"
|
17
|
+
end
|
18
|
+
|
19
|
+
class Player
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
puts MovieSystem::VERSION
|
24
|
+
puts MovieSystem.info
|
25
|
+
puts MovieSystem::Player.new
|
26
|
+
|
27
|
+
puts GameSystem::VERSION
|
28
|
+
puts GameSystem.info
|
29
|
+
puts GameSystem::Player.new
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Playable
|
2
|
+
def w00t
|
3
|
+
puts "#{name} was w00ted, Yeah!!!"
|
4
|
+
self.health += 15
|
5
|
+
end
|
6
|
+
|
7
|
+
def blam
|
8
|
+
puts "Oh! #{name} was blamed :("
|
9
|
+
self.health -= 10
|
10
|
+
end
|
11
|
+
|
12
|
+
def score
|
13
|
+
self.health + points
|
14
|
+
end
|
15
|
+
|
16
|
+
def status
|
17
|
+
strong? ? "#{name} is still standing." : "#{name} is out blammed."
|
18
|
+
end
|
19
|
+
|
20
|
+
def strong?
|
21
|
+
health > 150
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Documentation
|
2
|
+
require 'pry'
|
3
|
+
require_relative 'playable'
|
4
|
+
require_relative 'treasure_trove'
|
5
|
+
module StudioGame
|
6
|
+
class Player
|
7
|
+
include Playable
|
8
|
+
attr_accessor :name, :health
|
9
|
+
|
10
|
+
def initialize(name, health = 100)
|
11
|
+
@name = name.capitalize
|
12
|
+
@health = health
|
13
|
+
@found_treasures = Hash.new(0)
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_csv
|
17
|
+
"#{name},#{points}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.from_csv(line)
|
21
|
+
name, health = line.split(',')
|
22
|
+
health = health.nil? ? 100 : health
|
23
|
+
Player.new(name, Integer(health))
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"I'm #{@name} with health = #{@health}, points = #{points}, and score = #{score}."
|
28
|
+
end
|
29
|
+
|
30
|
+
def found_treasure(tresure)
|
31
|
+
puts "#{@name} found a #{tresure.name} worth #{tresure.points} points."
|
32
|
+
@found_treasures[tresure.name] += tresure.points
|
33
|
+
puts "#{@name}'s treasures: #{@found_treasures}."
|
34
|
+
tresure
|
35
|
+
end
|
36
|
+
|
37
|
+
def each_found_treasure
|
38
|
+
@found_treasures.each do |name, worth|
|
39
|
+
yield Treasure.new(name, worth)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def points
|
44
|
+
@found_treasures.values.reduce(0, :+)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
if __FILE__ == $PROGRAM_NAME
|
50
|
+
player = Player.new('moe')
|
51
|
+
puts player.name
|
52
|
+
puts player.health
|
53
|
+
player.w00t
|
54
|
+
puts player.health
|
55
|
+
player.blam
|
56
|
+
puts player.health
|
57
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Documentation
|
2
|
+
Treasure = Struct.new(:name, :points)
|
3
|
+
|
4
|
+
# Documentation
|
5
|
+
module TreasureTrove
|
6
|
+
TREASURES = [
|
7
|
+
Treasure.new(:pie, 5),
|
8
|
+
Treasure.new(:bottle, 25),
|
9
|
+
Treasure.new(:hammer, 50),
|
10
|
+
Treasure.new(:skillet, 100),
|
11
|
+
Treasure.new(:broomstick, 200),
|
12
|
+
Treasure.new(:crowbar, 400)
|
13
|
+
].freeze
|
14
|
+
|
15
|
+
def self.random
|
16
|
+
TREASURES[rand(0..5)]
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'studio_game/berserk_player'
|
2
|
+
|
3
|
+
describe BerserkPlayer do
|
4
|
+
let(:initial_health) { 50 }
|
5
|
+
let(:player) { BerserkPlayer.new('berserker', initial_health) }
|
6
|
+
before do
|
7
|
+
$stdout = StringIO.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'does not go berserk when w00ted up to 5 times' do
|
11
|
+
1.upto(5) { player.w00t }
|
12
|
+
expect(player.berserk?).to be_falsey
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'goes berserk when w00ted more than 5 times' do
|
16
|
+
1.upto(6) { player.w00t }
|
17
|
+
expect(player.berserk?).to be_truthy
|
18
|
+
end
|
19
|
+
|
20
|
+
it "gets w00ted instead of blammed when it's gone berserk" do
|
21
|
+
1.upto(6) { player.w00t }
|
22
|
+
1.upto(2) { player.blam }
|
23
|
+
|
24
|
+
expect(player.health).to eq(initial_health + (8 * 15))
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'studio_game/clumsy_player'
|
2
|
+
|
3
|
+
describe ClumsyPlayer do
|
4
|
+
let(:initial_health) { 100 }
|
5
|
+
let(:player) { ClumsyPlayer.new('klutz', initial_health) }
|
6
|
+
let(:hammer) { Treasure.new(:hammer, 50) }
|
7
|
+
let(:crowbar) { Treasure.new(:crowbar, 400) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
$stdout = StringIO.new
|
11
|
+
end
|
12
|
+
it 'only gets half the point value for each treasure' do
|
13
|
+
expect(player.points).to eq(0)
|
14
|
+
|
15
|
+
player.found_treasure(hammer)
|
16
|
+
player.found_treasure(hammer)
|
17
|
+
player.found_treasure(hammer)
|
18
|
+
|
19
|
+
expect(player.points).to eq(75)
|
20
|
+
|
21
|
+
player.found_treasure(crowbar)
|
22
|
+
|
23
|
+
expect(player.points).to eq(275)
|
24
|
+
|
25
|
+
yielded = []
|
26
|
+
player.each_found_treasure do |treasure|
|
27
|
+
yielded << treasure
|
28
|
+
end
|
29
|
+
|
30
|
+
expect(yielded).to eq([Treasure.new(:hammer, 75), Treasure.new(:crowbar, 200)])
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with a boost factor' do
|
34
|
+
let(:boost_factor) { 5 }
|
35
|
+
let(:player_boosted) { ClumsyPlayer.new('klutz', initial_health, boost_factor) }
|
36
|
+
|
37
|
+
it 'has a boost factor' do
|
38
|
+
expect(player_boosted.boost_factor).to eq(5)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'gets boost factor number of w00ts when w00ted' do
|
42
|
+
player_boosted.w00t
|
43
|
+
|
44
|
+
expect(player_boosted.health).to eq(initial_health + (15 * boost_factor))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/specs/game_spec.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'studio_game/game'
|
2
|
+
require 'studio_game/player'
|
3
|
+
module StudioGame
|
4
|
+
describe Game do
|
5
|
+
let(:game) { Game.new('Knuckeheads') }
|
6
|
+
let(:initial_health) { 100 }
|
7
|
+
let(:player_a) { Player.new('Ramón', initial_health) }
|
8
|
+
let(:player_b) { Player.new('Jose', initial_health) }
|
9
|
+
let(:rounds) { 2 }
|
10
|
+
|
11
|
+
before do
|
12
|
+
$stdout = StringIO.new
|
13
|
+
game.add_player(player_a)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'w00ts the player if a high number is rolled' do
|
17
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(5)
|
18
|
+
game.play(rounds)
|
19
|
+
expect(player_a.health).to be(initial_health + 15 * rounds)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'does nothing to players health with medium number' do
|
23
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(3)
|
24
|
+
game.play(rounds)
|
25
|
+
expect(player_a.health).to eq(initial_health)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'blams the player if a low number is rolled' do
|
29
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(1)
|
30
|
+
game.play(rounds)
|
31
|
+
expect(player_a.health).to eq(initial_health - 10 * rounds)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'prints players stats' do
|
35
|
+
allow_any_instance_of(Die).to receive(:roll).and_return(1)
|
36
|
+
player_a.found_treasure(Treasure.new(:crowbar, 400))
|
37
|
+
expect(game.print_stats[0].class).to eq(player_a.class)
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'computes total points as the sum of all player points' do
|
41
|
+
game.add_player(player_b)
|
42
|
+
|
43
|
+
player_a.found_treasure(Treasure.new(:hammer, 50))
|
44
|
+
player_a.found_treasure(Treasure.new(:hammer, 50))
|
45
|
+
player_b.found_treasure(Treasure.new(:crowbar, 400))
|
46
|
+
|
47
|
+
expect(game.total_points).to eq(500)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'studio_game/player'
|
2
|
+
require 'studio_game/treasure_trove'
|
3
|
+
require 'pry'
|
4
|
+
module StudioGame
|
5
|
+
describe Player do # rubocop:disable Metrics/BlockLength
|
6
|
+
let(:player) { Player.new('jose', 150) }
|
7
|
+
let(:hammer) { Treasure.new(:hammer, 50) }
|
8
|
+
let(:crowbar) { Treasure.new(:crowbar, 400) }
|
9
|
+
before do
|
10
|
+
$stdout = StringIO.new
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'validations' do # rubocop:disable Metrics/BlockLength
|
14
|
+
before do
|
15
|
+
@initial_health = player.health
|
16
|
+
end
|
17
|
+
it 'has a capitalize name' do
|
18
|
+
expect(player.name).to eq('Jose')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'has a initial health' do
|
22
|
+
expect(player.health).to eq(150)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'has a initial score' do
|
26
|
+
expect(player.score).to eq(@initial_health + player.points)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has a string representation' do
|
30
|
+
player.found_treasure(Treasure.new(:hammer, 50))
|
31
|
+
player.found_treasure(Treasure.new(:hammer, 50))
|
32
|
+
expect(player.to_s).to eq(
|
33
|
+
"I'm Jose with health = 150, points = 100, and score = 250."
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'increases health by 15 when w00ted' do
|
38
|
+
player.w00t
|
39
|
+
expect(player.health).to be(@initial_health + 15)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'decreases health by 10 when blammed' do
|
43
|
+
player.blam
|
44
|
+
expect(player.health).to be(@initial_health - 10)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'computes a score as the sum of its health and points' do
|
48
|
+
player.found_treasure(Treasure.new(:hammer, 50))
|
49
|
+
player.found_treasure(Treasure.new(:hammer, 50))
|
50
|
+
|
51
|
+
expect(player.score).to eq(250)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'computes points as the sum of all treasure points' do
|
55
|
+
expect(player.points).to eq(0)
|
56
|
+
|
57
|
+
expect(player.found_treasure(hammer)).to eq(Treasure.new(:hammer, 50))
|
58
|
+
|
59
|
+
expect(player.points).to eq(50)
|
60
|
+
|
61
|
+
expect(player.found_treasure(crowbar)).to eq(Treasure.new(:crowbar, 400))
|
62
|
+
|
63
|
+
expect(player.points).to eq(450)
|
64
|
+
|
65
|
+
expect(player.found_treasure(hammer)).to eq(Treasure.new(:hammer, 50))
|
66
|
+
|
67
|
+
expect(player.points).to eq(500)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "assigns a treasure for points during a player's turn" do
|
71
|
+
game = Game.new('Knuckleheads')
|
72
|
+
player = Player.new('moe')
|
73
|
+
|
74
|
+
game.add_player(player)
|
75
|
+
|
76
|
+
game.play(1)
|
77
|
+
|
78
|
+
expect(player.points).not_to be_zero
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when is created witout initial health' do
|
83
|
+
let(:player) { Player.new('jose') }
|
84
|
+
|
85
|
+
it 'has a initial health of 100' do
|
86
|
+
expect(player.health).to eq(100)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'when is strong' do
|
91
|
+
let(:player) { Player.new('jose', 167) }
|
92
|
+
|
93
|
+
it 'has a health above 150' do
|
94
|
+
expect(player.strong?).to eq(true)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'has a response for continuing playing' do
|
98
|
+
expect(player.status).to eq("#{player.name} is still standing.")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when is weak' do
|
103
|
+
let(:player) { Player.new('jose', 49) }
|
104
|
+
|
105
|
+
it 'has a health under 150' do
|
106
|
+
expect(player.strong?).to eq(false)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'has a response for player is out' do
|
110
|
+
expect(player.status).to eq("#{player.name} is out blammed.")
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when has various treasure' do
|
115
|
+
it 'yields each found treasure and its total points' do
|
116
|
+
player.found_treasure(Treasure.new(:skillet, 100))
|
117
|
+
player.found_treasure(Treasure.new(:skillet, 100))
|
118
|
+
player.found_treasure(Treasure.new(:hammer, 50))
|
119
|
+
player.found_treasure(Treasure.new(:bottle, 5))
|
120
|
+
player.found_treasure(Treasure.new(:bottle, 5))
|
121
|
+
player.found_treasure(Treasure.new(:bottle, 5))
|
122
|
+
player.found_treasure(Treasure.new(:bottle, 5))
|
123
|
+
player.found_treasure(Treasure.new(:bottle, 5))
|
124
|
+
|
125
|
+
yielded = []
|
126
|
+
player.each_found_treasure do |treasure|
|
127
|
+
yielded << treasure
|
128
|
+
end
|
129
|
+
|
130
|
+
expect(yielded).to eq([
|
131
|
+
Treasure.new(:skillet, 200),
|
132
|
+
Treasure.new(:hammer, 50),
|
133
|
+
Treasure.new(:bottle, 25)
|
134
|
+
])
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when is loaded by a csv file' do
|
139
|
+
let(:player) { Player.from_csv('larry,150') }
|
140
|
+
it 'can be created ' do
|
141
|
+
expect(player.name).to eq('Larry')
|
142
|
+
expect(player.health).to eq(150)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Documentation
|
2
|
+
require 'studio_game/treasure_trove'
|
3
|
+
|
4
|
+
describe Treasure do
|
5
|
+
before do
|
6
|
+
$stdout = StringIO.new
|
7
|
+
end
|
8
|
+
let(:treasure) { Treasure.new(:hammer, 50) }
|
9
|
+
|
10
|
+
it 'has a name attribute' do
|
11
|
+
expect(treasure.name).to eq(:hammer)
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'has a points attribute' do
|
15
|
+
expect(treasure.points).to eq(50)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe TreasureTrove do # rubocop:disable Metrics/BlockLength
|
20
|
+
describe 'Validations' do
|
21
|
+
it 'has six treasures' do
|
22
|
+
expect(TreasureTrove::TREASURES.size).to eq(6)
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'has a pie worth 5 points' do
|
26
|
+
expect(TreasureTrove::TREASURES[0]).to eq(Treasure.new(:pie, 5))
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has a bottle worth 25 points' do
|
30
|
+
expect(TreasureTrove::TREASURES[1]).to eq(Treasure.new(:bottle, 25))
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'has a hammer worth 50 points' do
|
34
|
+
expect(TreasureTrove::TREASURES[2]).to eq(Treasure.new(:hammer, 50))
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'has a skillet worth 100 points' do
|
38
|
+
expect(TreasureTrove::TREASURES[3]).to eq(Treasure.new(:skillet, 100))
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'has a broomstick worth 200 points' do
|
42
|
+
expect(TreasureTrove::TREASURES[4]).to eq(Treasure.new(:broomstick, 200))
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'has a crowbar worth 400 points' do
|
46
|
+
expect(TreasureTrove::TREASURES[5]).to eq(Treasure.new(:crowbar, 400))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe '#random' do
|
51
|
+
it 'sholud return a object treasure from TREASURES' do
|
52
|
+
expect(TreasureTrove.random.class).to eq(Treasure)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oolivera-studio_game
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Oscar M. Olivera
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-01-20 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: |
|
14
|
+
# The Pragmatic Studio
|
15
|
+
|
16
|
+
## Ruby Programming Course
|
17
|
+
|
18
|
+
### Studio Game
|
19
|
+
|
20
|
+
A game oriented practice to showcase all the sections of the ruby course.
|
21
|
+
email: oscarmolivera@gmail.com
|
22
|
+
executables:
|
23
|
+
- studio_game
|
24
|
+
extensions: []
|
25
|
+
extra_rdoc_files: []
|
26
|
+
files:
|
27
|
+
- README.md
|
28
|
+
- bin/studio_game
|
29
|
+
- doc/game/friends.csv
|
30
|
+
- doc/game/game_players.csv
|
31
|
+
- doc/game/game_results.csv
|
32
|
+
- doc/game/players.csv
|
33
|
+
- lib/studio_game/auditable.rb
|
34
|
+
- lib/studio_game/berserk_player.rb
|
35
|
+
- lib/studio_game/clumsy_player.rb
|
36
|
+
- lib/studio_game/die.rb
|
37
|
+
- lib/studio_game/game.rb
|
38
|
+
- lib/studio_game/game_turn.rb
|
39
|
+
- lib/studio_game/loaded_die.rb
|
40
|
+
- lib/studio_game/namespace.rb
|
41
|
+
- lib/studio_game/playable.rb
|
42
|
+
- lib/studio_game/player.rb
|
43
|
+
- lib/studio_game/treasure_trove.rb
|
44
|
+
- specs/berserk_player_spec.rb
|
45
|
+
- specs/clumsy_spec.rb
|
46
|
+
- specs/game_spec.rb
|
47
|
+
- specs/player_spec.rb
|
48
|
+
- specs/treasure_trove_spec.rb
|
49
|
+
homepage: https://facebook.com
|
50
|
+
licenses: []
|
51
|
+
metadata: {}
|
52
|
+
post_install_message:
|
53
|
+
rdoc_options: []
|
54
|
+
require_paths:
|
55
|
+
- lib
|
56
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '3.0'
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
requirements: []
|
67
|
+
rubygems_version: 3.2.3
|
68
|
+
signing_key:
|
69
|
+
specification_version: 4
|
70
|
+
summary: Simple game to learn ruby coding
|
71
|
+
test_files:
|
72
|
+
- specs/berserk_player_spec.rb
|
73
|
+
- specs/clumsy_spec.rb
|
74
|
+
- specs/game_spec.rb
|
75
|
+
- specs/player_spec.rb
|
76
|
+
- specs/treasure_trove_spec.rb
|