I’m new to the programming world, so much of this stuff is still pretty
foreign to me.
I’ve created a ‘roll_dice.rb’ program that draws on the ‘die.rb’ model.
When the roll_dice program is run, the user is simply prompted to type
‘roll’ to roll the dice and get a result. Typing ‘quit’ exits the
program.
I’d like to expand the functionality of this program such that when the
program is run, the user is first prompted to enter in how many dice
they would like to roll. After answering, the user would then type
‘roll’ and receive back the same number of answers as number of dice.
i.e. :
How many dice would you like to roll?
2
Type ‘roll’ to roll your dice.
roll
3
2
Type ‘roll’ to roll your dice.
roll
6
4
The thing is, I’m not sure how to add that kind of functionality to my
program yet. Thoughts and suggestions are appreciated. Thanks!
Here is my current code (I’ve also included it as an attachment):
die.rb
Class Die
def rolled_dice
1 + rand(6)
end
end
roll_dice.rb
require_relative ‘die’
@die = Die.new
while true
puts “Type ‘roll’ to roll the dice.”
answer = gets.chomp
if answer == ‘roll’
puts @die.rolled_dice
elsif answer == ‘quit’
break
else
puts “Please type ‘roll’ or ‘quit’.”
end
end
Thanks Robert and Joel for your suggestions. It forced me to browse some
Ruby functionality online. In the end, I went with Robert’s suggestion.
Here is the code as it stands now:
The individual Die:
class Die
def roll_dice
1 + rand(6)
end
end
The program:
require_relative ‘die’
@die = Die.new
Ask user how many dice to roll
puts “How many dice would you like to roll?”
Store that value into a variable as an integer
number_of_dice = gets.chomp.to_i
Run a loop that allows to user to roll until they type quit
while true
puts “Please type ‘roll’ to roll the dice or ‘quit’ to quit.”
response = gets.chomp
if response == ‘roll’
rolling_dice = number_of_dice
puts
# Utilize number_of_dice variable to simulate multiple dice being
rolled
while rolling_dice > 0
puts @die.roll_dice
rolling_dice -= 1
end
puts
elsif response == ‘quit’
break
else
puts “Please type ‘roll’ or ‘quit’.”
end
end
I’ve heard a little bit about the MVC structure. I recognize that the
command line output is my view, and for right now I’m not interested in
customizing that. However, I am curious to know if I’m following proper
form in terms of what code is in my controller (roll_dice.rb) and my
model (die.rb). Thoughts/comments/suggestions are always appreciated.
You could use an Array of Dice, based on the number given by the user:
puts ‘Enter the number of dice to use’
number = Integer( gets ) @dice = Array.new( number, Dice.new )
ask about rolling, etc…
puts @dice.map { |die| die.rolled_dice }
The way Dice is implemented it does not make sense to have more than
one of them.
Kind regards
robert
Fair point, I was thinking that if added complexity was required later -
e.g. dice maintaining their state - then an Array would be more
suitable.
As it stands there isn’t even a point in having a Die class, a single
method could do the job
The way Dice is implemented it does not make sense to have more than
one of them.
Fair point, I was thinking that if added complexity was required later -
e.g. dice maintaining their state - then an Array would be more
suitable.
As it stands there isn’t even a point in having a Die class, a single
method could do the job
Absolutely. One could even wonder whether this problem warrants a
method of its own.
There are two more remarks I forgot in my previous post:
instead of if…elsif a case construct would also fit nicely.
Endless loop can be done with loop and a block. Or we can place the
loop body in the where condition. Better still use a loop which test
the condition at the end
Ask user how many dice to roll
puts “How many dice would you like to roll?”
Store that value into a variable as an integer
number_of_dice = Integer(gets)
1 while puts “Please type ‘roll’ or ‘quit’.” or
case gets.chomp
when ‘roll’
number_of_dice.times { puts 1+rand(6) }
when ‘quit’
false
else
true
end
I admit, this is a bit weird way to do it. A more conservative
approach might be
begin
puts “Please type ‘roll’ or ‘quit’.”
go = case gets.chomp
when ‘roll’
number_of_dice.times { puts 1+rand(6) }
when ‘quit’
false
else
true
end
end while go
Disadvantage of #to_i vs. Integer() is that #to_i will happily convert
whatever it sees and you won’t notice errors - you end up wondering
why there is no output because the default value is 0. So better do
what Joel suggested (#chomp is not needed).
number_of_dice = Integer(gets)
while rolling_dice > 0
puts @die.roll_dice
rolling_dice -= 1
end
You can abbreviate the loop to
number_of_dice.times { puts @die.roo_dice }
command line output is my view, and for right now I’m not interested in
customizing that. However, I am curious to know if I’m following proper
form in terms of what code is in my controller (roll_dice.rb) and my
model (die.rb). Thoughts/comments/suggestions are always appreciated.
Generally for such a console application the term MVC is not used so
it feels a bit awkward here. But I think you got it about right.
Some things which are unusual:
Your model does not have state.
Your model does not notify anybody of state changes (well, since
there is no state, it cannot change :-))
There are no events because the structure of interactions is fixed
(opposed to graphical user interfaces where the user can click on this
button or enter text in an input field or close the window or…).
Kind regards
robert
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.