prag_studio_game 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 444e1edb5016c188e577e45c9f8092c077419d67
4
+ data.tar.gz: 9bed43b7a180f124fc960c124f2b9ff8b4eaa739
5
+ SHA512:
6
+ metadata.gz: 0825d678647a8d14946a4753386efb35c0474f0d5e51498e0da4c228df22904aefbc807a74b89bc103c120a98fd958a5eb35dbec47da9fd7da92175b3467fb70
7
+ data.tar.gz: 0dedec93dfb8945678f92a1be372b78c4397dbdef8ccd9bdb6166ec6f529d7c894b26a504c0bf534a6a4aba0b2304b3f71ceaf0a3234994a94af7b99df27dcc9
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2016 Waihon Yew
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,63 @@
1
+ Studio Game is a Ruby program developed based on Pragmatic Studio' Ruby Programming hands-on video course, and distributed as a Ruby gem.
2
+
3
+ This program has been developed using all the strengths of Ruby including the following.
4
+
5
+ Ruby Programming Environment
6
+ * Installing Ruby on your favorite operating system (free exercise)
7
+ * Running Ruby using the interactive Ruby shell (irb) and writing Ruby program files
8
+ * Using Ruby's documentation system to get help
9
+ * Installing external Ruby libraries using RubyGems
10
+ * Troubleshooting common problems
11
+
12
+ Ruby Language Constructs
13
+ * Expressions and variables
14
+ * Numbers, string, and symbols (free video & exercise)
15
+ * Loops and conditional expressions
16
+ * Arrays and hashes (free video & exercise on hashes)
17
+ * Classes, modules, and structs
18
+
19
+ Object-Oriented Programming
20
+ * Using built-in Ruby classes
21
+ * Defining your own classes with state and behavior (free video & exercise)
22
+ * Creating unique objects
23
+ * Telling objects what to do by calling methods
24
+ * Modeling class-level inheritance relationships
25
+ * Sharing code with mixins
26
+
27
+ Object-Oriented Design Principles
28
+ * Encapsulation
29
+ * Separation of concerns
30
+ * Polymorphism
31
+ * Don't Repeat Yourself
32
+ * Tell, Don't Ask
33
+
34
+ Blocks and Iterators
35
+ * Calling built-in methods that take blocks
36
+ * Writing your own methods that yield to blocks
37
+ * Implementing custom iterators
38
+ * Effectively using blocks in your programs
39
+
40
+ Organizing Ruby Code
41
+ * Creating a Ruby project structure
42
+ * Separating source files for easier reuse and testing
43
+ * Namespacing to avoid naming clashes
44
+
45
+ * Input/Output
46
+ * Reading data from files
47
+ * Writing data to files
48
+ * Creating an interactive console prompt
49
+ * Handling command-line input
50
+
51
+ Unit Testing
52
+ * Writing and running unit tests with RSpec
53
+ * Test-driven development and the red-green-refactor cycle
54
+ * Stubbing methods to control tests
55
+ * Refactoring code, safely!
56
+
57
+ Distribution
58
+ * Conforming to RubyGems conventions
59
+ * Writing a GemSpec
60
+ * Building a RubyGem
61
+ * Publishing a RubyGem to a public server
62
+
63
+ Ruby Programming Idioms
@@ -0,0 +1,6 @@
1
+ Knuckleheads High Scores:
2
+ Simon............... 765
3
+ Klutz............... 550.0
4
+ Alvin............... 535
5
+ Theo................ 250
6
+ Berserker........... 105
@@ -0,0 +1,3 @@
1
+ Alvin,100
2
+ Simon,60
3
+ Theo,125
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/studio_game/game'
3
+ require_relative '../lib/studio_game/clumsy_player'
4
+ require_relative '../lib/studio_game/berserk_player'
5
+
6
+ knuckleheads = StudioGame::Game.new("Knuckleheads")
7
+ default_player_file = File.join(File.dirname(__FILE__), "players.csv")
8
+ knuckleheads.load_players(ARGV.shift || default_player_file)
9
+
10
+ klutz = StudioGame::ClumsyPlayer.new("klutz", 105)
11
+ knuckleheads.add_player(klutz)
12
+
13
+ berserker = StudioGame::BerserkPlayer.new("berserker", 50)
14
+ knuckleheads.add_player(berserker)
15
+
16
+ loop do
17
+ puts "\nHow many game rounds? ('quit' to exit)"
18
+ answer = gets.chomp.downcase
19
+ case answer
20
+ when /^\d+$/
21
+ #knuckleheads.play(answer.to_i) do
22
+ # knuckleheads.total_points >= 5_000
23
+ #end
24
+ knuckleheads.play(answer.to_i)
25
+ when "quit", "exit"
26
+ knuckleheads.print_stats
27
+ break
28
+ else
29
+ puts "Please enter a number or 'quit'"
30
+ end
31
+ end
32
+
33
+ knuckleheads.save_high_scores
@@ -0,0 +1,7 @@
1
+ module StudioGame
2
+ module Auditable
3
+ def audit
4
+ puts "\nRolled a #{self.number} (#{self.class})"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'player'
2
+
3
+ module StudioGame
4
+ class BerserkPlayer < Player
5
+ def initialize(name, health=100)
6
+ super(name, health)
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
24
+
25
+ if __FILE__ == $0
26
+ berserker = BerserkPlayer.new("berserker", 50)
27
+ 6.times { berserker.w00t }
28
+ 2.times { berserker.blam }
29
+ puts berserker.health
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ module StudioGame
2
+ class Calculator
3
+ def initialize(num1, num2)
4
+ @num1 = num1
5
+ @num2 = num2
6
+ end
7
+
8
+ def add
9
+ @num1 + @num2
10
+ end
11
+
12
+ def subtract
13
+ @num1 - @num2
14
+ end
15
+ end
16
+
17
+ calc = Calculator.new(20, 11)
18
+ puts calc.add
19
+ puts calc.subtract
20
+ 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 found_treasure(treasure)
13
+ damaged_treasure = Treasure.new(treasure.name, treasure.points / 2.0)
14
+ super(damaged_treasure)
15
+ end
16
+
17
+ def w00t
18
+ @boost_factor.times { super }
19
+ end
20
+ end
21
+
22
+ if __FILE__ == $0
23
+ clumsy = ClumsyPlayer.new("klutz")
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
38
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'auditable'
2
+
3
+ module StudioGame
4
+ class Die
5
+ include Auditable
6
+
7
+ attr_reader :number
8
+
9
+ def initialize
10
+ #roll
11
+ end
12
+
13
+ def roll
14
+ @number = rand(1..6)
15
+ audit
16
+ @number
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,113 @@
1
+ require_relative 'player'
2
+ require_relative 'die'
3
+ require_relative 'game_turn'
4
+ require_relative 'treasure_trove'
5
+ require 'pp'
6
+ require 'csv'
7
+
8
+ module StudioGame
9
+ class Game
10
+ attr_reader :title
11
+
12
+ def initialize(title)
13
+ @title = title
14
+ @players = []
15
+ end
16
+
17
+ def add_player(player)
18
+ @players << player
19
+ end
20
+
21
+ def play(rounds)
22
+ puts "There are #{@players.size} players in #{@title}:"
23
+ @players.each do |player|
24
+ puts player
25
+ end
26
+
27
+ treasures = TreasureTrove::TREASURES
28
+ puts "\nTheere are #{treasures.size} treasures to be found:"
29
+ treasures.each do |treasure|
30
+ puts "A #{treasure.name} is worth #{treasure.points} points"
31
+ end
32
+
33
+ 1.upto(rounds) do |round|
34
+ if block_given?
35
+ # Exit the game if the block indicates so
36
+ break if yield
37
+ end
38
+ puts "\nRound #{round}:"
39
+ @players.each do |player|
40
+ GameTurn.take_turn(player)
41
+ puts player
42
+ end
43
+ end
44
+ end
45
+
46
+ def print_stats
47
+ strong_players, wimpy_players = @players.partition { |player| player.strong? }
48
+
49
+ puts "\n#{@title} Statistics:"
50
+
51
+ puts "\n#{strong_players.size} strong players:"
52
+ strong_players.each do |player|
53
+ print_name_and_health(player)
54
+ end
55
+
56
+ puts "\n#{wimpy_players.size} wimpy players:"
57
+ wimpy_players.each do |player|
58
+ print_name_and_health(player)
59
+ end
60
+
61
+ @players.each do |player|
62
+ puts "\n#{player.name}'s point totals:"
63
+ player.each_found_treasure do |treasure|
64
+ puts "#{treasure.points} total #{treasure.name} points"
65
+ end
66
+ puts "#{player.points} grand total points"
67
+ end
68
+
69
+ puts "\n#{total_points} total points from treasures found"
70
+
71
+ print_high_scores
72
+ end
73
+
74
+ def total_points
75
+ @players.reduce(0) { |sum, player| sum + player.points }
76
+ end
77
+
78
+ def load_players(from_file)
79
+ #File.readlines(from_file).each do |line|
80
+ #add_player(Player.from_csv(line))
81
+ CSV.foreach(from_file) do |row|
82
+ player = Player.new(row[0], Integer(row[1]))
83
+ add_player(player)
84
+ end
85
+ end
86
+
87
+ def save_high_scores(to_file="high_scores.txt")
88
+ File.open(to_file, "w") do |file|
89
+ print_high_scores(file)
90
+ end
91
+ end
92
+
93
+ private
94
+
95
+ def print_name_and_health(player)
96
+ puts "#{player.name} (#{player.health})"
97
+ end
98
+
99
+ def high_score_entry(player)
100
+ formatted_name = player.name.ljust(20, ".")
101
+ "#{formatted_name} #{player.score}"
102
+ end
103
+
104
+ def print_high_scores(file=$stdout)
105
+ prefix = "\n" if file == $stdout
106
+ file.puts "#{prefix}#{@title} High Scores:"
107
+ @players.sort.each do |player|
108
+ file.puts high_score_entry(player)
109
+ end
110
+ end
111
+
112
+ end
113
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'die'
2
+ require_relative 'player'
3
+ require_relative 'treasure_trove'
4
+
5
+ module StudioGame
6
+ module GameTurn
7
+ def self.take_turn(player)
8
+ #def take_turn(player)
9
+ die = Die.new
10
+ case die.roll
11
+ when 1..2
12
+ player.blam
13
+ when 3..4
14
+ puts "#{player.name} was skipped."
15
+ else
16
+ player.w00t
17
+ end
18
+
19
+ treasure = TreasureTrove.random
20
+ player.found_treasure(treasure)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ module StudioGame
2
+ def conversation
3
+ puts "Hello"
4
+ yield
5
+ puts "Goodbye"
6
+ end
7
+
8
+ conversation { puts "Good to meet you!" }
9
+
10
+ def five_times
11
+ # yield 1
12
+ # yield 2
13
+ # yield 3
14
+ # yield 4
15
+ # yield 5
16
+ # or
17
+ 1.upto(5) do |count|
18
+ yield count
19
+ end
20
+ end
21
+
22
+ five_times do |n|
23
+ puts "#{n} situps"
24
+ puts "#{n} pushups"
25
+ puts "#{n} chinups"
26
+ end
27
+
28
+ def n_times(number)
29
+ 1.upto(number) do |count|
30
+ yield count
31
+ end
32
+ end
33
+
34
+ n_times(5) do |n|
35
+ puts "#{n} situps"
36
+ puts "#{n} pushups"
37
+ puts "#{n} chinups"
38
+ end
39
+ end
@@ -0,0 +1,14 @@
1
+ module StudioGame
2
+ class LoadedDie
3
+ include Auditable
4
+
5
+ attr_reader :number
6
+
7
+ def roll
8
+ numbers = [1, 1, 2, 5, 6, 6]
9
+ @number = numbers.sample
10
+ audit
11
+ @number
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module StudioGame
2
+ module Playable
3
+ def w00t
4
+ self.health += 15
5
+ puts "#{self.name} got w00ted!"
6
+ end
7
+
8
+ def blam
9
+ self.health -= 10
10
+ puts "#{self.name} got blammed!"
11
+ end
12
+
13
+ def strong?
14
+ self.health > 100
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,68 @@
1
+ require_relative 'treasure_trove'
2
+ require_relative 'playable'
3
+
4
+ module StudioGame
5
+ class Player
6
+ include Playable
7
+
8
+ attr_accessor :name
9
+ attr_accessor :health
10
+
11
+ def initialize(name, health=100)
12
+ @name = name.capitalize
13
+ @health = health
14
+ @found_treasures = Hash.new(0)
15
+ end
16
+
17
+ def self.from_csv(string)
18
+ name, health = string.split(",")
19
+ Player.new(name, Integer(health))
20
+ end
21
+
22
+ def name=(new_name)
23
+ @name = new_name.capitalize
24
+ end
25
+
26
+ def to_s
27
+ "I'm #{@name} with health = #{@health}, points = #{points}, and score = #{score}."
28
+ end
29
+
30
+ def score
31
+ @health + points
32
+ end
33
+
34
+
35
+ def <=>(other)
36
+ other.score <=> score
37
+ end
38
+
39
+ def found_treasure(treasure)
40
+ @found_treasures[treasure.name] += treasure.points
41
+ puts "#{@name} found a #{treasure.name} worth #{treasure.points} points."
42
+ puts "#{@name}'s treasures: #{@found_treasures}"
43
+ end
44
+
45
+ def points
46
+ @found_treasures.values.reduce(0, :+)
47
+ end
48
+
49
+ def each_found_treasure
50
+ @found_treasures.each do |name, points|
51
+ yield Treasure.new(name, points)
52
+ end
53
+ end
54
+
55
+ end
56
+
57
+ # If current source file is the same as
58
+ # the name of the Ruby program file being run
59
+ if __FILE__ == $0 # or $PROGRAM_NAME
60
+ player = Player.new("moe")
61
+ puts player.name
62
+ puts player.health
63
+ player.w00t
64
+ puts player.health
65
+ player.blam
66
+ puts player.health
67
+ end
68
+ end
@@ -0,0 +1,23 @@
1
+ require 'pp'
2
+
3
+ module StudioGame
4
+ letters = { "c"=>3, "e"=>1, "l"=>1, "n"=>1, "t"=>1, "x"=>8, "y"=>4 }
5
+
6
+ # score = "excellently".each_char.reduce(0) { |sum, char| sum + letters[char] }
7
+ # or
8
+ score = 0
9
+ "excellently".each_char { |c| score += letters[c] }
10
+ #=> 23
11
+ # e x c e l l e n t l y
12
+ # 1 8 3 1 1 1 1 1 1 1 4
13
+ pp score
14
+
15
+ point_totals = Hash.new(0)
16
+ "excellently".each_char { |c| point_totals[c] += letters[c] }
17
+ pp point_totals
18
+
19
+ # score = point_totals.reduce(0) { |sum, point| pp point; sum += point[1] }
20
+ # or
21
+ score = point_totals.values.reduce(0, :+)
22
+ pp score
23
+ end
@@ -0,0 +1,18 @@
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 self.random
15
+ TREASURES.sample
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,31 @@
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
+ expect(@player.berserk?).to be_falsey
15
+ end
16
+
17
+ it "goes berserk when w00ted more than 5 times" do
18
+ 1.upto(6) { @player.w00t }
19
+
20
+ expect(@player.berserk?).to be_truthy
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
+ expect(@player.health).to eq(@initial_health + ((6 + 2) * 15))
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,51 @@
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 "only gets half the point value for each treasure" do
10
+ expect(@player.points).to be_zero
11
+
12
+ hammer = 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 = Treasure.new(:crowbar, 400)
20
+ @player.found_treasure(crowbar)
21
+
22
+ expect(@player.points).to eq(275)
23
+
24
+ yielded = []
25
+ @player.each_found_treasure do |treasure|
26
+ yielded << treasure
27
+ end
28
+
29
+ expect(yielded).to eq([Treasure.new(:hammer, 75), Treasure.new(:crowbar, 200)])
30
+ end
31
+
32
+ context "with a boost factor" do
33
+ before do
34
+ @initial_health = 100
35
+ @boost_factor = 5
36
+ @player = ClumsyPlayer.new("klutz", @initial_health, @boost_factor)
37
+ end
38
+
39
+ it "has a boost factor" do
40
+ expect(@player.boost_factor).to eq(5)
41
+ end
42
+
43
+ it "gets boost factor number of w00ts when w00ted" do
44
+ @player.w00t
45
+
46
+ expect(@player.health).to eq(@initial_health + (15 * @boost_factor))
47
+ end
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,74 @@
1
+ require 'studio_game/spec_helper'
2
+ require 'studio_game/game'
3
+ require 'studio_game/die'
4
+
5
+ module StudioGame
6
+ describe Game do
7
+
8
+ before do
9
+ @game = Game.new("Knuckleheads")
10
+
11
+ @initial_health = 100
12
+ @player = Player.new("moe", @initial_health)
13
+
14
+ @game.add_player(@player)
15
+
16
+ $stdout = StringIO.new
17
+ end
18
+
19
+ it "w00ts the player if a high number is rolled" do
20
+ #Die.any_instance.stub(:roll).and_return(5)
21
+ allow_any_instance_of(Die).to receive(:roll).and_return(5)
22
+
23
+ @game.play(2)
24
+
25
+ expect(@player.health).to eq(@initial_health + (15 * 2))
26
+ end
27
+
28
+ it "skips the player if a medium number is rolled" do
29
+ #Die.any_instance.stub(:roll).and_return(3)
30
+ allow_any_instance_of(Die).to receive(:roll).and_return(3)
31
+
32
+ @game.play(2)
33
+
34
+ expect(@player.health).to eq(@initial_health)
35
+ end
36
+
37
+ it "blam the player if a low number is rolled" do
38
+ #Die.any_instance.stub(:roll).and_return(1)
39
+ allow_any_instance_of(Die).to receive(:roll).and_return(1)
40
+
41
+ @game.play(2)
42
+
43
+ expect(@player.health).to eq(@initial_health - (10 * 2))
44
+ end
45
+
46
+ it "assigns a treasure for points during a player's turn" do
47
+ game = Game.new("Knuckleheads")
48
+ player = Player.new("moe")
49
+
50
+ game.add_player(player)
51
+
52
+ game.play(1)
53
+
54
+ expect(player.points).not_to be_zero
55
+ end
56
+
57
+ it "computes total points as the sum of all player points" do
58
+ game = Game.new("Knuckleheads")
59
+
60
+ player1 = Player.new("moe")
61
+ player2 = Player.new("larry")
62
+
63
+ game.add_player(player1)
64
+ game.add_player(player2)
65
+
66
+ player1.found_treasure(Treasure.new(:hammer, 50))
67
+ player1.found_treasure(Treasure.new(:hammer, 50))
68
+ player2.found_treasure(Treasure.new(:crowbar, 400))
69
+
70
+ expect(game.total_points).to eq(500)
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,152 @@
1
+ require 'studio_game/spec_helper'
2
+ require 'studio_game/player'
3
+ require 'studio_game/treasure_trove'
4
+
5
+ module StudioGame
6
+ # The describe method defines an example group, which takes the name of
7
+ # the group as string or as a class name.
8
+ describe Player do
9
+ before do
10
+ @initial_health = 150
11
+ @player = Player.new("larry", @initial_health)
12
+ $stdout = StringIO.new
13
+ end
14
+
15
+ # The it method defines a code example, and generally you want to use
16
+ # a string that expresses the behavior your're expecting.
17
+ it "has a capitalized name" do
18
+ # @player.name.should == "Larry"
19
+ # or
20
+ expect(@player.name).to eq("Larry")
21
+ end
22
+
23
+ it "has an initial health" do
24
+ # @player.health.should == 150
25
+ # or
26
+ expect(@player.health).to eq(150)
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
+
33
+ # @player.to_s.should == "I'm Larry with health = 150, points = 100, and score = 250."
34
+ # or
35
+ expect(@player.to_s).to eq("I'm Larry with health = 150, points = 100, and score = 250.")
36
+ end
37
+
38
+ it "computes a score as the sum of its health and points" do
39
+ @player.found_treasure(Treasure.new(:hammer, 50))
40
+ @player.found_treasure(Treasure.new(:hammer, 50))
41
+
42
+ # @player.score.should == (@initial_health + 5)
43
+ # or
44
+ expect(@player.score).to eq(@initial_health + 50 + 50)
45
+ end
46
+
47
+ it "increases health by 15 when w00ted" do
48
+ @player.w00t
49
+
50
+ # @player.health.should == (initial_health + 15)
51
+ # or
52
+ expect(@player.health).to eq(@initial_health + 15)
53
+ end
54
+
55
+ it "decreases health by 10 when blammed" do
56
+ @player.blam
57
+
58
+ # @player.health.should == (initial_health - 10)
59
+ # or
60
+ expect(@player.health).to eq(@initial_health - 10)
61
+ end
62
+
63
+ context "with a health greater than 100" do
64
+ before do
65
+ @initial_health = 150
66
+ @player = Player.new("larry", @initial_health)
67
+ end
68
+
69
+ it "is strong" do
70
+ # expect(@player.strong?).to eq(true)
71
+ # or
72
+ # expect(@player.strong?).to be_truthy
73
+ # or
74
+ expect(@player).to be_strong
75
+ end
76
+ end
77
+
78
+ context "with a health of 100 or less" do
79
+ before do
80
+ @initial_health = 100
81
+ @player = Player.new("larry", @initial_health)
82
+ end
83
+
84
+ it "is wimpy" do
85
+ # expect(@player).to_not be_strong
86
+ # or
87
+ expect(@player).not_to be_strong
88
+ end
89
+ end
90
+
91
+ context "in a collection of players" do
92
+ before do
93
+ @player1 = Player.new("moe", 100)
94
+ @player2 = Player.new("larry", 200)
95
+ @player3 = Player.new("curly", 300)
96
+
97
+ @players = [@player1, @player2, @player3]
98
+ end
99
+
100
+ it "is sorted by decreasing score" do
101
+ expect(@players.sort).to eq([@player3, @player2, @player1])
102
+ end
103
+ end
104
+
105
+ it "computes points as the sum of all treasure points" do
106
+ expect(@player.points).to eq(0)
107
+
108
+ @player.found_treasure(Treasure.new(:hammer, 50))
109
+
110
+ expect(@player.points).to eq(50)
111
+
112
+ @player.found_treasure(Treasure.new(:crowbar, 400))
113
+
114
+ expect(@player.points).to eq(450)
115
+
116
+ @player.found_treasure(Treasure.new(:hammer, 50))
117
+
118
+ expect(@player.points).to eq(500)
119
+ end
120
+
121
+ it "yields each found treasure and its total points" do
122
+ @player.found_treasure(Treasure.new(:skillet, 100))
123
+ @player.found_treasure(Treasure.new(:skillet, 100))
124
+ @player.found_treasure(Treasure.new(:hammer, 50))
125
+ @player.found_treasure(Treasure.new(:bottle, 5))
126
+ @player.found_treasure(Treasure.new(:bottle, 5))
127
+ @player.found_treasure(Treasure.new(:bottle, 5))
128
+ @player.found_treasure(Treasure.new(:bottle, 5))
129
+ @player.found_treasure(Treasure.new(:bottle, 5))
130
+
131
+ yielded = []
132
+ @player.each_found_treasure do |treasure|
133
+ yielded << treasure
134
+ end
135
+
136
+ expect(yielded).to eq([
137
+ Treasure.new(:skillet, 200),
138
+ Treasure.new(:hammer, 50),
139
+ Treasure.new(:bottle, 25)
140
+ ])
141
+ end
142
+
143
+ it "can be created from a CSV string" do
144
+ string = "larry,95"
145
+ player = Player.from_csv(string)
146
+
147
+ expect(player.name).to eq("Larry")
148
+ expect(player.health).to eq(95)
149
+ end
150
+
151
+ end
152
+ end
@@ -0,0 +1,10 @@
1
+ module StudioGame
2
+ RSpec.configure do |config|
3
+ config.expect_with :rspec do |c|
4
+ c.syntax = [:should, :expect]
5
+ end
6
+ config.mock_with :rspec do |c|
7
+ c.syntax = [:should, :expect]
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,57 @@
1
+ require 'studio_game/spec_helper'
2
+ require 'studio_game/treasure_trove'
3
+
4
+ module StudioGame
5
+ describe Treasure do
6
+
7
+ before do
8
+ @treasure = Treasure.new(:hammer, 50)
9
+ end
10
+
11
+ it "has a name attribute" do
12
+ expect(@treasure.name).to eq(:hammer)
13
+ end
14
+
15
+ it "has a points attribute" do
16
+ expect(@treasure.points).to eq(50)
17
+ end
18
+ end
19
+
20
+ describe "TreasureTrove" do
21
+
22
+ it "has six treasures" do
23
+ expect(TreasureTrove::TREASURES.size).to eq(6)
24
+ end
25
+
26
+ it "has a pie worth 5 points" do
27
+ expect(TreasureTrove::TREASURES[0]).to eq(Treasure.new(:pie, 5))
28
+ end
29
+
30
+ it "has a bottle worth 25 points" do
31
+ expect(TreasureTrove::TREASURES[1]).to eq(Treasure.new(:bottle, 25))
32
+ end
33
+
34
+ it "has a pie hammer 50 points" do
35
+ expect(TreasureTrove::TREASURES[2]).to eq(Treasure.new(:hammer, 50))
36
+ end
37
+
38
+ it "has a skillet worth 100 points" do
39
+ expect(TreasureTrove::TREASURES[3]).to eq(Treasure.new(:skillet, 100))
40
+ end
41
+
42
+ it "has a broomstick worth 200 points" do
43
+ expect(TreasureTrove::TREASURES[4]).to eq(Treasure.new(:broomstick, 200))
44
+ end
45
+
46
+ it "has a crowbar worth 400 points" do
47
+ expect(TreasureTrove::TREASURES[5]).to eq(Treasure.new(:crowbar, 400))
48
+ end
49
+
50
+ it "returns a random treasure" do
51
+ treasure = TreasureTrove.random
52
+
53
+ expect(TreasureTrove::TREASURES).to include(treasure)
54
+ end
55
+
56
+ end
57
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prag_studio_game
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Waihon Yew
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-27 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.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.5'
27
+ description: |
28
+ Studio Game is a Ruby program developed based on Pragmatic Studio' Ruby Programming hands-on video course, and distributed as a Ruby gem.
29
+
30
+ This program has been developed using all the strengths of Ruby including the following.
31
+
32
+ Ruby Programming Environment
33
+ * Installing Ruby on your favorite operating system (free exercise)
34
+ * Running Ruby using the interactive Ruby shell (irb) and writing Ruby program files
35
+ * Using Ruby's documentation system to get help
36
+ * Installing external Ruby libraries using RubyGems
37
+ * Troubleshooting common problems
38
+
39
+ Ruby Language Constructs
40
+ * Expressions and variables
41
+ * Numbers, string, and symbols (free video & exercise)
42
+ * Loops and conditional expressions
43
+ * Arrays and hashes (free video & exercise on hashes)
44
+ * Classes, modules, and structs
45
+
46
+ Object-Oriented Programming
47
+ * Using built-in Ruby classes
48
+ * Defining your own classes with state and behavior (free video & exercise)
49
+ * Creating unique objects
50
+ * Telling objects what to do by calling methods
51
+ * Modeling class-level inheritance relationships
52
+ * Sharing code with mixins
53
+
54
+ Object-Oriented Design Principles
55
+ * Encapsulation
56
+ * Separation of concerns
57
+ * Polymorphism
58
+ * Don't Repeat Yourself
59
+ * Tell, Don't Ask
60
+
61
+ Blocks and Iterators
62
+ * Calling built-in methods that take blocks
63
+ * Writing your own methods that yield to blocks
64
+ * Implementing custom iterators
65
+ * Effectively using blocks in your programs
66
+
67
+ Organizing Ruby Code
68
+ * Creating a Ruby project structure
69
+ * Separating source files for easier reuse and testing
70
+ * Namespacing to avoid naming clashes
71
+
72
+ * Input/Output
73
+ * Reading data from files
74
+ * Writing data to files
75
+ * Creating an interactive console prompt
76
+ * Handling command-line input
77
+
78
+ Unit Testing
79
+ * Writing and running unit tests with RSpec
80
+ * Test-driven development and the red-green-refactor cycle
81
+ * Stubbing methods to control tests
82
+ * Refactoring code, safely!
83
+
84
+ Distribution
85
+ * Conforming to RubyGems conventions
86
+ * Writing a GemSpec
87
+ * Building a RubyGem
88
+ * Publishing a RubyGem to a public server
89
+
90
+ Ruby Programming Idioms
91
+ email: yewwaihon@gmail.com
92
+ executables:
93
+ - studio_game
94
+ extensions: []
95
+ extra_rdoc_files: []
96
+ files:
97
+ - LICENSE
98
+ - README
99
+ - bin/high_scores.txt
100
+ - bin/players.csv
101
+ - bin/studio_game
102
+ - lib/studio_game/auditable.rb
103
+ - lib/studio_game/berserk_player.rb
104
+ - lib/studio_game/calculator.rb
105
+ - lib/studio_game/clumsy_player.rb
106
+ - lib/studio_game/die.rb
107
+ - lib/studio_game/game.rb
108
+ - lib/studio_game/game_turn.rb
109
+ - lib/studio_game/iterators.rb
110
+ - lib/studio_game/loaded_die.rb
111
+ - lib/studio_game/playable.rb
112
+ - lib/studio_game/player.rb
113
+ - lib/studio_game/scrabble.rb
114
+ - lib/studio_game/treasure_trove.rb
115
+ - spec/studio_game/berserk_player_spec.rb
116
+ - spec/studio_game/clumsy_player_spec.rb
117
+ - spec/studio_game/game_spec.rb
118
+ - spec/studio_game/player_spec.rb
119
+ - spec/studio_game/spec_helper.rb
120
+ - spec/studio_game/treasure_trove_spec.rb
121
+ homepage: https://github.com/waihon/prag_studio_game
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '1.9'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.6.4
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Pragmatic Studio's Ruby Programming's Workbook App.
145
+ test_files:
146
+ - spec/studio_game/berserk_player_spec.rb
147
+ - spec/studio_game/clumsy_player_spec.rb
148
+ - spec/studio_game/game_spec.rb
149
+ - spec/studio_game/player_spec.rb
150
+ - spec/studio_game/spec_helper.rb
151
+ - spec/studio_game/treasure_trove_spec.rb