Roulette & rand

Hi,

I’m trying to teach my self ruby so i decided to write a simple roulette
that picks a rand number (0 to 36) then decides if its red or black. but
after i’ve written a version of the code i realized that the code was
biased towards black ( much easier to see over 1 million rolls)

Then to test this I’ve simplified everything and its still biased
against black. if i take 0 out of the equation and made use (1+rand(25))
the bias disappeared.

Anyway without further annoying you here is the code. If you spin it for
over a million you can easily see the bias (i tried up to 1000000000).

Thanks for any help. I know it’s not a life or death situation but for
the life of me I just want to know why is this happening.

THE CODE:

ARRAYS =======================

black = [2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31, 33,
35]
red = [1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34,
36]
zero = [0]

VARIABLES ===================

bl = 0
rd = 0
zr = 0

# OF ROLLS ==================

puts ‘How many rolls to simulate’
number_of_rolls = gets.chomp.to_i

THE LOOP ====================

while number_of_rolls > 0

number = rand(36)

if
black.include?(number)
bl +=1
elsif
red.include?(number)
rd +=1
elsif
zero.include?(number)
zr +=1
end
number_of_rolls -=1
end

puts bl
puts rd
puts zr

Evening Semih,

On Thu, Sep 24, 2009 at 10:59 PM, Semih Ozkoseoglu
[email protected]wrote:

I think you meant to say that the bias is against red and towards black
(as
you did in the first paragraph) because that’s both what I got when
trying
your code as well as what will make sense.

Rand doesn’t return an integer between 0 and x it returns an integer
between
0 and x -1 (http://www.ruby-doc.org/core/classes/Kernel.html#M005974).
So
you will find rather quickly that changing your code to rand(37) will
work
just fine for you and show no bias as well as the sum of all choices
will
equal your number of rolls.

When you ran using rand(36) the highest value you could ever had gotten
was
35 and therefore you had 18 black choices - 17 red choices and zero.
That
would give you more blacks then reds.

John

Hi Jon,

Thanks for the reply. You were completely right. I can’t believe I
missed such a thing. I changed 36 to 37 and now everything is as it
should be.

Cheers
Semih

Hi Stefano,

Thanks for taking the time to write such an helpfull reply. I get your
logic and I like its simpilicity. I will try to simplify my own code as
well.

Its always great to learn a few new things.

Thanks again
Semih

On Friday 25 September 2009, Semih Ozkoseoglu wrote:

|
|black = [2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31, 33,
|
| number = rand(36)
| end
| number_of_rolls -=1
|end
|
|puts bl
|puts rd
|puts zr

I think the problem comes from the fact that rand(n) returns an integer
between 0 and n-1. In your case, this means that the number 36 will
never be
generated, which in turn implies that there are more black numbers (18)
than
red (17 since 36 will never be generated). To avoid this, you’ll need to
replace rand(36) with rand(37), which generates numbers between 0 and
36. By
the way, you can greatly simplify your code, like this:

colors = {}

[2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31,33,35].each
do |i|
colors[i] = :black
end
[1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32,34,36].each
do |i|
colors[i] = :red
end
colors[0] = :zero

results = {:black => 0, :red => 0, :zero => 0}

puts ‘How many rolls to simulate’
number_of_rolls = gets.chomp.to_i

number_of_rolls.times do
number = rand(37)
color = colors[number]
results[color] += 1
end

puts “Black: #{results[:black]}”
puts “Red: #{results[:red]}”
puts “Zero: #{results[:zero]}”

What this code does is the following:

  • create a hash (called colors) which associates each number with its
    color,
    represented by a symbol. The hash is filled from arrays containing the
    black
    numbers and the red ones (it could also be filled by hand:
    colors[1] = :red
    colors[2] = :black
  • create the hash results which will contain the number of times each
    color is
    choosen. Therefore, the hash contains three entries, :black, :red and
    :zero,
    all set to 0
  • let the user choose the number of rolls
  • for the number of times chosen by the user, do the following
  • generate a random number between 0 and 36
  • get the color corresponding to the number. This is done by looking at
    the
    value corresponding to the number in the colors hash
  • increase by one the result relative to the chosen color
  • displays the result

I hope this helps

Stefano

On Fri, Sep 25, 2009 at 8:21 AM, Semih Ozkoseoglu
[email protected] wrote:

Hi again Stefano,

I was looking at the code and as I’m quite new to both programming and
Ruby, I can’t seem to understand two things. First is the |i| in

[2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31,33,35].each
do |i|

The |i| is a block parameter. The each method essentially calls the
code in the following block once for each element in the array, so
each in each iteration of the block i will be equal to the current
element of the array.

Try this in IRB

[1,2,3].each {|x| puts x}

and you’ll see what I mean.

and second is the ‘:’ in why not just ‘black’ for example.

colors[i] = :black

If you can find the time to tell me what do these do to make the code
work it would be much apriciated.

:black is a Symbol, not a String. I’m not sure exactly how much
difference it makes, but from what I’ve heard it’s a good habit to get
into. The trick is that the symbol :black is always the exact same
object, no matter where you see it in your program. On the other
hand, you can have 2 strings with the same contents which will be
different objects.

Try this in IRB

a = “black”
b = “black”
c = :black
d = :black

puts a.object_id
puts b.object_id
puts c.object_id
puts d.object_id

You’ll notice that a and b are different objects, but c and d are the
same object.

Thanks again
Semih

Posted via http://www.ruby-forum.com/.


Paul S.
http://www.nomadicfun.co.uk

[email protected]

On Friday 25 September 2009, Semih Ozkoseoglu wrote:

|Hi again Stefano,
|
|I was looking at the code and as I’m quite new to both programming and
|Ruby, I can’t seem to understand two things. First is the |i| in
|
|> [2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31,33,35].each
|> do |i|

I don’t know whether you’ve already read about blocks in ruby. Given
your
question, I don’t think so but, in case you did, you can skip the first
part
of my answer.

One of the most peculiar characteristics of ruby are blocks. As the name
says,
they are blocks of code which can be passed to methods and will be
called by
those methods at a later time. They can be introduced either with the
syntax

do

end

or with
{…}

The … are actually the body of the block, that is the code which will
be
executed later. For example, the code

5.times do
puts “Hello”
end

passes a block whose body is

puts “Hello”

to the “times” method of the object 5. The documentation for the times
method
says that n.times calls the block n times, that is it executes the
contents of
the block n times. In the example above, n is 5, so times will call
execute
the body of the block 5 times. The output is then:

Hello
Hello
Hello
Hello
Hello

Now, I can answer your question: what does
[2,4,6].each do |i|

end
mean? As you can see, there are a do and an end keyword, so this must be
a
block. The difference with the example above is the |i|. At the very
beginning
of the block, immediately after the do keyword or the opening brace, a
number
of comma-separated variables (just one, in this case) enclosed in a pair
of
pipe characters (|) are the arguments passed to the block. Passing
arguments
to a block works in a similar way as passing arguments to a method. In
the
code above, for example, the each method of class Array is called.
According
to the documentation, the each method calls the block for every element
of the
array, passing the element itself to the block. This means that, inside
the
body of the block, the variable i will contain one of the elements of
the
array in turn. For example:

[2,4,6].each do |i|
puts i
end

outputs:
2
4
6

“each” calls the block three times: the first the argument is 2, so the
variable i is set to 2; the second time i is set to 4 and the third time
i is
set to 6.

This is only a very short introduction to blocks. For more, you can look
at
http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_containers.html
(the
section called “Block and Iterators”)

|and second is the ‘:’ in why not just ‘black’ for example.

In ruby, a sequence of letters, number, underscores (and some other
characters) preceeded by a column (for example, :black) is a Symbol.
Symbols
are similar to strings. The main differences is that while every time I
write
a string literal, for example “hello”, I create a different string, with
symbols this doesn’t happen: if I write the symbol :hello one hundred
times, I
still get the same object every time. If I had written “hello” one
hundred
times, I’d have got one hundred strings all containing the word “hello”.
Expecially when beginning programming in ruby, it may be difficult to
understand when it’s better to use a symbol rather than a string (you
can find
a lot of material on this topic searching google for something like
“strings
and symbols”). Symbols are often used as hash keys when you know in
advance
which keys are allowed. For example, in your program you already know
that the
only possible outcomes of a roll are black, red or zero, so you can use
a
symbols as keys. A situation in which symbols wouldn’t be a good choice
is if
you’re storing information about people in the hash, using each person’s
name
as keys. Obviously, in this case you don’t know in advance which would
be the
keys of the array, so you should use strings instead.

If you know C or C++, symbols are somewhat similar to enums, except that
they
don’t have a numerical value associated with them.

|
|> colors[i] = :black
|
|If you can find the time to tell me what do these do to make the code
|work it would be much apriciated.

I hope this helps

|Thanks again
|Semih

Stefano

Hi again Stefano,

I was looking at the code and as I’m quite new to both programming and
Ruby, I can’t seem to understand two things. First is the |i| in

[2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31,33,35].each
do |i|

and second is the ‘:’ in why not just ‘black’ for example.

colors[i] = :black

If you can find the time to tell me what do these do to make the code
work it would be much apriciated.

Thanks again
Semih

Hi again,

I stumbled upon another interesting problem while I was playing with the
code that I mentioned above.

After the simple roulette code sorted (thanks to everyone who has
responded) I tried to write a code where the bet was decided by another
random roll. Suddenly the code started to loose twice it was loosing
before.

Now correct me if I’m wrong but shouldn’t I always loose around 1/37 of
the time; no matter how I decide to bet on what color?

I don’t know if there is something wrong with my code or with my logic
and I welcome any suggestions. Again I’m sure its not the most important
problem but I’m just curious why this might be happening.

Thanks for reading and here is the code that I put together so far (i
tried to compare only betting red to betting randomly)

colors = {}
[2, 4, 6, 8, 10, 11, 13, 15, 17, 20, 22, 24, 26, 28, 29, 31, 33,
35].each do |i|
colors[i] = :black
end
[1, 3, 5, 7, 9, 12, 14, 16, 18, 19, 21, 23, 25, 27, 30, 32, 34, 36].each
do |i|
colors[i] = :red
end
colors[0] = :zero

bet_rand = 0
bet_red = 0

puts ‘How many rolls to simulate’
number_of_rolls = gets.chomp.to_i

number_of_rolls.times do

number_01 = rand(37)
color_01 = colors[number_01]
number_02 = rand(37)
color_02 = colors[number_02]

if color_01 == :red
bet_red += 1
else
bet_red -= 1
end

if color_02 == color_01
bet_rand += 1
else
bet_rand -= 1
end
end

puts bet_rand
puts bet_red

Stefano, Paul,

I thank you both for being so helpful to a noob such as myself. I did
read about the Ruby community before but this is much more than I
expected.

The good thing is that I got it. Ruby is an amazing language, it makes
so much sense.

Again thank you both.

Semih

On Fri, Sep 25, 2009 at 1:26 PM, Semih Ozkoseoglu
[email protected] wrote:

Now correct me if I’m wrong but shouldn’t I always loose around 1/37 of
colors = {}
bet_rand = 0
color_02 = colors[number_02]
bet_rand -= 1
end
end

puts bet_rand
puts bet_red

Posted via http://www.ruby-forum.com/.

One problem that I can see is that you’re allowing your random betting
strategy to pick 0, rather than red or black, which I don’t think is
your intention.

Change

number_02 = rand(37)
color_02 = colors[number_02]

to

color_02 = [:red, :black][rand(2)]

maybe?


Paul S.
http://www.nomadicfun.co.uk

[email protected]

Symbols are a good habit to get into because they always represent a
unique object, the symbol, while strings always create a new object.
irb(main):009:0> 0.object_id
=> 1
irb(main):010:0> 0.object_id
=> 1
irb(main):011:0> “0”.object_id
=> 21396750
irb(main):012:0> “0”.object_id
=> 21393440

If we’re gonna talk about code simplification…

colors = { 0 => :green }
(1…36).each { |num| colors[num] = (num % 2 == 0) ? :black : :red }

But I’m also lazy, and this is actually slower than the way you guys
generate your hash…

Uh-oh … cough cough
I don’t really play those games, could you tell? :slight_smile:

Hi –

On Fri, 25 Sep 2009, Aldric G. wrote:

Symbols are a good habit to get into because they always represent a
unique object, the symbol, while strings always create a new object.

That’s true, but your example:

irb(main):009:0> 0.object_id
=> 1
irb(main):010:0> 0.object_id
=> 1
irb(main):011:0> “0”.object_id
=> 21396750
irb(main):012:0> “0”.object_id
=> 21393440

doesn’t demonstrate it; you don’t have any symbols :slight_smile:

irb(main):001:0> :x.object_id
=> 158738
irb(main):002:0> :x.object_id
=> 158738

David

David A. Black wrote:

Hi –

That’s true, but your example
doesn’t demonstrate it; you don’t have any symbols :slight_smile:

By the gods! Mea culpa. I am sorry - some days I should just look at the
keyboard and say ‘No’.

On Fri, Sep 25, 2009 at 3:09 PM, Aldric G. [email protected]
wrote:

If we’re gonna talk about code simplification…

colors = { 0 => :green }
(1…36).each { |num| colors[num] = (num % 2 == 0) ? :black : :red }

But I’m also lazy, and this is actually slower than the way you guys
generate your hash…

And also different, as the red and black numbers aren’t the odd and
even numbers.


Posted via http://www.ruby-forum.com/.


Paul S.
http://www.nomadicfun.co.uk

[email protected]

One problem that I can see is that you’re allowing your random betting
strategy to pick 0, rather than red or black, which I don’t think is
your intention.

Change

number_02 = rand(37)
color_02 = colors[number_02]

to

color_02 = [:red, :black][rand(2)]

maybe?

Hi Paul,

I’ll have a look at this issue sometime today and will write an update
if it changes anything.

Thank you.

And Josh,

Hi, it is giving me the output that I would expect, here is a image
showing
how I calculated it, and I ran the program 3 times with results very
similar
to what I calculated they should be.
http://img132.imageshack.us/img132/8939/roulette.png

I get the exact same results with you but what I dont understand is why
you think that the results are normal. I dont understand why it looses
twice as much when you bet randomly (if its not the problem Paul
mentioned above). It would be great if you can tell me how you
calculated what the results should be.

Thanks.
Semih

On Fri, Sep 25, 2009 at 7:26 AM, Semih Ozkoseoglu
[email protected]wrote:

Now correct me if I’m wrong but shouldn’t I always loose around 1/37 of
colors = {}
bet_rand = 0
color_02 = colors[number_02]
bet_rand -= 1
end
end

puts bet_rand
puts bet_red

Posted via http://www.ruby-forum.com/.

Hi, it is giving me the output that I would expect, here is a image
showing
how I calculated it, and I ran the program 3 times with results very
similar
to what I calculated they should be.
http://img132.imageshack.us/img132/8939/roulette.png

Hi Josh,

Thanks for taking the time. I might need to read a few more times before
I make sense of your whole solution but I think I understand your point.

Thanks again, its much appreciated.

Semih

On Fri, Sep 25, 2009 at 5:16 PM, Semih Ozkoseoglu
[email protected]wrote:

I get the exact same results with you but what I dont understand is why

Here is the formatted explanation:
http://img38.imageshack.us/img38/8939/roulette.png

And for completeness sake, here is a the unformatted explanation:

Okay, so you are adding 1 for every win (w), and subtracting one for
every
loss (l), which gives nw-nl , which can be simplified to n(w-l) So for
a
pair of win and loss, at some given number of attempts, n, we get the
formula.
[math]f(w,l) = n(w-l)[/math]

You want to know why it’s value is approximately twice as large, so
let’s
compare the two functions by dividing them. We will calculate f for
bet_rand
and bet_red, and divide them by eachother.

First we need to find the likelihood of winning and losing, our w and l,
for
bet_rand and bet_red.

bet_rand compares color_01 and color_02, each of which are randomly
selected
from values 0 through 36 (thirty seven possible values). So there is a 1
in
37 chance of color_01 being zero, and for that case, there is a 1 in 37
chance of color_02 being zero. And there is an 18 in 37 chance of
color_01
being red, and a 18 in 37 chance of color_02 being red. And there is an
18
in 37 chance of color_01 being black, and a 18 in 37 chance of color_02
being black.

So this gives us [math]\frac{18}{37} * \frac{18}{37} + \frac{18}{37} *
\frac{18}{37} + \frac{1}{37} * \frac{1}{37}[/math]

Which comes out to [math]\frac{649}{1369}[/math]

And the likelihood of losing is l = 1 - w =
[math]\frac{720}{1369}[/math]

Now, for bet_red, color_01 will always be red. So there is a 0 in 37
chance
of color_01 being zero, and for that case, there is a 1 in 37 chance of
color_02 being zero. And there is an 37 in 37 chance of color_01 being
red
(because it is manually set to red), and a 18 in 37 chance of color_02
being
red. And there is an 0 in 37 chance of color_01 being black, and a 18 in
37
chance of color_02 being black.

So this gives us [math]\frac{37}{37} * \frac{18}{37} + \frac{0}{37} *
\frac{18}{37} + \frac{0}{37} * \frac{1}{37}[/math]

Which comes out to [math]\frac{18}{37}[/math]

And the likelihood of losing is l = 1 - w = [math]\frac{19}{37}[/math]

So now we have our probabilities to feed the function.

Now, we need to find a meaningful way to compare them. What we will do
is
compare their values for some given n, we noticed that bet_rand seemed
to
grow about twice as fast as bet_red. So we will divide bet_rand’s limit
as n
approaches infinity by bet_red’s, and see if it comes out to about 2.
This
gives us

Our formula
[math]d(w,l) =
\frac{f(w_{bet_rand},l_{bet_rand})}{f(w_{bet_rand},l_{bet_rand})}[/math]

Fill in the values.
[math]=
\frac{f(\frac{649}{1369},\frac{720}{1369})}{f(\frac{18}{37},\frac{19}{37})}[/math]

Substitute the value of f(w,l)
[math]=
\frac{n(\frac{649}{1369}-\frac{720}{1369})}{n(\frac{18}{37}-\frac{19}{37})}[/math]

At this point, we can see that the value of n is irrelevant, as it
cancels
itself out.

[math]=
\frac{(\frac{649}{1369}-\frac{720}{1369})}{(\frac{18}{37}-\frac{19}{37})}[/math]

And simplifying, we get.

[math]= \frac{71}{37}[/math]

[math]\approx 1.91891891891892[/math]

So we have shown that we can expect bet_rand to grow (in a negative
direction) about 1.92 times quicker than bet_red.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs