studio-game-soobrakay 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/LICENSE +21 -0
- data/README.md +8 -0
- data/bin/players.csv +3 -0
- data/bin/studio-game +31 -0
- data/lib/studio_game/auditable.rb +5 -0
- data/lib/studio_game/berserk_player.rb +23 -0
- data/lib/studio_game/clumsy_player.rb +9 -0
- data/lib/studio_game/die.rb +16 -0
- data/lib/studio_game/game.rb +99 -0
- data/lib/studio_game/game_turn.rb +21 -0
- data/lib/studio_game/loaded_die.rb +14 -0
- data/lib/studio_game/playable.rb +21 -0
- data/lib/studio_game/player.rb +65 -0
- data/lib/studio_game/treasure_trove.rb +22 -0
- data/spec/studio_game/berserk_player_spec.rb +28 -0
- data/spec/studio_game/clumsy_player_spec.rb +35 -0
- data/spec/studio_game/game_spec.rb +49 -0
- data/spec/studio_game/player_spec.rb +98 -0
- data/spec/studio_game/treasure_trove_spec.rb +60 -0
- metadata +90 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: f59d59a83e659421c1e36e53266401e3f5c1840f
|
|
4
|
+
data.tar.gz: 13659759cccf09215f05875a208b7419c98e2d52
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a3822ab32d134babd8ff1614dc9d1a985ad1cd86e47beb68283505920b0d0c94f33ef800f95d7d3d6c6698adc2613ca3705cd732ad63e896ace75836804cca4c
|
|
7
|
+
data.tar.gz: 1384619338db6a2ad1d6d3773f2cd40b1f3e168c46e204e65fb1986190492cf354a64497a3c1a14ba6997643bb4e28d3d5aa03c9a2e11f65754a197d972b1341
|
data/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017 Soobrakay
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
data/bin/players.csv
ADDED
data/bin/studio-game
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#! /usr/bin/env ruby
|
|
2
|
+
require_relative '../lib/studio_game/game'
|
|
3
|
+
require_relative '../lib/studio_game/berserk_player'
|
|
4
|
+
require_relative '../lib/studio_game/clumsy_player'
|
|
5
|
+
|
|
6
|
+
game = Game.new
|
|
7
|
+
|
|
8
|
+
default_player_file = File.join(File.dirname(__FILE__), 'players.csv')
|
|
9
|
+
|
|
10
|
+
game.load_players(ARGV.shift || default_player_file)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
game.add_player BerserkPlayer.new 'berserky', 100
|
|
14
|
+
game.add_player ClumsyPlayer.new 'clumsy', 100
|
|
15
|
+
|
|
16
|
+
loop do
|
|
17
|
+
puts 'How many game rounds? ("quit" to exit)'
|
|
18
|
+
answer = gets.chomp.downcase
|
|
19
|
+
case answer
|
|
20
|
+
when /^\d+$/
|
|
21
|
+
game.play answer.to_i
|
|
22
|
+
when 'quit', 'exit', 'q', 'x'
|
|
23
|
+
game.print_stats
|
|
24
|
+
break
|
|
25
|
+
else
|
|
26
|
+
puts 'Please enter a number or "quit".'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
game.print_stats
|
|
31
|
+
game.save_high_scores
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_relative 'player'
|
|
2
|
+
|
|
3
|
+
# Berserk players ignore blams after getting w00ted several times
|
|
4
|
+
class BerserkPlayer < Player
|
|
5
|
+
def initialize(name, health = 100)
|
|
6
|
+
super
|
|
7
|
+
@w00t_count = 0
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def berserk?
|
|
11
|
+
@w00t_count > 5
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def w00t
|
|
15
|
+
super
|
|
16
|
+
@w00t_count += 1
|
|
17
|
+
puts "#{@name} is berserk!" if berserk?
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def blam
|
|
21
|
+
berserk? ? w00t : super
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Contains the `Die` class for generating d6 rolls.
|
|
2
|
+
|
|
3
|
+
# `Die` provides `roll` method to generate d6 roll. Also provides `number`
|
|
4
|
+
# accessor to get the last rolled number.
|
|
5
|
+
require_relative 'auditable'
|
|
6
|
+
|
|
7
|
+
class Die
|
|
8
|
+
include Auditable
|
|
9
|
+
attr_reader :number
|
|
10
|
+
|
|
11
|
+
def roll
|
|
12
|
+
@number = rand 1..6
|
|
13
|
+
audit
|
|
14
|
+
@number
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'csv'
|
|
2
|
+
|
|
3
|
+
require_relative 'game_turn'
|
|
4
|
+
require_relative 'player'
|
|
5
|
+
require_relative 'treasure_trove'
|
|
6
|
+
|
|
7
|
+
# Games have a title, add players to the game, and play rounds of the game
|
|
8
|
+
class Game
|
|
9
|
+
attr_reader :title
|
|
10
|
+
|
|
11
|
+
def initialize(title = 'default')
|
|
12
|
+
@title = title
|
|
13
|
+
@players = []
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Adds a player to the game
|
|
17
|
+
#
|
|
18
|
+
# @param player [Player] player to add to the game
|
|
19
|
+
def add_player(player)
|
|
20
|
+
@players.push player
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Plays the game
|
|
24
|
+
#
|
|
25
|
+
# @param rounds [Integer] number of turns each player gets
|
|
26
|
+
def play(rounds = 1)
|
|
27
|
+
puts "There are #{@players.length} players in #{title}:"
|
|
28
|
+
print_treasures
|
|
29
|
+
1.upto rounds do |round|
|
|
30
|
+
play_round round
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Prints all the available treasures and their points
|
|
35
|
+
def print_treasures
|
|
36
|
+
treasures = TreasureTrove::TREASURES
|
|
37
|
+
puts "There are #{treasures.length} treasures to be found:"
|
|
38
|
+
treasures.each do |treasure|
|
|
39
|
+
puts "A #{treasure.name} is worth #{treasure.points} points"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Plays a single round of the game for all players
|
|
44
|
+
def play_round(round)
|
|
45
|
+
puts "\nRound #{round}"
|
|
46
|
+
@players.each do |player|
|
|
47
|
+
GameTurn.take_turn player
|
|
48
|
+
puts player
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# :reek:TooManyStatements
|
|
53
|
+
def print_stats
|
|
54
|
+
strong, wimpy = @players.partition(&:strong?)
|
|
55
|
+
puts "\n#{title} Statistics:"
|
|
56
|
+
print_players strong
|
|
57
|
+
print_players wimpy, 'wimpy'
|
|
58
|
+
print_points
|
|
59
|
+
print_high_scores
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def print_players(players, label = 'strong')
|
|
63
|
+
puts "#{players.length} #{label} players:"
|
|
64
|
+
players.each { |player| puts "#{player.name} (#{player.health})" }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def print_points
|
|
68
|
+
@players.sort.each do |player|
|
|
69
|
+
puts "\n#{player.name}'s point totals:"
|
|
70
|
+
print_player_treasures player
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def print_player_treasures(player)
|
|
75
|
+
player.each_found_treasure do |treasure|
|
|
76
|
+
puts "#{treasure.points} total #{treasure.name} points"
|
|
77
|
+
end
|
|
78
|
+
puts "#{player.points} grand total points"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def load_players(player_file)
|
|
82
|
+
CSV.read(player_file).each do |player, health|
|
|
83
|
+
add_player Player.new player, health.to_i
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def print_high_scores(out = $stdout)
|
|
88
|
+
out.puts "\n#{title} High Scores:"
|
|
89
|
+
@players.sort.each do |player|
|
|
90
|
+
out.puts "#{player.name.ljust 60, '.'} #{player.score}"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def save_high_scores(to_file = 'high_scores.txt')
|
|
95
|
+
File.open(to_file, 'w') do |file|
|
|
96
|
+
print_high_scores file
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require_relative 'die'
|
|
2
|
+
require_relative 'treasure_trove'
|
|
3
|
+
|
|
4
|
+
# GameTurn provides a `take_turn` method take takes a `Player` parameter
|
|
5
|
+
#
|
|
6
|
+
# @param player [Player] the player taking the turn
|
|
7
|
+
module GameTurn
|
|
8
|
+
def self.take_turn(player)
|
|
9
|
+
case Die.new.roll
|
|
10
|
+
when 1..2
|
|
11
|
+
player.blam
|
|
12
|
+
when 3..4
|
|
13
|
+
puts "#{player.name} was skipped."
|
|
14
|
+
else
|
|
15
|
+
player.w00t
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
treasure = TreasureTrove.random
|
|
19
|
+
player.found_treasure treasure
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module Playable
|
|
2
|
+
# blam reduces a player's health and prints a message
|
|
3
|
+
# @return [Integer] current health
|
|
4
|
+
def blam
|
|
5
|
+
puts "#{self.name} got blammed!"
|
|
6
|
+
self.health -= 10
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# w00t raises a player's health and prints a message
|
|
10
|
+
# @return [Integer] current health
|
|
11
|
+
def w00t
|
|
12
|
+
puts "#{self.name} got w00ted!"
|
|
13
|
+
self.health += 15
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# strong? returns true if a player's health is above 100
|
|
17
|
+
# @return [Boolean] true if strong, false otherwise
|
|
18
|
+
def strong?
|
|
19
|
+
self.health > 100
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require_relative 'playable'
|
|
2
|
+
|
|
3
|
+
# Players of the game have a name and health.
|
|
4
|
+
class Player
|
|
5
|
+
include Playable
|
|
6
|
+
attr_accessor :health
|
|
7
|
+
attr_accessor :name
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Create a Player
|
|
11
|
+
#
|
|
12
|
+
# @param name [String] name of the player
|
|
13
|
+
# @param health [Integer] starting health for the player
|
|
14
|
+
def initialize(name, health = 100)
|
|
15
|
+
@name = name.capitalize
|
|
16
|
+
@health = health
|
|
17
|
+
@found_treasures = Hash.new(0)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Override to_s to print a message of player name and health
|
|
22
|
+
def to_s
|
|
23
|
+
"I'm #{name} with health = #{health}, points = #{points}, "\
|
|
24
|
+
"and score = #{score}."
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Player's have a score based on health
|
|
29
|
+
#
|
|
30
|
+
# @return [Integer] player's current score
|
|
31
|
+
def score
|
|
32
|
+
@health + points
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Override sort operator to sort by score descending
|
|
38
|
+
def <=>(other)
|
|
39
|
+
other.score <=> score
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
# Adds a treasure to the found treasures
|
|
44
|
+
#
|
|
45
|
+
# @param treasure [TreasureTrove::Treasure] treasure to add
|
|
46
|
+
def found_treasure(treasure)
|
|
47
|
+
treasure_name = treasure.name
|
|
48
|
+
treasure_points = treasure.points
|
|
49
|
+
|
|
50
|
+
@found_treasures[treasure_name] += treasure_points
|
|
51
|
+
|
|
52
|
+
puts "#{@name} found a #{treasure_name} worth #{treasure_points} points."
|
|
53
|
+
puts "#{@name}'s treasures: #{@found_treasures}"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def points
|
|
57
|
+
@found_treasures.values.reduce(0, :+)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def each_found_treasure
|
|
61
|
+
@found_treasures.each do |key, value|
|
|
62
|
+
yield TreasureTrove::Treasure.new key, value
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# TreasureTrove provides a `Treasure` class and `random` method to get Treasure.
|
|
2
|
+
module TreasureTrove
|
|
3
|
+
# Treasures have a `name` and `points` value.
|
|
4
|
+
Treasure = Struct.new :name, :points
|
|
5
|
+
|
|
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.sample
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def self.damaged_treasure(treasure)
|
|
20
|
+
Treasure.new treasure.name, treasure.points / 2.0
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'studio_game/berserk_player'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
describe 'BerserkPlayer' do
|
|
5
|
+
before do
|
|
6
|
+
@initial_health = 50
|
|
7
|
+
@player = BerserkPlayer.new 'berserker', @initial_health
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'does not go berserk when w00ted up to 5 times' do
|
|
11
|
+
1.upto(5) { @player.w00t }
|
|
12
|
+
|
|
13
|
+
expect(@player.berserk?).to be_falsey
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it 'goes berserk when w00ted more than 5 times' do
|
|
17
|
+
1.upto(6) { @player.w00t }
|
|
18
|
+
expect(@player.berserk?).to be_truthy
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'gets w00ted instead of blammed when gone berserk' do
|
|
22
|
+
1.upto(6) { @player.w00t }
|
|
23
|
+
1.upto(2) { @player.blam }
|
|
24
|
+
|
|
25
|
+
expect(@player.health).to eq @initial_health + 8 * 15
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'studio_game/clumsy_player'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
describe 'ClumsyPlayer' do
|
|
5
|
+
before do
|
|
6
|
+
@player = ClumsyPlayer.new 'klutz'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'gets only half the point value for each treasure' do
|
|
10
|
+
expect(@player.points).to eq 0
|
|
11
|
+
|
|
12
|
+
hammer = TreasureTrove::Treasure.new :hammer, 50
|
|
13
|
+
@player.found_treasure hammer
|
|
14
|
+
@player.found_treasure hammer
|
|
15
|
+
@player.found_treasure hammer
|
|
16
|
+
|
|
17
|
+
expect(@player.points).to eq 75
|
|
18
|
+
|
|
19
|
+
crowbar = TreasureTrove::Treasure.new :crowbar, 400
|
|
20
|
+
@player.found_treasure crowbar
|
|
21
|
+
expect(@player.points).to eq 275
|
|
22
|
+
|
|
23
|
+
yielded = []
|
|
24
|
+
@player.each_found_treasure do |treasure|
|
|
25
|
+
yielded << treasure
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
expected = [
|
|
29
|
+
TreasureTrove::Treasure.new(:hammer, 75),
|
|
30
|
+
TreasureTrove::Treasure.new(:crowbar, 200)
|
|
31
|
+
]
|
|
32
|
+
expect(yielded).to eq expected
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'studio_game/game'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
describe Game do
|
|
5
|
+
|
|
6
|
+
before do
|
|
7
|
+
@game = Game.new
|
|
8
|
+
@initial_health = 100
|
|
9
|
+
@player = Player.new 'moe', @initial_health
|
|
10
|
+
@game.add_player @player
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
context 'should w00t a player if a high number is rolled' do
|
|
14
|
+
it 'should play one round if no rounds provided' do
|
|
15
|
+
allow_any_instance_of(Die).to receive(:roll).and_return 5
|
|
16
|
+
@game.play
|
|
17
|
+
expect(@player.health).to eq @initial_health + 15
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'should play the rounds provided' do
|
|
21
|
+
rounds = 2
|
|
22
|
+
allow_any_instance_of(Die).to receive(:roll).and_return 5
|
|
23
|
+
@game.play rounds
|
|
24
|
+
expect(@player.health).to eq @initial_health + 15 * rounds
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'should do nothing to a player if a medium number is rolled' do
|
|
30
|
+
allow_any_instance_of(Die).to receive(:roll).and_return 3
|
|
31
|
+
@game.play
|
|
32
|
+
expect(@player.health).to eq @initial_health
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it 'should blam a player if a low number is rolled' do
|
|
36
|
+
allow_any_instance_of(Die).to receive(:roll).and_return 1
|
|
37
|
+
@game.play
|
|
38
|
+
expect(@player.health).to eq @initial_health - 10
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'assigns a treasure for points during a turn' do
|
|
42
|
+
game = Game.new
|
|
43
|
+
player = Player.new 'moe'
|
|
44
|
+
game.add_player player
|
|
45
|
+
game.play 1
|
|
46
|
+
expect(player.points).not_to eq 0
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
require 'studio_game/player'
|
|
2
|
+
require 'studio_game/treasure_trove'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
module StudioGame
|
|
6
|
+
# rubocop:disable BlockLength
|
|
7
|
+
describe Player do
|
|
8
|
+
before do
|
|
9
|
+
@player = Player.new 'shemp'
|
|
10
|
+
$stdout = StringIO.new
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'has a capitalized name' do
|
|
14
|
+
expect(@player.name).to eq 'Shemp'
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'has an initial health' do
|
|
18
|
+
expect(@player.health).to eq 100
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'has a string representation' do
|
|
22
|
+
expected = "I'm Shemp with health = 100, points = 0, and score = 100."
|
|
23
|
+
expect(@player.to_s).to eq expected
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'computes a score as the sum of its health and points' do
|
|
27
|
+
treasure = TreasureTrove::Treasure.new :hammer, 50
|
|
28
|
+
2.times { @player.found_treasure treasure }
|
|
29
|
+
expect(@player.score).to eq 100 + 2 * 50
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'increases health by 15 when w00ted' do
|
|
33
|
+
@player.w00t
|
|
34
|
+
expect(@player.health).to eq 115
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'decreases health by 10 when blammed' do
|
|
38
|
+
@player.blam
|
|
39
|
+
expect(@player.health).to eq 90
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'computes points as the sum of all treasure points' do
|
|
43
|
+
expect(@player.points).to eq 0
|
|
44
|
+
|
|
45
|
+
@player.found_treasure TreasureTrove::Treasure.new :hammer, 50
|
|
46
|
+
expect(@player.points).to eq 50
|
|
47
|
+
|
|
48
|
+
@player.found_treasure TreasureTrove::Treasure.new :crowbar, 400
|
|
49
|
+
expect(@player.points).to eq 450
|
|
50
|
+
|
|
51
|
+
@player.found_treasure TreasureTrove::Treasure.new :hammer, 50
|
|
52
|
+
expect(@player.points).to eq 500
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
context 'strong player' do
|
|
56
|
+
before do
|
|
57
|
+
@player = Player.new 'moe', 150
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'should be strong?' do
|
|
61
|
+
expect(@player.strong?).to be_truthy
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context 'weak player' do
|
|
66
|
+
before do
|
|
67
|
+
@player = Player.new 'curly', 50
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'should not be strong' do
|
|
71
|
+
expect(@player.strong?).not_to be_truthy
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'yields each found treasure and its total points' do
|
|
76
|
+
@player.found_treasure TreasureTrove::Treasure.new :skillet, 100
|
|
77
|
+
@player.found_treasure TreasureTrove::Treasure.new :skillet, 100
|
|
78
|
+
@player.found_treasure TreasureTrove::Treasure.new :hammer, 50
|
|
79
|
+
@player.found_treasure TreasureTrove::Treasure.new :bottle, 5
|
|
80
|
+
@player.found_treasure TreasureTrove::Treasure.new :bottle, 5
|
|
81
|
+
@player.found_treasure TreasureTrove::Treasure.new :bottle, 5
|
|
82
|
+
@player.found_treasure TreasureTrove::Treasure.new :bottle, 5
|
|
83
|
+
@player.found_treasure TreasureTrove::Treasure.new :bottle, 5
|
|
84
|
+
|
|
85
|
+
yielded = []
|
|
86
|
+
@player.each_found_treasure do |treasure|
|
|
87
|
+
yielded << treasure
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
expect(yielded).to eq [
|
|
91
|
+
TreasureTrove::Treasure.new(:skillet, 200),
|
|
92
|
+
TreasureTrove::Treasure.new(:hammer, 50),
|
|
93
|
+
TreasureTrove::Treasure.new(:bottle, 25)
|
|
94
|
+
]
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
# rubocop: enable Metrics/BlockLength
|
|
98
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'studio_game/treasure_trove'
|
|
2
|
+
|
|
3
|
+
module StudioGame
|
|
4
|
+
describe 'Treasure' do
|
|
5
|
+
before do
|
|
6
|
+
@treasure = TreasureTrove::Treasure.new :hammer, 50
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'has a name attribute' do
|
|
10
|
+
expect(@treasure.name).to eq :hammer
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'has a points attribute' do
|
|
14
|
+
expect(@treasure.points).to eq 50
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# rubocop: disable Metrics/BlockLength
|
|
19
|
+
describe 'TreasureTrove' do
|
|
20
|
+
it 'has six treasures' do
|
|
21
|
+
expect(TreasureTrove::TREASURES.size).to eq 6
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'has a pie worth 5 points' do
|
|
25
|
+
treasure = TreasureTrove::Treasure.new :pie, 5
|
|
26
|
+
expect(TreasureTrove::TREASURES).to include treasure
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'has a bottle worth 25 points' do
|
|
30
|
+
treasure = TreasureTrove::Treasure.new :bottle, 25
|
|
31
|
+
expect(TreasureTrove::TREASURES).to include treasure
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it 'has a hammer worth 50 points' do
|
|
35
|
+
treasure = TreasureTrove::Treasure.new :hammer, 50
|
|
36
|
+
expect(TreasureTrove::TREASURES).to include treasure
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'has a skillet worth 100 points' do
|
|
40
|
+
treasure = TreasureTrove::Treasure.new :skillet, 100
|
|
41
|
+
expect(TreasureTrove::TREASURES).to include treasure
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'has a broomstick worth 200 points' do
|
|
45
|
+
treasure = TreasureTrove::Treasure.new :broomstick, 200
|
|
46
|
+
expect(TreasureTrove::TREASURES).to include treasure
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'has a crowbar worth 400 points' do
|
|
50
|
+
treasure = TreasureTrove::Treasure.new :crowbar, 400
|
|
51
|
+
expect(TreasureTrove::TREASURES).to include treasure
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
it 'returns a random treasure' do
|
|
55
|
+
treasure = TreasureTrove.random
|
|
56
|
+
expect(TreasureTrove::TREASURES).to include treasure
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
# rubocop: enable Metrics/BlockLength
|
|
60
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: studio-game-soobrakay
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- soobrakay
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2017-09-10 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: '3.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '3.0'
|
|
27
|
+
description: |
|
|
28
|
+
studio-game
|
|
29
|
+
===========
|
|
30
|
+
|
|
31
|
+
Project from the [Pragmatic Studio Ruby Course][1]. Click the link to learn
|
|
32
|
+
more.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
[1]: https://online.pragmaticstudio.com/courses/ruby/
|
|
36
|
+
email: soobrakay@github.com
|
|
37
|
+
executables:
|
|
38
|
+
- studio-game
|
|
39
|
+
extensions: []
|
|
40
|
+
extra_rdoc_files: []
|
|
41
|
+
files:
|
|
42
|
+
- LICENSE
|
|
43
|
+
- README.md
|
|
44
|
+
- bin/players.csv
|
|
45
|
+
- bin/studio-game
|
|
46
|
+
- lib/studio_game/auditable.rb
|
|
47
|
+
- lib/studio_game/berserk_player.rb
|
|
48
|
+
- lib/studio_game/clumsy_player.rb
|
|
49
|
+
- lib/studio_game/die.rb
|
|
50
|
+
- lib/studio_game/game.rb
|
|
51
|
+
- lib/studio_game/game_turn.rb
|
|
52
|
+
- lib/studio_game/loaded_die.rb
|
|
53
|
+
- lib/studio_game/playable.rb
|
|
54
|
+
- lib/studio_game/player.rb
|
|
55
|
+
- lib/studio_game/treasure_trove.rb
|
|
56
|
+
- spec/studio_game/berserk_player_spec.rb
|
|
57
|
+
- spec/studio_game/clumsy_player_spec.rb
|
|
58
|
+
- spec/studio_game/game_spec.rb
|
|
59
|
+
- spec/studio_game/player_spec.rb
|
|
60
|
+
- spec/studio_game/treasure_trove_spec.rb
|
|
61
|
+
homepage: https://github.com/soobrakay/studio-game
|
|
62
|
+
licenses:
|
|
63
|
+
- MIT
|
|
64
|
+
metadata: {}
|
|
65
|
+
post_install_message:
|
|
66
|
+
rdoc_options: []
|
|
67
|
+
require_paths:
|
|
68
|
+
- lib
|
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '1.9'
|
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: '0'
|
|
79
|
+
requirements: []
|
|
80
|
+
rubyforge_project:
|
|
81
|
+
rubygems_version: 2.6.11
|
|
82
|
+
signing_key:
|
|
83
|
+
specification_version: 4
|
|
84
|
+
summary: Gem from Pragmatic Studio Ruby Course
|
|
85
|
+
test_files:
|
|
86
|
+
- spec/studio_game/berserk_player_spec.rb
|
|
87
|
+
- spec/studio_game/clumsy_player_spec.rb
|
|
88
|
+
- spec/studio_game/game_spec.rb
|
|
89
|
+
- spec/studio_game/player_spec.rb
|
|
90
|
+
- spec/studio_game/treasure_trove_spec.rb
|