studio_game_michaelwestphal 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 +19 -0
- data/README +5 -0
- data/bin/players.csv +3 -0
- data/bin/studio_game +36 -0
- data/lib/studio_game/auditable.rb +7 -0
- data/lib/studio_game/berserk_player.rb +35 -0
- data/lib/studio_game/clumsy_player.rb +47 -0
- data/lib/studio_game/die.rb +26 -0
- data/lib/studio_game/game.rb +133 -0
- data/lib/studio_game/game_turn.rb +24 -0
- data/lib/studio_game/loaded_die.rb +16 -0
- data/lib/studio_game/playable.rb +20 -0
- data/lib/studio_game/player.rb +70 -0
- data/lib/studio_game/treasure_trove.rb +34 -0
- data/spec/studio_game/berserk_player_spec.rb +45 -0
- data/spec/studio_game/clumsy_player_spec.rb +57 -0
- data/spec/studio_game/game_spec.rb +90 -0
- data/spec/studio_game/player_spec.rb +119 -0
- data/spec/studio_game/treasure_trove_spec.rb +57 -0
- metadata +89 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA256:
         | 
| 3 | 
            +
              metadata.gz: a4cbbecafa0ce19433f2eceed117e16771cd618dc3dbd0d1d720c1f985754123
         | 
| 4 | 
            +
              data.tar.gz: '030397178ecb162e1554410aa2c0fc4d1352805f2a7c2e008880630f3cb2c679'
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 2d95850bf962e2ee726767b4b225e4a2b90b7fd09d0038c690a818f22bce973d303d319baa1b4a5878ffdbfbef12e2795a1f14ab921b0fb97e4cbbddf86a69b9
         | 
| 7 | 
            +
              data.tar.gz: ad368f65659c6447d0be0739465516383d2b24b2afee4ba250347fcc1f6be15d4517968b8abb747d9691a8ff69abf9fded349a0004a9be7e2a18321b6a42d26b
         | 
    
        data/LICENSE
    ADDED
    
    | @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            Copyright (c) 2022 Michael Westphal
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         | 
| 4 | 
            +
            of this software and associated documentation files (the "Software"), to deal
         | 
| 5 | 
            +
            in the Software without restriction, including without limitation the rights
         | 
| 6 | 
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         | 
| 7 | 
            +
            copies of the Software, and to permit persons to whom the Software is
         | 
| 8 | 
            +
            furnished to do so, subject to the following conditions:
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            The above copyright notice and this permission notice shall be included in all
         | 
| 11 | 
            +
            copies or substantial portions of the Software.
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         | 
| 14 | 
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         | 
| 15 | 
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         | 
| 16 | 
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         | 
| 17 | 
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         | 
| 18 | 
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
         | 
| 19 | 
            +
            SOFTWARE.
         | 
    
        data/README
    ADDED
    
    | @@ -0,0 +1,5 @@ | |
| 1 | 
            +
            # Studio Game
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            The Studio Game developed while taking the [Ruby Programming course](https://pragmaticstudio.com/courses/ruby) from the [Pragmatic Studio](https://pragmaticstudio.com/).
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            📚 **[My Pragmatic Studio alumni page](https://pragmaticstudio.com/alumni/michaelwestphal)**
         | 
    
        data/bin/players.csv
    ADDED
    
    
    
        data/bin/studio_game
    ADDED
    
    | @@ -0,0 +1,36 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            require_relative '../lib/studio_game/player'
         | 
| 3 | 
            +
            require_relative '../lib/studio_game/clumsy_player'
         | 
| 4 | 
            +
            require_relative '../lib/studio_game/berserk_player'
         | 
| 5 | 
            +
            require_relative '../lib/studio_game/game'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            klutz = StudioGame::ClumsyPlayer.new('klutz', 105)
         | 
| 8 | 
            +
            berserker = StudioGame::BerserkPlayer.new('berserker', 50)
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            knuckleheads = StudioGame::Game.new('Knuckleheads')
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            default_player_file = File.join(File.dirname(__FILE__), 'players.csv')
         | 
| 13 | 
            +
            knuckleheads.load_players(ARGV.shift || default_player_file)
         | 
| 14 | 
            +
            knuckleheads.add_player(klutz)
         | 
| 15 | 
            +
            knuckleheads.add_player(berserker)
         | 
| 16 | 
            +
             | 
| 17 | 
            +
            loop do
         | 
| 18 | 
            +
              puts "How many game rounds? ('quit' to exit)"
         | 
| 19 | 
            +
              # Chomp removes new line
         | 
| 20 | 
            +
              answer = gets.chomp.downcase
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              case answer
         | 
| 23 | 
            +
              when /^\d+$/
         | 
| 24 | 
            +
                knuckleheads.play(answer.to_i)
         | 
| 25 | 
            +
              when 'exit', 'quit'
         | 
| 26 | 
            +
                knuckleheads.print_stats
         | 
| 27 | 
            +
                break
         | 
| 28 | 
            +
              else
         | 
| 29 | 
            +
                puts "Please enter a number or 'quit'"
         | 
| 30 | 
            +
              end
         | 
| 31 | 
            +
            end
         | 
| 32 | 
            +
            knuckleheads.save_high_scores
         | 
| 33 | 
            +
             | 
| 34 | 
            +
            # knuckleheads.play(10) { knuckleheads.total_points >= 2000 }
         | 
| 35 | 
            +
             | 
| 36 | 
            +
            # puts player3.inspect
         | 
| @@ -0,0 +1,35 @@ | |
| 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 | 
            +
                  if berserk?
         | 
| 22 | 
            +
                    w00t
         | 
| 23 | 
            +
                  else
         | 
| 24 | 
            +
                    super
         | 
| 25 | 
            +
                  end
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            if __FILE__ == $PROGRAM_NAME
         | 
| 31 | 
            +
              berserker = StudioGame::BerserkPlayer.new("berserker", 50)
         | 
| 32 | 
            +
              6.times { berserker.w00t }
         | 
| 33 | 
            +
              2.times { berserker.blam }
         | 
| 34 | 
            +
              puts berserker.health
         | 
| 35 | 
            +
            end
         | 
| @@ -0,0 +1,47 @@ | |
| 1 | 
            +
            require_relative 'player'
         | 
| 2 | 
            +
            require_relative 'treasure_trove'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module StudioGame
         | 
| 5 | 
            +
              class ClumsyPlayer < Player
         | 
| 6 | 
            +
                attr_reader :boost_factor
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                def initialize(name, health = 100, boost_factor = 1)
         | 
| 9 | 
            +
                  super(name, health)
         | 
| 10 | 
            +
                  @boost_factor = boost_factor
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                def found_treasure(treasure)
         | 
| 14 | 
            +
                  # NOTE: The 2.0 denominator is changing the numeric type of the points held in the treasure
         | 
| 15 | 
            +
                  #  from an Integer to Float. (See the test within the TreasureTrove module.) This is changing
         | 
| 16 | 
            +
                  #  the value of the total_points method on the Game automatically converts the returned sum
         | 
| 17 | 
            +
                  #  into a Float when it comes across it in the treasures. Float must "supersede" Integer,
         | 
| 18 | 
            +
                  #  forcing a type conversion when working between integers and decimals. I bet we could force
         | 
| 19 | 
            +
                  #  it back with to_i...
         | 
| 20 | 
            +
                  damaged_treasure = Treasure.new(treasure.name, treasure.points / 2.0)
         | 
| 21 | 
            +
                  super(damaged_treasure)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def w00t
         | 
| 25 | 
            +
                  @boost_factor.times { super }
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
              end
         | 
| 28 | 
            +
            end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
            if __FILE__ == $PROGRAM_NAME
         | 
| 31 | 
            +
              clumsy = StudioGame::ClumsyPlayer.new("klutz", 100, 3)
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              hammer = StudioGame::Treasure.new(:hammer, 50)
         | 
| 34 | 
            +
              clumsy.found_treasure(hammer)
         | 
| 35 | 
            +
              clumsy.found_treasure(hammer)
         | 
| 36 | 
            +
              clumsy.found_treasure(hammer)
         | 
| 37 | 
            +
             | 
| 38 | 
            +
              crowbar = StudioGame::Treasure.new(:crowbar, 400)
         | 
| 39 | 
            +
              clumsy.found_treasure(crowbar)
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              clumsy.w00t
         | 
| 42 | 
            +
             | 
| 43 | 
            +
              clumsy.each_found_treasure do |treasure|
         | 
| 44 | 
            +
                puts "#{treasure.points} total #{treasure.name} points"
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
              puts "#{clumsy.points} grand total points"
         | 
| 47 | 
            +
            end
         | 
| @@ -0,0 +1,26 @@ | |
| 1 | 
            +
            require_relative 'auditable'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module StudioGame
         | 
| 4 | 
            +
              class Die
         | 
| 5 | 
            +
                include Auditable
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                attr_reader :number
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                # Introduced during Chapter 13: Conditionals and TDD as a means to ensure the number
         | 
| 10 | 
            +
                #  instance variable always has a valid value given the attribute reader.
         | 
| 11 | 
            +
                # def initialize
         | 
| 12 | 
            +
                #   roll
         | 
| 13 | 
            +
                # end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def roll
         | 
| 16 | 
            +
                  @number = rand(1..6)
         | 
| 17 | 
            +
                  audit
         | 
| 18 | 
            +
                  @number
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
              end
         | 
| 21 | 
            +
            end
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            if __FILE__ == $PROGRAM_NAME
         | 
| 24 | 
            +
              die = StudioGame::Die.new
         | 
| 25 | 
            +
              die.roll
         | 
| 26 | 
            +
            end
         | 
| @@ -0,0 +1,133 @@ | |
| 1 | 
            +
            # require 'csv'
         | 
| 2 | 
            +
            require_relative 'player'
         | 
| 3 | 
            +
            require_relative 'game_turn'
         | 
| 4 | 
            +
            require_relative 'treasure_trove'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module StudioGame
         | 
| 7 | 
            +
              class Game
         | 
| 8 | 
            +
                attr_reader :title
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                def initialize(title)
         | 
| 11 | 
            +
                  @title = title
         | 
| 12 | 
            +
                  @players = []
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                def add_player(player)
         | 
| 16 | 
            +
                  @players << player
         | 
| 17 | 
            +
                  # Or with push
         | 
| 18 | 
            +
                  # @players.push(player)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def load_players(from_file = "players.csv")
         | 
| 22 | 
            +
                  # CSV.foreach(from_file) do |row|
         | 
| 23 | 
            +
                  #   name, health = row
         | 
| 24 | 
            +
                  #   add_player(Player.new(name, Integer(health)))
         | 
| 25 | 
            +
                  # end
         | 
| 26 | 
            +
                  File.readlines(from_file).each do |line|
         | 
| 27 | 
            +
                    # In the course we refactored the original implementation
         | 
| 28 | 
            +
                    # to be within the new class-level from_csv method on Player.
         | 
| 29 | 
            +
                    # The idea being that we are keeping code at the same general
         | 
| 30 | 
            +
                    # level of abstraction and the from_csv portion was lower
         | 
| 31 | 
            +
                    # than the reading of lines and adding them as players.
         | 
| 32 | 
            +
                    add_player(Player.from_csv(line))
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def save_high_scores(to_file = "high_scores.txt")
         | 
| 37 | 
            +
                  File.open(to_file, "w") do |file|
         | 
| 38 | 
            +
                    file.puts "#{@title} High Scores:"
         | 
| 39 | 
            +
                    @players.sort.each do |player|
         | 
| 40 | 
            +
                      file.puts high_score_entry(player)
         | 
| 41 | 
            +
                    end
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def high_score_entry(player)
         | 
| 46 | 
            +
                  formatted_name = player.name.ljust(20,'.')
         | 
| 47 | 
            +
                  "#{formatted_name} #{player.health}"
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
             | 
| 50 | 
            +
                # I'm trying to think about the data modeling and design they have going on here
         | 
| 51 | 
            +
                # How they're choosing to encapsulate data and the like. I feel I "design on the fly"
         | 
| 52 | 
            +
                # too often at what expense? It feels like that the expense of my models and the ability
         | 
| 53 | 
            +
                # to see what is really happening. I "just want to code" at the expense of the feature
         | 
| 54 | 
            +
                # even if I'm relatively satisfied with the end result, it does not feel like enough
         | 
| 55 | 
            +
                # care and forethought has been given...
         | 
| 56 | 
            +
                def total_points
         | 
| 57 | 
            +
                  # ClumsyPlayer can have Float value Treasure points. If we want to force the sum
         | 
| 58 | 
            +
                  # back to an Integer, try to_i...
         | 
| 59 | 
            +
                  @players.reduce(0) { |acc,n| acc + n.points }
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                def play(rounds)
         | 
| 63 | 
            +
                  current_formatted_time = Time.new.strftime('%A %m/%d/%Y at %H:%M')
         | 
| 64 | 
            +
                  puts "The game started on #{current_formatted_time}"
         | 
| 65 | 
            +
                  puts "There are #{@players.size} players in #{@title}:"
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  @players.each do |player|
         | 
| 68 | 
            +
                    puts player
         | 
| 69 | 
            +
                  end
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  treasures = TreasureTrove::TREASURES
         | 
| 72 | 
            +
                  puts "\nThere are #{treasures.size} treasures to be found:"
         | 
| 73 | 
            +
                  treasures.each do |treasure|
         | 
| 74 | 
            +
                    puts "A #{treasure.name} is worth #{treasure.points} points"
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  1.upto(rounds) do |round|
         | 
| 78 | 
            +
                    if block_given?
         | 
| 79 | 
            +
                      break if yield
         | 
| 80 | 
            +
                    end
         | 
| 81 | 
            +
                    # OR
         | 
| 82 | 
            +
                    # break if block_given? and yield
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                    puts "\nRound: #{round}:"
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                    @players.each do |player|
         | 
| 87 | 
            +
                      GameTurn.take_turn(player)
         | 
| 88 | 
            +
                      puts player
         | 
| 89 | 
            +
                    end
         | 
| 90 | 
            +
                  end
         | 
| 91 | 
            +
                end
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                def print_name_and_health(player)
         | 
| 94 | 
            +
                  puts "#{player.name} (#{player.health})"
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                def print_stats
         | 
| 98 | 
            +
                  puts "\n#{@title} Statistics"
         | 
| 99 | 
            +
             | 
| 100 | 
            +
                  strong_players, wimpy_players = @players.partition { |player| player.strong? }
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  puts "\n#{strong_players.length} strong players:"
         | 
| 103 | 
            +
                  strong_players.each do |player|
         | 
| 104 | 
            +
                    print_name_and_health(player)
         | 
| 105 | 
            +
                  end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  puts "\n#{wimpy_players.length} wimpy players:"
         | 
| 108 | 
            +
                  wimpy_players.each do |player|
         | 
| 109 | 
            +
                    print_name_and_health(player)
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  puts "\n#{@title} High Scores:"
         | 
| 113 | 
            +
                  @players.sort.each do |player|
         | 
| 114 | 
            +
                    puts high_score_entry(player)
         | 
| 115 | 
            +
                  end
         | 
| 116 | 
            +
             | 
| 117 | 
            +
                  @players.each do |player|
         | 
| 118 | 
            +
                    puts "\n#{player.name}'s total points:"
         | 
| 119 | 
            +
                    player.each_found_treasure do |treasure|
         | 
| 120 | 
            +
                      puts "#{treasure.points} total #{treasure.name} points"
         | 
| 121 | 
            +
                    end
         | 
| 122 | 
            +
                    puts "#{player.points} grand total points"
         | 
| 123 | 
            +
                  end
         | 
| 124 | 
            +
             | 
| 125 | 
            +
                  puts "\n#{total_points} total points from treasures found"
         | 
| 126 | 
            +
                end
         | 
| 127 | 
            +
              end
         | 
| 128 | 
            +
            end
         | 
| 129 | 
            +
             | 
| 130 | 
            +
            if __FILE__ == $PROGRAM_NAME
         | 
| 131 | 
            +
              game = StudioGame::Game.new('Bingo')
         | 
| 132 | 
            +
              game.load_players
         | 
| 133 | 
            +
            end
         | 
| @@ -0,0 +1,24 @@ | |
| 1 | 
            +
            require_relative 'player'
         | 
| 2 | 
            +
            require_relative 'die'
         | 
| 3 | 
            +
            # require_relative 'loaded_die'
         | 
| 4 | 
            +
            require_relative 'treasure_trove'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module StudioGame
         | 
| 7 | 
            +
              module GameTurn
         | 
| 8 | 
            +
                def self.take_turn(player)
         | 
| 9 | 
            +
                  die = Die.new
         | 
| 10 | 
            +
                  # die = LoadedDie.new
         | 
| 11 | 
            +
                  case die.roll
         | 
| 12 | 
            +
                  when 1..2
         | 
| 13 | 
            +
                    player.blam
         | 
| 14 | 
            +
                  when 3..4
         | 
| 15 | 
            +
                    puts "#{player.name} was skipped."
         | 
| 16 | 
            +
                  else
         | 
| 17 | 
            +
                    player.w00t
         | 
| 18 | 
            +
                  end
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  treasure = TreasureTrove.random
         | 
| 21 | 
            +
                  player.found_treasure(treasure)
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            module StudioGame
         | 
| 2 | 
            +
              module Playable
         | 
| 3 | 
            +
                def strong?
         | 
| 4 | 
            +
                  health > 100
         | 
| 5 | 
            +
                end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
                def blam
         | 
| 8 | 
            +
                  self.health -= 10
         | 
| 9 | 
            +
                  puts "#{name} got blammed!"
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def w00t
         | 
| 13 | 
            +
                  self.health += 15
         | 
| 14 | 
            +
                  puts "#{name} got w00ted!"
         | 
| 15 | 
            +
                end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                # TODO: Move the comparison operator into here too since it's health related?
         | 
| 18 | 
            +
                #  Is that a "playable" trait?
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,70 @@ | |
| 1 | 
            +
            require_relative 'playable'
         | 
| 2 | 
            +
            require_relative 'treasure_trove'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module StudioGame
         | 
| 5 | 
            +
              class Player
         | 
| 6 | 
            +
                include Playable
         | 
| 7 | 
            +
                attr_accessor :health
         | 
| 8 | 
            +
                attr_reader :name
         | 
| 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 self.from_csv(string)
         | 
| 17 | 
            +
                  name, health = string.split(',')
         | 
| 18 | 
            +
                  Player.new(name, Integer(health))
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def name=(new_name)
         | 
| 22 | 
            +
                  @name = new_name.capitalize
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def score
         | 
| 26 | 
            +
                  @health + points
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def points
         | 
| 30 | 
            +
                  @found_treasures.values.reduce(0, :+)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                def each_found_treasure
         | 
| 34 | 
            +
                  @found_treasures.each do |name, points|
         | 
| 35 | 
            +
                    yield Treasure.new(name, points)
         | 
| 36 | 
            +
                  end
         | 
| 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 to_s
         | 
| 46 | 
            +
                  "I'm #{@name} with health = #{@health}, points = #{points}, and score = #{score}."
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def time
         | 
| 50 | 
            +
                  current_time = Time.new
         | 
| 51 | 
            +
                  current_time.strftime('%H:%M:%S')
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def <=>(other)
         | 
| 55 | 
            +
                  # TODO: Why don't I need the at-sign here to reference the health of this player?
         | 
| 56 | 
            +
                  # other.health <=> @health
         | 
| 57 | 
            +
                  other.health <=> health
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
              end
         | 
| 60 | 
            +
            end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
            if __FILE__ == $PROGRAM_NAME
         | 
| 63 | 
            +
              player = StudioGame::Player.new('moe')
         | 
| 64 | 
            +
              puts player.name
         | 
| 65 | 
            +
              puts player.health
         | 
| 66 | 
            +
              player.w00t
         | 
| 67 | 
            +
              puts player.health
         | 
| 68 | 
            +
              player.blam
         | 
| 69 | 
            +
              puts player.health
         | 
| 70 | 
            +
            end
         | 
| @@ -0,0 +1,34 @@ | |
| 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
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            if __FILE__ == $PROGRAM_NAME
         | 
| 21 | 
            +
              # I want to see how numeric types are converted
         | 
| 22 | 
            +
              # Please see the found_treasure method in ClumsyPlayer
         | 
| 23 | 
            +
              treasure_one = StudioGame::Treasure.new('one', 1)
         | 
| 24 | 
            +
              treasure_two = StudioGame::Treasure.new('two', 2.0)
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              puts treasure_one.points.class
         | 
| 27 | 
            +
              puts treasure_two.points.class
         | 
| 28 | 
            +
             | 
| 29 | 
            +
              treasure_one = StudioGame::Treasure.new('one', 1/1)
         | 
| 30 | 
            +
              treasure_two = StudioGame::Treasure.new('two', 2/1.0)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
              puts treasure_one.points.class
         | 
| 33 | 
            +
              puts treasure_two.points.class
         | 
| 34 | 
            +
            end
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            require 'studio_game/berserk_player'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module StudioGame
         | 
| 4 | 
            +
              describe BerserkPlayer do
         | 
| 5 | 
            +
                before do
         | 
| 6 | 
            +
                  # Hide console output
         | 
| 7 | 
            +
                  $stdout = StringIO.new
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  @initial_health = 100
         | 
| 10 | 
            +
                  @player = BerserkPlayer.new("berserker", @initial_health)
         | 
| 11 | 
            +
                end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                it "goes berserk after six w00ts" do
         | 
| 14 | 
            +
                  5.times { @player.w00t }
         | 
| 15 | 
            +
                  @player.blam
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  current_health = @initial_health + (5 * 15) - 10
         | 
| 18 | 
            +
                  expect(@player.health).to eq(current_health)
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  @player.w00t
         | 
| 21 | 
            +
                  @player.blam
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  expect(@player.health).to eq(current_health + (2 * 15))
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                it "does not go berserk when w00ted up to 5 times" do
         | 
| 27 | 
            +
                  1.upto(5) { @player.w00t }
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  expect(@player.berserk?).to be_falsey
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                it "goes berserk when w00ted more than 5 times" do
         | 
| 33 | 
            +
                  1.upto(6) { @player.w00t }
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  expect(@player.berserk?).to be_truthy
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                it "gets w00ted instead of blammed when it's gone berserk" do
         | 
| 39 | 
            +
                  1.upto(6) { @player.w00t }
         | 
| 40 | 
            +
                  1.upto(2) { @player.blam }
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                  expect(@player.health).to eq(@initial_health + (8 * 15))
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
              end
         | 
| 45 | 
            +
            end
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            require 'studio_game/clumsy_player'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module StudioGame
         | 
| 4 | 
            +
              describe ClumsyPlayer do
         | 
| 5 | 
            +
                before do
         | 
| 6 | 
            +
                  # Hide console output
         | 
| 7 | 
            +
                  $stdout = StringIO.new
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  @player = ClumsyPlayer.new("klutz")
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                it "only gets half the point value for each treasure" do
         | 
| 13 | 
            +
                  expect(@player.points).to eq(0)
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  hammer = Treasure.new(:hammer, 50)
         | 
| 16 | 
            +
                  @player.found_treasure(hammer)
         | 
| 17 | 
            +
                  @player.found_treasure(hammer)
         | 
| 18 | 
            +
                  @player.found_treasure(hammer)
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                  expect(@player.points).to eq(75)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  crowbar = Treasure.new(:crowbar, 400)
         | 
| 23 | 
            +
                  @player.found_treasure(crowbar)
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                  expect(@player.points).to eq(275)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  yielded = []
         | 
| 28 | 
            +
                  @player.each_found_treasure do |treasure|
         | 
| 29 | 
            +
                    yielded << treasure
         | 
| 30 | 
            +
                  end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  expect(yielded).to eq([Treasure.new(:hammer, 75), Treasure.new(:crowbar, 200)])
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                context "with a boost factor" do
         | 
| 36 | 
            +
                  before do
         | 
| 37 | 
            +
                    # Hide console output
         | 
| 38 | 
            +
                    $stdout = StringIO.new
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                    @boost_factor = 3
         | 
| 41 | 
            +
                    @initial_health = 100
         | 
| 42 | 
            +
                    @player = ClumsyPlayer.new("klutz", @initial_health, @boost_factor)
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                  it "has a boost factor" do
         | 
| 46 | 
            +
                    expect(@player.boost_factor).to eq(@boost_factor)
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  it "gets boost factor number of w00ts when w00ted" do
         | 
| 50 | 
            +
                    @player.w00t
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                    expect(@player.health).to eq(@initial_health + (15 * @boost_factor))
         | 
| 53 | 
            +
                  end
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
            end
         | 
| @@ -0,0 +1,90 @@ | |
| 1 | 
            +
            require 'studio_game/game'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module StudioGame
         | 
| 4 | 
            +
              describe Game do
         | 
| 5 | 
            +
                before do
         | 
| 6 | 
            +
                  $stdout = StringIO.new
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                  @game = Game.new('Knuckleheads')
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                  @initial_health = 100
         | 
| 11 | 
            +
                  @player = Player.new('moe', @initial_health)
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                  @game.add_player(@player)
         | 
| 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 | 
            +
             | 
| 19 | 
            +
                  @game.play(2)
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                  expect(@player.health).to eq(@initial_health + (15 * 2))
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                it 'skips the player if a medium number is rolled' do
         | 
| 25 | 
            +
                  allow_any_instance_of(Die).to receive(:roll).and_return(3)
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  @game.play(2)
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                  expect(@player.health).to eq(@initial_health)
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                it 'blams the player if a low number is rolled' do
         | 
| 33 | 
            +
                  allow_any_instance_of(Die).to receive(:roll).and_return(1)
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  @game.play(2)
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                  expect(@player.health).to eq(@initial_health - (10 * 2))
         | 
| 38 | 
            +
                end
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                it 'plays a number of rounds' do
         | 
| 41 | 
            +
                  # FIXME: It appears I added this as my own "extra credit". What should I do? Should I leave it?
         | 
| 42 | 
            +
                  # 👇 This does not work
         | 
| 43 | 
            +
                  allow_any_instance_of(Die).to receive(:roll).and_return(1, 3, 5)
         | 
| 44 | 
            +
                  # allow_any_instance_of(Die).to receive(:roll).and_return(1)
         | 
| 45 | 
            +
                  # allow_any_instance_of(Die).to receive(:roll).and_return(3)
         | 
| 46 | 
            +
                  # allow_any_instance_of(Die).to receive(:roll).and_return(5)
         | 
| 47 | 
            +
             | 
| 48 | 
            +
                  # The reason is around the allow_any_instance_of works on a call
         | 
| 49 | 
            +
                  # and not an instance, so effectively it seems to only be able to utilize the first
         | 
| 50 | 
            +
                  # value in the and_return. Is there a way to spy upon the GameTurn module to find and
         | 
| 51 | 
            +
                  # wrap, or something like it, its use of the Die class?
         | 
| 52 | 
            +
                  #
         | 
| 53 | 
            +
                  # https://rspec.info/documentation/3.10/rspec-mocks/#settings-mocks-or-stubs-on-any-instance-of-a-class
         | 
| 54 | 
            +
                  # https://rubydoc.info/gems/rspec-mocks/3.10.2/RSpec/Mocks/MessageExpectation#and_return-instance_method
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                  @game.play(3)
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  # 👇 should be the result
         | 
| 59 | 
            +
                  # expect(@player.health).to eq(@initial_health + 5)
         | 
| 60 | 
            +
                  expect(@player.health).to eq(@initial_health - (3 * 10))
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                it "assigns a treasure for points during a player's turn" do
         | 
| 64 | 
            +
                  game = Game.new("Knuckleheads")
         | 
| 65 | 
            +
                  player = Player.new("moe")
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                  game.add_player(player)
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                  game.play(1)
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                  expect(player.points).not_to be_zero
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                it "computes total points as the sum of all player points" do
         | 
| 75 | 
            +
                  game = Game.new("Knuckleheads")
         | 
| 76 | 
            +
             | 
| 77 | 
            +
                  player1 = Player.new("moe")
         | 
| 78 | 
            +
                  player2 = Player.new("larry")
         | 
| 79 | 
            +
             | 
| 80 | 
            +
                  game.add_player(player1)
         | 
| 81 | 
            +
                  game.add_player(player2)
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                  player1.found_treasure(Treasure.new(:hammer, 50))
         | 
| 84 | 
            +
                  player1.found_treasure(Treasure.new(:hammer, 50))
         | 
| 85 | 
            +
                  player2.found_treasure(Treasure.new(:crowbar, 400))
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  expect(game.total_points).to eq(500)
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
              end
         | 
| 90 | 
            +
            end
         | 
| @@ -0,0 +1,119 @@ | |
| 1 | 
            +
            require 'studio_game/player'
         | 
| 2 | 
            +
            require 'studio_game/treasure_trove'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module StudioGame
         | 
| 5 | 
            +
              describe Player do
         | 
| 6 | 
            +
                before do
         | 
| 7 | 
            +
                  $stdout = StringIO.new
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  @name = 'larry'
         | 
| 10 | 
            +
                  @initial_health = 150
         | 
| 11 | 
            +
                  @player = Player.new(@name, @initial_health)
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                it 'creates a Player from a CSV string' do
         | 
| 15 | 
            +
                  player = Player.from_csv('Megan,150')
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  expect(player.name).to eq('Megan')
         | 
| 18 | 
            +
                  expect(player.health).to eq(150)
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                it 'has a capitalized name' do
         | 
| 22 | 
            +
                  expect(@player.name).to eq(@name.capitalize)
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                it 'has an initial health' do
         | 
| 26 | 
            +
                  expect(@player.health).to eq(@initial_health)
         | 
| 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 | 
            +
                  expect(@player.to_s).to eq("I'm Larry with health = 150, points = 100, and score = 250.")
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                it "computes a score as the sum of its health and points" do
         | 
| 37 | 
            +
                  @player.found_treasure(Treasure.new(:hammer, 50))
         | 
| 38 | 
            +
                  @player.found_treasure(Treasure.new(:hammer, 50))
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                  expect(@player.score).to eq(250)
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                it 'increases health by 15 when w00ted' do
         | 
| 44 | 
            +
                  @player.w00t
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  expect(@player.health).to eq(@initial_health + 15)
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                it 'decreases health by 10 when blammed' do
         | 
| 50 | 
            +
                  @player.blam
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  expect(@player.health).to eq(@initial_health - 10)
         | 
| 53 | 
            +
                end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
                context 'with a health greater than 100' do
         | 
| 56 | 
            +
                  it 'is strong' do
         | 
| 57 | 
            +
                    player = Player.new('Someone', 150)
         | 
| 58 | 
            +
                    expect(player).to be_strong
         | 
| 59 | 
            +
                  end
         | 
| 60 | 
            +
                end
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                context 'with a health of 100 or less' do
         | 
| 63 | 
            +
                  it 'is whimpy' do
         | 
| 64 | 
            +
                    player = Player.new('Someone', 100)
         | 
| 65 | 
            +
                    expect(player).not_to be_strong
         | 
| 66 | 
            +
                  end
         | 
| 67 | 
            +
                end
         | 
| 68 | 
            +
             | 
| 69 | 
            +
                context "in a collection of players" do
         | 
| 70 | 
            +
                  before do
         | 
| 71 | 
            +
                    @player1 = Player.new("moe", 100)
         | 
| 72 | 
            +
                    @player2 = Player.new("larry", 200)
         | 
| 73 | 
            +
                    @player3 = Player.new("curly", 300)
         | 
| 74 | 
            +
             | 
| 75 | 
            +
                    @players = [@player1, @player2, @player3]
         | 
| 76 | 
            +
                  end
         | 
| 77 | 
            +
             | 
| 78 | 
            +
                  it "is sorted by decreasing score" do
         | 
| 79 | 
            +
                    # @players.sort.should == [@player3, @player2, @player1]
         | 
| 80 | 
            +
                    expect(@players.sort).to eq([@player3, @player2, @player1])
         | 
| 81 | 
            +
                  end
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
             | 
| 84 | 
            +
                it "computes points as the sum of all treasure points" do
         | 
| 85 | 
            +
                  expect(@player.points).to eq(0)
         | 
| 86 | 
            +
             | 
| 87 | 
            +
                  @player.found_treasure(Treasure.new(:hammer, 50))
         | 
| 88 | 
            +
                  expect(@player.points).to eq(50)
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                  @player.found_treasure(Treasure.new(:crowbar, 400))
         | 
| 91 | 
            +
                  expect(@player.points).to eq(450)
         | 
| 92 | 
            +
             | 
| 93 | 
            +
                  @player.found_treasure(Treasure.new(:hammer, 50))
         | 
| 94 | 
            +
                  expect(@player.points).to eq(500)
         | 
| 95 | 
            +
                end
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                it "yields each found treasure and its total points" do
         | 
| 98 | 
            +
                  @player.found_treasure(Treasure.new(:skillet, 100))
         | 
| 99 | 
            +
                  @player.found_treasure(Treasure.new(:skillet, 100))
         | 
| 100 | 
            +
                  @player.found_treasure(Treasure.new(:hammer, 50))
         | 
| 101 | 
            +
                  @player.found_treasure(Treasure.new(:bottle, 5))
         | 
| 102 | 
            +
                  @player.found_treasure(Treasure.new(:bottle, 5))
         | 
| 103 | 
            +
                  @player.found_treasure(Treasure.new(:bottle, 5))
         | 
| 104 | 
            +
                  @player.found_treasure(Treasure.new(:bottle, 5))
         | 
| 105 | 
            +
                  @player.found_treasure(Treasure.new(:bottle, 5))
         | 
| 106 | 
            +
             | 
| 107 | 
            +
                  yielded = []
         | 
| 108 | 
            +
                  @player.each_found_treasure do |treasure|
         | 
| 109 | 
            +
                    yielded << treasure
         | 
| 110 | 
            +
                  end
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  expect(yielded).to eq([
         | 
| 113 | 
            +
                                          Treasure.new(:skillet, 200),
         | 
| 114 | 
            +
                                          Treasure.new(:hammer, 50),
         | 
| 115 | 
            +
                                          Treasure.new(:bottle, 25)
         | 
| 116 | 
            +
                                        ])
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
              end
         | 
| 119 | 
            +
            end
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            require 'studio_game/treasure_trove'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module StudioGame
         | 
| 4 | 
            +
              describe Treasure do
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                before do
         | 
| 7 | 
            +
                  @treasure = Treasure.new(:hammer, 50)
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                it "has a name attribute" do
         | 
| 11 | 
            +
                  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 | 
            +
             | 
| 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 hammer worth 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,89 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: studio_game_michaelwestphal
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 1.0.0
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Michael Westphal
         | 
| 8 | 
            +
            autorequire:
         | 
| 9 | 
            +
            bindir: bin
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2022-12-30 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.10'
         | 
| 20 | 
            +
                - - ">="
         | 
| 21 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 22 | 
            +
                    version: 3.10.0
         | 
| 23 | 
            +
              type: :development
         | 
| 24 | 
            +
              prerelease: false
         | 
| 25 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 26 | 
            +
                requirements:
         | 
| 27 | 
            +
                - - "~>"
         | 
| 28 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 29 | 
            +
                    version: '3.10'
         | 
| 30 | 
            +
                - - ">="
         | 
| 31 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 32 | 
            +
                    version: 3.10.0
         | 
| 33 | 
            +
            description: "# Studio Game\n\nThe Studio Game developed while taking the [Ruby Programming
         | 
| 34 | 
            +
              course](https://pragmaticstudio.com/courses/ruby) from the [Pragmatic Studio](https://pragmaticstudio.com/).\n\n\U0001F4DA
         | 
| 35 | 
            +
              **[My Pragmatic Studio alumni page](https://pragmaticstudio.com/alumni/michaelwestphal)**\n"
         | 
| 36 | 
            +
            email: michaelwestphal@hey.com
         | 
| 37 | 
            +
            executables:
         | 
| 38 | 
            +
            - studio_game
         | 
| 39 | 
            +
            extensions: []
         | 
| 40 | 
            +
            extra_rdoc_files: []
         | 
| 41 | 
            +
            files:
         | 
| 42 | 
            +
            - LICENSE
         | 
| 43 | 
            +
            - README
         | 
| 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/michaelwestphal/ruby-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: '3.0'
         | 
| 74 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 75 | 
            +
              requirements:
         | 
| 76 | 
            +
              - - ">="
         | 
| 77 | 
            +
                - !ruby/object:Gem::Version
         | 
| 78 | 
            +
                  version: '0'
         | 
| 79 | 
            +
            requirements: []
         | 
| 80 | 
            +
            rubygems_version: 3.3.7
         | 
| 81 | 
            +
            signing_key:
         | 
| 82 | 
            +
            specification_version: 4
         | 
| 83 | 
            +
            summary: Studio Game from Pragmatic Studio Ruby course
         | 
| 84 | 
            +
            test_files:
         | 
| 85 | 
            +
            - spec/studio_game/berserk_player_spec.rb
         | 
| 86 | 
            +
            - spec/studio_game/clumsy_player_spec.rb
         | 
| 87 | 
            +
            - spec/studio_game/game_spec.rb
         | 
| 88 | 
            +
            - spec/studio_game/player_spec.rb
         | 
| 89 | 
            +
            - spec/studio_game/treasure_trove_spec.rb
         |