-2

i have a game where the exit will trigger a kind of dice which can lead you to a random level. I have this script that does this:

public string levelToLoad; // first level
public bool levelSplit; //Do we split?
public string levelToSplit; //second levl
public int splitLevelChance; //if the chance was 4/7, this should be the 4
public int SplitDenominator; //And this should be the 7

int normal = 0;  //To keep count
int split = 0;

for (int i = 0; i < 2000; i++) //Run the test 2000 times
{
    System.Random rnd = new System.Random();

    int dice = rnd.Next(1, SplitDenominator + 1); //Roll a dice
    print(dice);

    if (dice <= splitLevelChance)
    {
        normal++;
      //  SceneManager.LoadScene(levelToLoad);
    }
    else
    {
        split++;
       // SceneManager.LoadScene(levelToSplit);
    }
}

print("normal: " + normal);
print("split:" + split);

So this is working fine with stuff like 1/4 or 1/8 but when i do for example 8/ 18 its being inaccurate.

Below is the tests i did with 8/18

Test 1 - normal = 899, split = 1101

Test 2 - normal = 879, split = 1121

Test 3 - normal = 885, split = 1115

If my math is correct, normal should get around 615 and split 1385

Edit: my math was wrong, the code actually works correctly

Rachel Dockter
  • 946
  • 1
  • 8
  • 21
  • @john my question is completely different, did you even read it – Rachel Dockter Jun 01 '18 at 11:09
  • 1
    I did, and I see that you're creating a new `Random` variable in the loop every single time. Since the initial seed is based on the `Environment.Ticks` value, it means that a tight loop will get the same "random" value over and over. I imagine that kind of thing might throw your numbers off in the way you describe. – ProgrammingLlama Jun 01 '18 at 11:10
  • Its generating a new value for me, thats why the tests ive conducted doesnt give 2000 in one and 0 in the other – Rachel Dockter Jun 01 '18 at 11:11
  • OK, but consider that `Ticks` has the same value for a period of time Y, and your code runs for time period X*Y. Every number generated in each Y period will be identical. Once the Y period elapses, a new number will be generated for the new Y period. – ProgrammingLlama Jun 01 '18 at 11:13
  • Ok, ive taken the random generator out of the for loop and did 3 more tests, its giving me the same range of results. Is my math just wrong or would 8/18 give roughly 880 on 2000 rolls – Rachel Dockter Jun 01 '18 at 11:14
  • Is there any chance you can post a code example that I can drop into Visual Studio to test with? – ProgrammingLlama Jun 01 '18 at 11:16
  • sure, just replace System.Random rnd = new System.Random(); with Random rnd = new Random(); make Splitlevelchance equal 8 and split leveldemoninator equal 18. I cant remember what replaces print, i think Console.writeline(..) – Rachel Dockter Jun 01 '18 at 11:18
  • 1
    what's wrong with the results? isn't 885/(885+1115) approximately 8/18? – Lincoln Cheng Jun 01 '18 at 11:18
  • I just tried with those values with the `Random` outside the for loop, and I got 881 vs 1119. For a 8/18 probability (8/18*2000) that sounds about right. FWIW If I remove the `print(...)` I get 0 vs 2000 or 2000 vs 0 depending on the seed value - the print actually takes some time which probably saves it a bit. – ProgrammingLlama Jun 01 '18 at 11:19
  • I did 2000 / 26 and then multiplied it by 8. Which gave me 615. Is that calculation wrong – Rachel Dockter Jun 01 '18 at 11:22
  • Where does 26 come from? Your current code is equivalent to the fraction 8/18, or ~44.4% – ProgrammingLlama Jun 01 '18 at 11:23
  • 18 + 8, thats like the scope of how many possibilites there could be – Rachel Dockter Jun 01 '18 at 11:24
  • 2
    It seems that my code is actually right then, my irl math is just wrong, oops – Rachel Dockter Jun 01 '18 at 11:24
  • @Rachel Please do keep the `Random` outside the loop, or you will have the other problem I described :) (You can test it by commenting out `print(dice)`) I hadn't factored in your IRL maths being wrong lol ^_^ – ProgrammingLlama Jun 01 '18 at 11:25
  • 2
    Ok ill put it outside the loop, it cant hurt since it gives the same results for me anyway. Thankyou though, i should of used an online probability calculator instead of my head – Rachel Dockter Jun 01 '18 at 11:26
  • 2
    Since the question was based on a false premise, it's probably better to just delete it now – DavidG Jun 01 '18 at 11:30
  • Show your math for should get around 615 and split 1385 – paparazzo Jun 01 '18 at 11:30
  • (2000/(8+18)) * x with x being 8 to get 615 and 18 or get 1385. Also not letting me delete the question – Rachel Dockter Jun 01 '18 at 11:32
  • I checked your code and print(dice); has blocks of repeated numbers. It is an obvious problem. The blocks were still random enough to give similar results but you have a much smaller sample set than the 2000. – paparazzo Jun 01 '18 at 11:43
  • 1
    I've flagged to close this question as "off-topic - the problem can be no longer reproduced." – sonnyb Jun 01 '18 at 12:17
  • When using Unity, use Unity's `Random` API to generate random number. – Programmer Jun 01 '18 at 14:07

1 Answers1

1

You need to pull new Random out of the loop.

System.Random rnd = new System.Random();
for (int i = 0; i < 2000; i++) //Run the test 2000 times
{

Seed is based on time so it will get the same seed for a number of loops.

paparazzo
  • 44,497
  • 23
  • 105
  • 176
  • Down vote may I ask the problem? – paparazzo Jun 01 '18 at 11:12
  • This doesnt make a difference, if the value i was getting was the same everytime, The tests ive done in my question would come back, normal = 2000, split = 0 or visa versa. That wasnt me who downvotted btw, i wouldnt pay attention to it, people can be obnoxious on here, i personally appriciate you trying to help though – Rachel Dockter Jun 01 '18 at 11:12
  • @RachelDockter Have you tried my answer? – paparazzo Jun 01 '18 at 11:13
  • yes, i did 3 more tests with it outside the loop and its giving me the same range of results – Rachel Dockter Jun 01 '18 at 11:15
  • 2
    Downvoted because if this *was* the answer (which comments say it's not), it is a blatant duplicate that does not need the 100000th duplicate answer – Camilo Terevinto Jun 01 '18 at 11:16
  • 1
    Indeed @CamiloTerevinto is correct here. While most questions involving `Random` are usually an obvious duplicate, this isn't related to that problem. – DavidG Jun 01 '18 at 11:20
  • 1
    @RachelDockter Camilo is saying this **isn't** a dupe, please read carefully. – DavidG Jun 01 '18 at 11:20
  • @paparazzo Its generating the same range of numbers regardless of if its inside or outside the loop – Rachel Dockter Jun 01 '18 at 11:20
  • @DavidG sorry my mistake – Rachel Dockter Jun 01 '18 at 11:21
  • @CamiloTerevinto That comment was it must be good because not 2000 in one and 0 in the other. Not conclusive in my book. – paparazzo Jun 01 '18 at 11:21
  • @RachelDockter Also, downvotes are not "obnoxious", that's just how the site works. People vote on content, it's not personal so please don't take it that way. Votes are there to ensure we get high quality content on this site. – DavidG Jun 01 '18 at 11:22
  • @Rachel As I've just added above, the `print(...)` in the loop is saving you when the random declaration is in the loop - the time it takes to print allows the seed value time to change. – ProgrammingLlama Jun 01 '18 at 11:23