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 Anonymous on March 30, 2009 - 11:42 am
The 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 Cedric on March 30, 2009 - 12:18 pm
This 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 Weirich on March 31, 2009 - 6:33 am
I 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 Weirich on March 31, 2009 - 7:29 am
The git URL was for cloning. Just point your browser to gist.github.com/88188 to see the code.
#5 by Cedric on March 31, 2009 - 7:32 am
Jim, 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 Weirich on March 31, 2009 - 7:45 am
There are no integers between 65 and 66 exclusive. Rand(100) returns an integer.
#7 by Tonio on March 31, 2009 - 9:36 am
Martingale 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 Mathew on April 1, 2009 - 11:13 am
oops..i guess i’ll stick to Black-21-Jack (it won’t let me post without -21-).
#9 by Anonymous Coward on April 6, 2009 - 2:17 am
Using 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 YvesG on April 9, 2009 - 4:28 pm
I 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 Richard on April 24, 2009 - 10:25 pm
I 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 Bert on May 27, 2009 - 7:00 am
I 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 bharathwaj on June 9, 2009 - 1:21 am
Hello,
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.