Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Re: check my logic & a random number issue

by jarich (Curate)
on Oct 11, 2002 at 03:44 UTC ( [id://204405]=note: print w/replies, xml ) Need Help??


in reply to check my logic & a random number issue

The reason I think something is wrong, is because when I simulated just 100 trials, there were a number of identical net win/loss results that occured twice. Is my logic, or random number generation the problem?
Other than just eyeballing the results, what statistical analyses have you performed? Have you checked that your average dice roll is 7? When I added code in to print the average dice roll, I noticed that there's a condition that you haven't covered.
if ($roll == $point) { $gameover = 1; if ($roll == 6 || $roll == 8) { $gameover = 1; #not necessary $winnings += 1.2 + 1; print "WIN $winnings\n"; } elsif ($roll == 5 || $roll == 9) { $gameover = 1; # not necessary $winnings += 1.5 + 1; print "WIN $winnings\n"; } elsif ($roll == 4 || $roll == 10) { $gameover = 1; # not necessary $winnings += 2 + 1; print "WIN $winnings\n"; } else { print "what happens here?"; # loss? draw? } }
Because you put $gameover = 1 at the start of that conditional block you don't need to continue to do so for each specific condition. Unless, of course, you had intended to remove that first $gameover = 1.

Is it these kind of pairs that are bothering you?

LOSE -1 average dice roll: 7 LOSE -1 average dice roll: 8 LOSE -2 average dice roll: 7 LOSE -2 average dice roll: 7 LOSE -1 average dice roll: 7 LOSE -1 average dice roll: 7
because chances are high that these are just statistical fluctuations. If you look at the dice rolls that generate these losses you'll find that they're all different. The game of craps may just be weighted to encourage losses. ;)

You'll notice that 8 in my average dice roll. This is a running average and those 5 losses just happened to be results 5 - 10 of a simulation. The average ought to stay around 7 but will fluctuate around it through about 3 standard errors. ;)

So, in conclusion, yes there is a logic error in your code, your game occasionally ends without setting wins or losses. Had you kept a total of games played you might have spotted this. Whether or not your random number generator is non-random or your use of it is flawed can only really be determined by analysing it in the same using something similar to what dws suggested.

Your logic may contain other errors but as I've never studied the game of craps I have no idea what the frequency of certain results should be. Should you lose more often than you win, but win bigger? Should you lose 1 unit twice as often as you lose 2 units? I'm 100% certain that there are statistic tables out there for this game just as there are for other casino games. Once you have that data, you'll be able to analyse your results better and check whether they're in line with what they should be.

Hope it helps

jarich

PS: for the interests of simplifying your code, you can easily drop the database stuff.

PPS: FWIW in the interests of not installing more stuff, my roll function came out to be:

sub rolldice() { # was: my $roll = int(rand(12)) + 1; my $d1 = int(rand(6)) + 1; my $d2 = int(rand(6)) + 1; my $roll = $d1 + $d2; return $roll; }

Update: Didn't think hard enough about my rolldice function. Fixed now.

Replies are listed 'Best First'.
Re: Re: check my logic & a random number issue
by blahblahblah (Priest) on Oct 11, 2002 at 04:15 UTC
    While it can't hurt to add the "else... what happens here" block that you suggest for checking errors, I don't think it would ever be reached. All of that code is inside a block where $roll == $point. If $point is ever set to anything other than 4,5,6,8,9,10, the game is over on the first roll.

    Another thing you might want to do is round the winnings down for each game. I'm pretty sure that's what the casinos do. And maybe make the minimum bet something more typical, like $5. In addition to making it more realistic, these two things combined might make the results very different than a simple $1 bet with no rounding. I don't feel like doing the math, though, so that's just a gut feeling.

    When I've played I've won a lot by betting the minimum on the pass line and then doubling the minimum for the odds. Watch out for those bets in the middle -- they're not worth it!

      Very good catch.

      My modifications to the code changed the way it worked and therefore the responses I got. My roll function allowed "1" to be returned, which ought to be impossible (with two dice). A mistake I made when making my version strict compliant prevented this mistake from showing up in my version, so I assumed it was a bug in the original code (using my roll function though).

      In which case I can't see any logic errors in the code (except perhaps for not validating the roll dice value and catching errors that shouldn't happen in that extra else statement).

      What I said about doing proper statistical analyses is still valid. ;)

      Oh, and don't take the fact that I made mistakes in a quick and dirty strict compliancy conversion to be an argument for not using strict. ;) This (as well as formatting) was sorely missed in the original version of this code.

      jarich

Re: Re: check my logic & a random number issue
by Daruma (Curate) on Oct 11, 2002 at 05:19 UTC
    Greetings!!

    PPS: FWIW in the interests of not installing more stuff, my roll function came out to be:

    sub rolldice() { my $roll = int(rand(12)) + 1; return $roll; }
    After reading your node, jarich, I began wondering how different Math::Random, int(rand(6)) and int(rand(12)) might be... I noted your suggested rolldice() subroutine quoted above. To appropriately spread the roll result to mimic a table craps game, there should be a curve peaking at seven. I decided to slap together a quick test...

    #!c:\perl\bin\perl.exe use strict; use warnings; use diagnostics; use Math::Random; my $num_rolls = 10000; my @rollhashes; for (my $i=0; $i<4; $i++) { $rollhashes[$i] = { 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0, 8 => 0, 9 => 0, 10 => 0, 11 => 0, 12 => 0 }; } for (1 .. $num_rolls) { my $m1 = random_uniform_integer(1,1,6); my $m2 = random_uniform_integer(1,1,6); my $math = $m1 + $m2; $rollhashes[2]{$math}++; my $m0 = random_uniform_integer(2,1,12); $rollhashes[0]{$m0}++; my $r1 = (int(rand(6) + 1)); my $r2 = (int(rand(6) + 1)); my $rand = $r1 + $r2; $rollhashes[3]{$rand}++; my $r0 = (int(rand(12) + 2)); $rollhashes[1]{$r0}++; } print "\nUSING TWO DICE:\n"; print "\nMath::Random\t\tint(rand)\n"; for (my $i = 2; $i <= 12; $i++) { my $n = sprintf("%02d",$i); print "$n = $rollhashes[2]{$i}\t\t$n = $rollhashes[3]{$i}\n"; } print "\nUSING ONE DIE:\n"; print "\nMath::Random\t\tint(rand)\n"; for (my $i = 2; $i <= 12; $i++) { my $n = sprintf("%02d",$i); print "$n = $rollhashes[0]{$i}\t\t$n = $rollhashes[1]{$i}\n"; }
    And here is the output:

    USING TWO DICE: Math::Random int(rand) 02 = 271 02 = 270 03 = 533 03 = 606 04 = 876 04 = 849 05 = 1129 05 = 1172 06 = 1364 06 = 1362 07 = 1640 07 = 1632 08 = 1390 08 = 1402 09 = 1101 09 = 1079 10 = 876 10 = 838 11 = 540 11 = 535 12 = 280 12 = 255 USING ONE DIE: Math::Random int(rand) 02 = 862 02 = 852 03 = 853 03 = 835 04 = 795 04 = 865 05 = 849 05 = 876 06 = 817 06 = 772 07 = 801 07 = 836 08 = 822 08 = 801 09 = 809 09 = 814 10 = 856 10 = 821 11 = 891 11 = 841 12 = 823 12 = 848
    So, using one die rather than two has a tremendous impact on the spread of the numbers! Additionally, I noted that the differences between using Math::Random and int(rand(6)) were fairly slight. After running the above code over numerous tests, I found them to be quite comparable. In the interest of not installing more than is necessary, I would go with the int(rand(6)) rather than slurping in the Math::Random goodies.

    Craps is my favorite Vegas game... I find it to be the most fun and exciting of all the games I've tried. (Probably more fun than it should be!)

    -Daruma

    Update: formatting changes and fixed reference to jarich's rand(12) usage... Thanks, jarich!!
    Update2:Reworked my unnecessarily long code with a few loops...
      You're quite right. When you use a single dice (twelve sided) the probability of getting any number (1 to 12 inclusive) is just 1/12. When you use two dices of 6 sides each the probability of each number is markedly different.
      Value Probability Combinations 1 0 2 1/36 1:1 3 2/36 1:2, 2:1 4 3/36 1:3, 2:2, 3,1 5 4/36 1:4, 2:3, 3:2, 4:1 6 5/36 1:5, 2:4, 3:3, 4:2, 5:1 7 6/36 1:6, 2:5, 3:4, 4:3, 5:2, 6:1 8 5/36 2:6, 3:5, 4:4, 5:3, 6:2 9 4/36 3:6, 4:5, 5:4, 6:3 10 3/36 4:6, 5:5, 6:4 11 2/36 5:6, 6:5 12 1/36 6:6
      Of course, if you're not using a truely random or very, very convincing pseudo-random generator you probably won't quite get these probabilities.

      Considering that 7 is a bad number to get in Craps, it'd be nicer to use just a 12 sided dice, but then the Casinos would have to rig the game another way to get their money. ;)

      It's good to know that for this kind of example rand() is as good as Math::Random.

      jarich

        If you look at the dice rolls that generate these losses you'll find that they're all different.

        Jarich: I think that explains the issue I was seeing. You can lose with a craps roll on the come out roll, and then win the next round with a winning odds bet on a 6 OR a winning odds bet on an 8, and the net win will still be the same. Basically different roll combinations are likely to yield the same net win/loss result. I'm sure I'll find some to be fairly common.

        Daruma: Thanks for putting up the results of Math::Random vs. int(rand). When you look at the probabilities of the various outcomes, and compare them with the actual real-life probabilities, although they both have fairly normal distributions, the Math::Random yields a better result.

        Math::Random int(rand) roll occ prob roll occ prob 2 271 2.71% 2 270 2.70% 3 533 5.33% 3 606 6.06% 4 876 8.76% 4 849 8.49% 5 1129 11.29% 5 1172 11.72% 6 1364 13.64% 6 1362 13.62% 7 1640 16.40% 7 1632 16.32% 8 1390 13.90% 8 1402 14.02% 9 1101 11.01% 9 1079 10.79% 10 876 8.76% 10 838 8.38% 11 540 5.40% 11 535 5.35% 12 280 2.80% 12 255 2.55% real life roll prob 1 2.78% 3 5.56% 4 8.33% 5 11.11% 6 13.89% 7 16.67% 8 13.89% 9 11.11% 10 8.33% 11 5.56% 12 2.78%
        Thanks for all the help so far. Now I guess it comes down to a random number issue. Are there any perl modules, or different techniques I can use to get the rolls as random and close to real-life as possible, or is Math::Random likely as good as it will get?

        Thanks for the continued help!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://204405]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2024-04-26 06:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found