Reputation: 13
I'm doing a game creation exercise from Learn Ruby the Hard Way. It's themed after Destiny since that's what I've got on the brain at the moment.
I wanted to have the player pick a character class, and then have that choice hand off some numbers as stats to be checked later in play. Below is the version that actually worked, but it involves creating a several global variables, which I keep reading is not a "best practice" in Ruby.
My question is, is there a way to do what I've got the code below doing without creating all of these global variables, or am I doing what needs to be done?
$might = 1
$agility = 1
$intellect = 1
def start
puts "Make all decisions by pressing the corresponding number."
puts "Choose your class:"
puts "1. Titan"
puts "2. Hunter"
puts "3. Warlock"
print "> "
choice = $stdin.gets.chomp
if choice == "1"
$might = 3
puts "You've chosen Titan!"
elsif choice == "2"
$agility = 3
puts "You've chosen Hunter!"
elsif choice == "3"
$intellect = 3
puts "You've chosen Warlock!"
else
puts "Try again."
start
end
end
puts start
puts "Might: #{$might}"
puts "Agility: #{$agility}"
puts "Intellect: #{$intellect}"
Upvotes: 1
Views: 55
Reputation: 121000
One option could be returning whatever you want from a method:
def start
puts "Make all decisions by pressing the corresponding number."
puts "Choose your class:"
puts "1. Titan"
puts "2. Hunter"
puts "3. Warlock"
print "> "
choice = $stdin.gets.chomp
case choice
when '1'
puts "You've chosen Titan!"
{agility: 1, might: 3, intellect: 1}
when '2'
puts "You've chosen Hunter!"
{agility: 3, might: 1, intellect: 1}
when '3'
puts "You've chosen Warlock!"
{agility: 1, might: 1, intellect: 3}
else
puts "Try again."
start
end
end
hero = start
puts "Might: #{hero[:might]}"
puts "Agility: #{hero[:agility]}"
puts "Intellect: #{hero[:intellect]}"
Upvotes: 0
Reputation: 2869
Maybe something like this. I prepare it for updates.
class Character
attr_accessor :might, :agility, :intelect, :type
def initialize(type, might = 1, agility = 1, intelect = 1)
@type = type
@might, @agility, @intelect = might, agility, intelect
end
def print_attributes
puts "Type: #{@type}"
puts "Might: #{@might}"
puts "Agility: #{@agility}"
puts "Intelect: #{@intelect}"
end
end
class Player
attr_reader :character
def initialize(character)
@character = character
end
end
class Game
CHARACTER_CLASSES = [
{:type => "Titan", :might => 3, :agility => 1, :intelect => 1},
{:type => "Hunter", :might => 1, :agility => 3, :intelect => 1},
{:type => "Warlock", :might => 1, :agility => 1, :intelect => 3}
]
attr_reader :player
def initialize
@player = nil
end
def start
puts "Make all decisions by pressing the corresponding number."
repeat = true
while repeat
puts "Choose your class:"
CHARACTER_CLASSES.each_with_index do |char_config, i|
puts "#{i+1}. #{char_config[:type]}"
end
choice = gets.chomp
choice_i = choice.to_i
unless choice_i == 0
if char_data = CHARACTER_CLASSES[choice_i - 1]
@player = Player.new( Character.new(char_data[:type], char_data[:might], char_data[:agility], char_data[:intelect]) )
repeat = false
end
end
end
end
end
game = Game.new
game.start
game.player.character.print_attributes
Upvotes: 1
Reputation: 27855
You can create a class and use instance variables:
class Game
def initialize
@might = 1
@agility = 1
@intellect = 1
end
attr_reader :might
attr_reader :agility
attr_reader :intellect
def start
puts "Make all decisions by pressing the corresponding number."
puts "Choose your class:"
puts "1. Titan"
puts "2. Hunter"
puts "3. Warlock"
print "> "
choice = $stdin.gets.chomp
case choice
when "1"
@might = 3
puts "You've chosen Titan!"
when "2"
@agility = 3
puts "You've chosen Hunter!"
when "3"
@intellect = 3
puts "You've chosen Warlock!"
else
puts "Try again."
start
end
end
end
game = Game.new
game.start
puts "Might: #{game.might}"
puts "Agility: #{game.agility}"
puts "Intellect: #{game.intellect}"
Remark:
attr_reader
defined the attribute accessor for the instance variables.Upvotes: 1