Playr Blog

Your resource for all things playr. New game announcements, updates, bug fixes, news, you can find it first here.

Thursday, November 06, 2008


All dice rolls on Zilch are random.  Totally random, or as random as the Flash RNG will allow.  Don't believe me?

Read the source code for my Dice class.

And in case anybody cries foul, here's the HideableObject class that I use to nudge things in and out of view on the screen.



René said...

I'll certify that it's random. Nice code style, by the way.

Gaby said...

Thanks! It works for me :)

Galgaron said...

Yep, it's random.

On another note, I'm not sure that the game is recording zilch-free games now. You might want to check that. On Kongregate high scores, it shows I only have 1, but I know I've done at least 4. But I have not gotten any more awards for any more zilch-free games.

Gaby said...

Possible problem, yes. The next update is looking like it might un-award some awards, but it changes the in-game stats used for some of them so they will be awarded again in due course. Don't be concerned if some awards vanish.

Andrew from Middlebrook said...

awesome code, awesome game.

Ignore all the did a great job!

Ni said...

I'm just wondering, (as you got... interesting way to comment your code. When you have to choose whether to comment points of interests or self explanationary booleans, rather comment the points of interest)
In other words, I'm just wondering whats that array of arrays is for? I mean that 6x6 thing that seems to be related to the dices. You got 6 dices, why do you have array for each side of each dice?
And cant you really just stop drawing a certain object in some frames, do you really have to hide it? (Or did I get the wrong idea from reading the name of"Hidden objects class" I didnt bother to read it trough.)
Well, I dont code with flash action script or what ever you wish to call it, so I wouldn't know, just that, every coding language I have used so far has had plenty of methods to avoid wasting resources.
And yeah, kinda pretty looking code, even though I would prefer having the "=" closer to what equals what... but thats just a matter of taste, I dont like olives either.

Gaby said...

I like things that line up, hence the '=' are all in a line. OCD possibly...

The arrays of arrays are basically an array from 1 to 6 which represents the six faces of the dice, then each of those six faces has six possible graphics that could be used on it. This is why when you have several dice of the same type they don't show the same graphic, one graphic is chosen randomly from the list for that side of the dice.

XLII said...

It's not random.

I've done statistical and math calculation and both variancy and standard deviation are off-line.

Standard deviation is 0.763 against 0.747 (pure math chance) and Variancy is 0.55 against 0.58 (math based) based on population of 150 dice throws.

What is even worse - that both VAR and SD are both RISING with increase of samples taken, which implies that RNG used here sucks ;)

This might suggest a bit that dice rolls are based on Gaussian probability (which is pure bullshit for dice throws - because it doesn't matter if you want to throw edge-based values against middle ones).

The funniest thing is that the biggest deviation are for scoring "dice".

Pure calculation shows that for 2 dices, chances for Zilch is 4/9. I actually made it to make 20 Zilch based on following scheme which gives:
(4 / 9)^20 = 0.00000904377268% chance for this happening.

Which means that I'm either superlucky, or Zilch isn't random at all.

Nice game though. If it wasn't for broken RNG I'd probably sink in it for good. Even better idea to play some offline with real dices ;)

Bang said...

xlii, not quite sure if i understand ur comment about being superlucky... does this mean that u got 20 zilches in a row?

If so, then ur calculation isnt completely correct, and u are making one of the most common mistakes made by gameplayers and gamblers alike.

In simple terms, dice/cards/coins/lottories etc. have no memories. lol

to quote u: "Pure calculation shows that for 2 dices, chances for Zilch is 4/9. I actually made it to make 20 Zilch based on following scheme which gives:
(4 / 9)^20 = 0.00000904377268% chance for this happening."

This is very accurate and correct. but only until you make that first zilch.

Before u roll any dice, as u calculated, getting 20 zilches in a row with 2 dice left is extremely unlikely.

However, once u get that first zilch, this is no longer an unknown factor. It has already occured, and the results are known. So the probability for this roll becomes 1 since the results are already known.

So after ur first zilch, we need a new calculation for the chances of 20 zilches in a row. It would be:

1 (for the known first zilch)* (4/9)^19.

With each zilch u get, the chances of getting 20 zilches in a row becomes more likely, because of the known factors. after that 19th zilch, you have almost a 50% chance of getting the 20th zilch, since our calculation would be 1*19*(4/9).

Gaby said...

If you reckon the Flash RNG sucks then please send a bug report to Adobe, they'd be happy to hear it :)

zandperl said...

Not sure if this is a bug or something that needs clarification in the rules. I just tied a game and it was recorded for the awards as a loss. Reckless got to 10100 points, then in my next turn I got 10100 points as well (9350 plus banked 750). Where it reports the outcome it says that both I and the computer got 10100 and didn't report a winner, but I unlocked the "Very Unlucky" (3 losses in a row) award. I didn't notice if the total losses incremented in the game stats screen. If this is behaving the way it should (if you intended that a score over 10000 must be ~beaten~) then I'd appreciate having that clarified in the rules or hints.

XLII said...


Of course - it's called gambler paradox (or gambler ruin) and it's well known rule.

However while you can't use this method to calculate your current chance (as I wasn't) you can use it to visualise or represent probability of chain of events. And in this case this chain had exactly such probability.

And yes - I actually had 20 Zilch's, yet I was testing how many times in row I could Zilch while testing my luck on previous mentioned 2-dice throw combination.

I don't actually think 5/9 is too low to throw (bit more than coin toss anyway), however experience with Zilch - which, by the way, inspired me to do above calculations - show otherwise.

Rolling three dices is pretty risky in game (while chances for Zilch! are less than 1/9), and rolling two dices is extremly risky.

It gets even weirder when you use 1 dice throw. Because it is pretty random and it feels balanced.

While playing at Kongregate I asked fellow players to share their "feeling rate" about 2-dice throws. Some of them said that they feel that it is less than 10% chance (they also had multiple Zilch using this technique) I haven't heard single opinion stating that it feels like coin throw.

Anyway, I'll take a look at the code. Maybe I could dig something out if it ;)

Rick said...

This is the code that rolls the dice, right?

num = Math.floor( ( Math.random() * 6 ) + 1 );

I haven't done statistical analysis like some posters, but generically speaking, every time you do math on floating point numbers, you expose yourself to more floating point errors. Why not add the 1 AFTER flooring?

num = Math.floor( ( Math.random() * 6 )) + 1;

This should have the same output in theory, but in practice means less floating point arithmetic (the 1 is added to an integer, not a float).

You should also see a negligible reduction in lag, since integer arithmetic is faster than float arithmetic.

Rick said...

Also, if I interpret the code correctly, rolling the dice longer actually generates more random numbers, which shouldn't accomplish anything meaningful, assuming independent probabilities; worse, players (well, at least myself, but I don't think I'm alone in this) assume the short rolling option is cosmetic, but it actually affects gameplay (even ideally, it inflates lag; at worse, something goes wrong with the random number generator). Why not remove the multiple references to generating the random number? Just do it once, no matter how much cosmetic rolling you're doing.

Gaby said...

The longer rolls are cosmetic, randomly switching between a number of dice graphics gives the appearance of a dice spinning around.

I'm not really concerned about lag as it's not a time sensitive game and the number of actual random numbers picked is negligible.

Some reasonable comments about picking lots of random numbers, I can see some optimisations that could be applied. Whilst the dice themselves are actually "rolling", eg switching between states to simulate a roll, that could be pre-programmed, only picking a random number at the end of the rolling phase.

Griffer said...

Maybe, you could first generate the actually number, then calculate back the frames for the numbers, because actual dice do not roll from 1 to 6 to 4 to 3 etc. , but rather 1 to 2/3/4/5 to 6 to 5/4/3/2, depending how you throw it.

Griffer said...

the actual* number ofcourse.

Derrick said...

Pure calculation shows that for 2 dices, chances for Zilch is 4/9. I actually made it to make 20 Zilch based on following scheme which gives:
(4 / 9)^20 = 0.00000904377268% chance for this happening.

Which means that I'm either superlucky, or Zilch isn't random at all.

No, for 20, it would be (2/3)^20 (or (4/9)^10), just like for 2 it was (2/3)^2. (2/3)^20 is about .0003%, or 3 in ten thousand. So that if just ten thousand play the game once, and only up until 20 dice rolls, 3 of them should get nothing but zilch. There's been over 200,000 plays at kongregate alone (who knows how many plays at this site, and wherever else it is hosted), and each of those plays could be for multiple games, and each of those games have WAY more than twenty dice rolls.

Of course that's silly, because the only way you could get to 20 rolls would be to score some points (banked or not not banked), otherwise you'll get 18 rolls or 24. These calculations are for absolutely no scoring at anytime. 20 dice rolls that include scoring and not banking is going to be much more complex to calculate, but much more commmon.

SwingLowSweetDeej said...

When the Wizard is back taking questions I'm sure he can help with this:

Andrew said...

I actually made an entire blog post concerning how you're handling this situation, I think it's worth a read. At the end are some suggestions that I think would help your game.

Jon said...

Yes, I suppose it as as random as the Flash RNG will allow. The problem is that this is not very random at all. I've seen basically the same behavior that xlii describes. Granted, there isn't really anything you can do about this (short of using an entropy service to seed each roll. Think server-side CPU hog). An RNG is only as good as its seed, and Math.random() doesn't even allow you to specify one. Even if you could specify a seed, it would be very difficult to do it well in a flash program. Even C programs that use an RNG seeded with time*pid don't turn out to be very random (or evenly distributed). Ultimately, an auto-seeded RNG running in a virtual machine just isn't close to random.

All that aside, its a very fun game when realist doesn't pull 3 3k+ turns out of his a** in a row.

Kutulu said...

> which implies that RNG used here sucks

Well, ok, lets get the pedantic stuff right out of the way: it's a *pesudo* random number generator, obviously. And yah, it kinda sucks.

For one, I don't believe Math.random() lets you specify a seed value, which implies that your random numbers are only as random as the decision Flash makes about it's seed value. And I doubt they're using any terribly complex PRNG algorithm for web games :)

Second, I'm a tiny bit suspicious about your math to calculate the odds of Zilching on two dice. It seems to be over simplified by assuming that you only have two dice and are rolling them repeatedly. But you aren't. In between zilches, you are rolling multiple other rolls and selectively elminating non-zilch combinations from your result set in order to get back to having just two dice to roll, which on the surface seems like it would taint your calculation. In other words, since you have to actually *try* to put yourself into a position to Zilch with just 2 dice, you are increasing your odds of doing so.

(Then again, the whole reason I stopped taking statistics courses is because I kept trying to run probabilities at a craps table in my head and it made by brain hurt, so I'm out of practice.)

Ni said...

Kutulu, you are missing the point of what Xlii is saying.

Lets give a metamorphic example: You got a banana you want to peel, the color of the shirt of the guy you bought the banana and/or peeler or the number of bananas does not matter. You just want to peel one of them. Wouldn't it be strange if when you peeled the banana you actually found a pineapple inside?

What Xlii is saying, that even though 2 dice throws should give a certain probability of Zilching, they actually give one whole another probability of Zilching, thus proving that the program is not so random after all. Getting into the point where you have 2 dices left to throw doesn't matter at all.

Oh, and one thing, when one of the players gets over 10 000 score, and the last "round" begins... There is a mistake there, there is no "round", just one turn for the losing player to try to get his score higher than the winning ones. Who started the game doesn't matter.

Where as, if it would really be a "round" the one who started the game would matter. If the one that is winning was the one that started the game, then the losing one would have his turn and thats it. If the winning one is the "number 2" player, then the "round" would be "number 1" as in the one who started the game (and is in this case, losing) and then once again the "number 2" player if the scores turned around.
Please fix that, its annoying.

Scott said...

Nice game Gaby, I enjoy playing it. Well done.

I know zilch (ha) about coding, but why will it never Zilch in the first roll? If you played this in real life, there must be a reasonable chance of doing so, so even if it happens rarely, this should be a possibility. I've played hundreds of games and it has never happened. Not a criticism, but I think it would make it more real and interesting if this could happen.

jamesramm said...

Check your math. IS a population of 150 throws really a good sample, which truly reflects all possibiilities? For just two die, there are 36 possible combinations. an experiment with two real die shows that even after 200 throws, its is only beggining to appraoch a normal (gaussian) distribution, according to the central limit theorem. And why you said that dice throws arent based on gaussian statistics is beyond me, as it is THE classic example..
So, your negative results arent proof of anything but gross undersampling, me thinks. Doesnt mean the game isnt biased though.
Also calculating the variance seperately doesnt tell us anymore than the standard deviation as it is merely the std dev squared. A students t-test would be a good solid way to test the game...
the mean vs expected value is always a good place to start aswell. Try it with one die, roll, many rolls before your plot becomes centered around the expected value (which is 3.5 for a 6 sided die)? then think about how many rolls you should try when dealing with 6 die.
I also dont understand about your 20 zilches in a row? Its impossible to get a zilch on the first in order to get a jsut keep on 20 zilches in a row is a certainty if you just keep rolling each turn until you get one. Funnily enough, the expected number of rolls before you hit a zilch is around 3.5 aswell...

George said...

There seems to be a lot of confusion about the two-die randomness issue, so I thought I'd throw my hat in the ring.

I agree with those saying that the RNG is bad and the game itself is fun (I'm going to play it with real dice at home - thanks Gaby!). I have also noticed the the two-die problem.

Here's how I figure it: one of the reasons why probability and statistics classes start out with coin flips and six-sided die rolls is that the probabilities involved are so simple that new students already have a gut feel for them (we can sort this out without much math).

It is true that dice have no memory and each roll is independent of all others. This allows us to look at the two-die sample set without worrying about how we got there. If all I need to know is: is the RNG good?, I can use the simple two die test and only examine what happens when the game gets to that point and I choose 'Roll' every time.

To be clear, the two outcomes are: zilch or not zilch. If neither die is a 1 or a 5, the outcome is 'zilch'. If either or both dice score, the outcome is 'not zilch'. My test is to see how many zilches in a row I end up getting, with the first outcome of 'not zilch' triggering a new trial.

This is a good test because, as others have said, the probability of getting multiple zilches in a row with two dice drops below 4/100 after 7. I choose a target that high to make a relatively small sample set reasonable (it also happens that I just got 7 zilches in a row with two dice on my FIRST trial).

The progression works like this:
P 1st roll is zilch = 2/3
P 2nd roll in a row is zilch = (2/3)^2
P 3rd roll in a row is zilch = (2/3)^3

As I said before, I got 7 zilches in a row with two dice on my first trial. That makes me very suspicious (not certain, but suspicious) that the RNG is bad.

Try the test out yourselves; the more people that find that they get more zilches in a row than they should in relatively few trials, the more certain you can be that the RNG isn't R. See?

One final note in regard to the Gambler's Fallacy (which the above is certainly not). The fallacy is that you can alter the probability of any single roll by the outcomes of the rolls that preceded it. Here's a fun story:

A wall street investor and a mathematician are both told that a coin has been flipped 99 times and come up heads every time. They are then asked to predict the outcome of the 100th throw.

The mathematician says: Easy; it's 50-50 because each throw is an independent event.

The investor says: Are you kidding me? The next throw will be heads because that coin is rigged.


George said...

I messed up on the math!

Progression should read:

P 1st roll is zilch = 4/9
P 2nd roll in a row is zilch = (4/9)^2
P 3rd roll in a row is zilch = (4/9)^3

This is because 2/3 is the probability of zilching on ONE die. This actually only makes the above argument stronger because the probability of seven zilches in a row drops to less than 4/1000!


borandi said...

Best way to define randomness is not to rely on the RNG. Use the Fisher-Yates Shuffle algorithm, as shown here:

That link shows how MS fixed their EU browser ballot, then what happens if you use the Fisher Yates algorithm instead.