I'm making an iOS SpriteKit game right now for first time I'm developing any app and it's tough challenge for me because it's really a big project for first time. My game is a Dice game and I defined move as 4 number. So when ever I touch the screen Player moves 4 blocks, But now I want to add Dice to the Game and I need Numbers from 1 to 4 and 8. So it will be 1,2,3,4 and 8 Numbers in the Dice. I know in Swift we can get Random Numbers with "arc4random" but how do I get numbers 1 to 4 and also 8 can I do it with arc4random and if possible I need 4 and 8 numbers to come 20% more often. Any Help will be really Helpful. Thanks.
-
1This might be helpful for you - https://stackoverflow.com/questions/32552336/generating-random-numbers-with-swift – Rashed Jul 01 '18 at 10:45
-
See also [Generate random numbers with a given distribution](https://stackoverflow.com/questions/30309556/generate-random-numbers-with-a-given-distribution) – Martin R Jul 01 '18 at 10:58
-
thanks for suggestion – Ramesh Sanghar Jul 01 '18 at 11:00
2 Answers
Put your sides
into an array and use randomElement()
to perform the roll:
let sides = [1, 2, 3, 4, 8]
let roll = sides.randomElement()!
if possible I need 4 and 8 numbers to come 20% more often
That means, 4
and 8
should come up 6 times for every time the others come up 5. So put 5 of each of 1
-3
in your array, and 6 each of 4
and 8
:
let sides = [1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8]
let roll = sides.randomElement()!
Note: It is perfectly safe and appropriate to force unwrap the result of randomElement()
with !
here because randomElement()
only returns nil
when the collection is empty, and we know it’s not.
Also, check out MartinR's randomNumber(probabilities:)
function.
You'd use his function like this:
let sides = [1, 2, 3, 4, 8]
let probabilities = [1.0, 1.0, 1.0, 1.2, 1.2]
let rand = randomNumber(probabilities: probabilities)
let roll = sides[rand]

- 150,663
- 30
- 266
- 294
-
StackOverFlow and people here are really helpful this is the first time I got help from here first time I didn't know how to ask for it :) – Ramesh Sanghar Jul 01 '18 at 10:59
-
@rameshsanghar don't forget to mark the right answer as accepted by pressing the ✓ sign on the left side – Somebody Jul 01 '18 at 11:04
You can generate a random number from 1-8, and if 5,6,7 comes, you can run the random number function again until an acceptable value. Its kinda a workaround, but it works because the dataset is small.

- 72
- 8
-
1you can in theory cause your game to freeze with this. What if you have the very unfortunate luck of always randomly getting 5? You will never break out of your loop then. – Knight0fDragon Jul 01 '18 at 14:48
-
1@Knight0fDragon The number of iterations required to get a result follows a geometric distribution with parameter 5/8. The expected number of attempts is 1.6, i.e., on average it will take less than 2 attempts. The probability of requiring 30 or more attempts is 1.6631753199735166e-13, less than one in a trillion. You quite literally stand a much better chance of being hit by lightning than having this happen, by several orders of magnitude. If you get 30 or more 5's in a row, you need a new PRNG. – pjs Jul 03 '18 at 04:13
-
@pjs that is still hire than zero, what is your point? Need to look up what “in theory” means I guess. – Knight0fDragon Jul 03 '18 at 11:04
-
@Knight0fDragon Acceptance/rejection techniques are common in random variate generation because their performance can sometimes be better than O(1) alternatives. Marsaglia's polar method for generating Gaussian random variables is a concrete example. It's conceptually the same as the Box-Muller method, but is preferred to the latter because generating x/y pairs over a square and throwing away those that don't fall inside a circumscribed circle is faster than evaluating sines and cosines. The ziggurat method, also a rejection method, is one of the fastest algorithms for Gaussians. – pjs Jul 03 '18 at 12:11
-
@pjs this is not a place to debate, so I am going to finish by saying there are ways to enact acceptance rejection techniques that do not cause the possibility of an infinite loop while at the same time being just as fast. When it comes to rejection methods, you don’t normally keep rejecting the same number over and over again. Also just caught that I used “hire”, I meant to say “higher”. It takes just 1 bad update from Apple to break arc random, as an end user I would much rather see an app fail because of the bad update rather than freeze. – Knight0fDragon Jul 03 '18 at 12:18
-
@Knight0fDragon You're mistaken about "ways to enact acceptance techniques that do not cause the possibility of an infinite loop." If it's truncated, it's a decision tree rather than a rejection technique. But that's a side issue. My point is that it's fine to disagree with this or other answers because better answers are available. However, rejection techniques are common and are even the method of choice in some cases, so it's inappropriate to ding it *because* it's a rejection method. – pjs Jul 03 '18 at 12:48
-
@Knight0fDragon can you please check my this question and maybe help me out https://stackoverflow.com/questions/52499619/skaction-works-in-didmovetoview-but-doesnt-works-in-function – Ramesh Sanghar Sep 26 '18 at 04:35