A few people answered correctly to my little challenge, but not everyone.

At first sight, the rules look pretty favorable to the player: half of the time, I lose my money, but the other half, I get back at least as much as I bet.

Or do I?

Well, no. If you look at the rules carefully, you realize that what you are getting back if the roll is over 50 is not as obvious as it looks. Take the 66-75 range: you get 1.5 times your money, but you need to remember that part of this is the original bet. So if you bet $1, rolling between 66 and 75 will only make you richer by $0.5 and not $1.5. And the same applies to the other rolls.

Your gain expectation therefore is:

-1*0.50 + 0.5*0.10 + 1*0.24 + 2*0.01 =-0.19

For every dollar you bet, you will lose 19 cents.

Here is a simulation in Ruby:

fortune = 0 max = 1000000 for i in 1..max do n = (rand * 100).round if (n < 50) then fortune = fortune - 1 elsif (n >= 50 && n <= 64) then fortune = fortune + 0 elsif (n >= 65 && n <= 75) then fortune = fortune + 0.5 elsif (n >= 76 && n <= 99) then fortune = fortune + 1 elsif (n == 100) then fortune = fortune + 2 else puts "#{i}: n:#{n}" end end puts fortune

and the output:

$ ruby ~/t/game.rb -184887.0

The mistake that a few commenters made (and which I made as well initially) was to have a few extra "ones" in their gain calculation.

#1 by

Anonymouson March 30, 2009 - 11:42 amThe outcome can be very different if you are allowed to change how much you risk.

For instance, as suggested by a commenter on the previous post, you can double up every time you loose. On top of that, you lower your bet every time you win and have your fortune is positive.

fortune = 0

bet = 1

max = 1000000

for i in 1..max do

n = (rand * 100).round

if (n < 50)

fortune = fortune – bet

bet = 2*bet

elsif (n >= 50 && n <= 64) then fortune = fortune + 0

elsif (n >= 65 && n <= 75) then fortune = fortune + 0.5*bet

elsif (n >= 76 && n <= 99) then fortune = fortune + 1*bet

elsif (n == 100) then fortune = fortune + 2*bet

else puts “#{i}: n:#{n}”

end

if (n >= 65 && fortune > 0) then bet = 1

end

puts “#{i} fortune = #{fortune} : bet = #{bet}”

end

puts fortune

#2 by

Cedricon March 30, 2009 - 12:18 pmThis is called a Martingale and it’s a well documented approach that will defeat any gamb_ling scheme, provided you have unlimited funds:

en.wikipedia.org/wiki/Martingale_(probability_theory)

#3 by

Jim Weirichon March 31, 2009 - 6:33 amI think the simulation is a bit off. The (100*rand).round expression will return 0 to 100 (rather than 1 to 100). Zero and 100 both are 1/2 as likely as any other number, so 100 appears less often in the simulation than expected (thus increasing the loss). Also the limits are inconsistent, partially compensating for extra loss caused the range error. A corrected version can be found at git://gist.github.com/88188.git.

#4 by

Jim Weirichon March 31, 2009 - 7:29 amThe git URL was for cloning. Just point your browser to gist.github.com/88188 to see the code.

#5 by

Cedricon March 31, 2009 - 7:32 amJim, I think your solution is a bit off as well since it will fall back to the default case for values between [65,66], [75,76] and [99,100] (with these boundaries excluded).

#6 by

Jim Weirichon March 31, 2009 - 7:45 amThere are no integers between 65 and 66 exclusive. Rand(100) returns an integer.

#7 by

Tonioon March 31, 2009 - 9:36 amMartingale won’t defeat any gamb_ling scheme… not really. You’d need unlimited funds for that. But if you have unlimited funds, winning money won’t change your available funds (still unlimited). With any limit to your funds, a Martingale still ends up with a negative expected outcome if the game is rigged against the player.

en.wikipedia.org/wiki/Martingale_(betting_system)

#8 by

Sony Mathewon April 1, 2009 - 11:13 amoops..i guess i’ll stick to Black-21-Jack (it won’t let me post without -21-).

#9 by

Anonymous Cowardon April 6, 2009 - 2:17 amUsing floating numbers for such a trivial problem shows much of what is wrong in this industry. This is exactly like people using floating point numbers to represent monetary amount like $3.42. Hint: in many case you don’t store 3.42 “dollar” but 342 cents.

It’s really, really, sad to see people misuse floating point numbers like that.

The result of your simulation contains about 100000 accumulation of precision errors. It just happens to be “close” to the correct response because you’re accumulating errors in one way then in the other (but it’s still mindboggingly saddening to see such misuse of floating point numbers).

Oh and one day, one day, a unit test framework author shall read and understand Goldberg and implement a correct floating-point comparison method. But I’m not holding my breath.

#10 by

YvesGon April 9, 2009 - 4:28 pmI wouldn’t try the martingale technique as I’d loose even more, in a legacy language, that would be:

public class Game {

public static void main(String[] args) {

java.util.Random rand = new java.util.Random();

float fortune = 0;

float bet = 1;

int tries = 1000000;

while (tries– > 0){

fortune -= bet;

int roll = rand.nextInt(100) + 1;

if (roll <= 50){

bet = bet * 2;

continue;

}

if (roll = 51 && roll = 66 && roll =76 && roll <=99) fortune += bet * 2;

if (roll == 100) fortune += bet * 3;

bet = 1;

}

System.out.println(fortune);

}

}

#11 by

Richardon April 24, 2009 - 10:25 pmI guess you can still use Martingale to take down someone with finite funds. It doesn’t change your situation, but it does change theirs

#12 by

Berton May 27, 2009 - 7:00 amI would agree that if you bet your entire fortune ever time that you would end up in the hole. But if you always bet a fixed amount (exactly $1 every time), I believe the outcome would be to the advantage of the player.

I just tested 100 games with 1 million rounds each and always came up positive.

#13 by

bharathwajon June 9, 2009 - 1:21 amHello,

I think you gain expectancy calculation is wrong. It should be

-1 * 0.5 + 1 * 0.15 + 1.5 * 0.1 + 2 * 0.24 + 3 * 0.01 = 0.16

So I will surely play the game. Of course by probability theory I will gain on infinite try outs. If I am wrong please let me know.