Reputation: 186
If I simulate the rolling of a six-sided die as follows, it always evaluates to 6. How do I fix this?
def rolldice()
roll = rand()
case roll
when 0..(1/6) then return 1
when (1/6)..(2/6) then return 2
when (2/6)..(3/6) then return 3
when (3/6)..(4/6) then return 4
when (4/6)..(5/6) then return 5
else return 6
end
end
die1 = rolldice()
puts die1
Upvotes: 1
Views: 77
Reputation: 11188
When you divide two integers then the result will be an integer so your code is actually doing this:
when 0..0 then return 1
when 0..0 then return 2
when 0..0 then return 3
when 0..0 then return 4
when 0..0 then return 5
else return 6
Try this simple example in IRB:
1 / 6
=> 0
Upvotes: 1
Reputation: 332
Case statement is not the best option to you. It may fit best for texts or fix values. Assuming that you're doing an RPG application, the Switch may be more useful to choose what to do with weapons/armors.
Case is a more elegant way to write a lot of if elses, but behave almost the same way. Before writing the Case you should test the conditions using irb (or rails console if you prefer). This make things easier.
Case also do a lot of comparisons, in this particular case they are not necessary, using the rand() directly will perform better and the code will be simpler. Note that rand(6) will return from 0 to 5, just sum 1 to get the d6.
def rolldice
return rand(6)+1
end
Upvotes: 0
Reputation: 3225
Stefan is right but the answer doesn't clearly explain your problem.
The problem is that rand()
gives you a Float (which can have numbers after the decimal point).
But in the case
statement you are using ranges such as 0..(1/6)
.
The problem there is that the numbers in (1/6)
are both integers, so the answer is an integer. That's why (1/6)
is 0
, it's rounded.
You could also solve the problem by using when
ranges such as:
when (3.0/6)..(4.0/6) then return 4
Looking at (3.0/6)
we have a Float divided by an Integer, the result is a Float, in this case 0.5
.
But in the end it's probably best to follow Stefan's suggestion. Instead of using rand
for a Float from 0
to 1
, we can use a range. Some options:
rand(1..6) # Returns an Integer from 1 to 6
rand(6) # Returns an Integer from 0 to 5
If you use the first case, then you can rewrite the when as just when 5
... or so on. In this case, because all you want is to return the number, you don't even need the case
statement, hence Stefan's shorter answer of just calling rand
directly and using that value.
Upvotes: 1