简体   繁体   中英

C# Slotmachine winning algorythm

I'm trying to program a slot machine.

I have 5 rollers and 7 winning pictures. It looks like

-----|-----|-----|-----|----|

-----|-----|-----|-----|----|

-----|-----|-----|-----|----|

I get each roll 3 pictures.

foreach (var s in Walze1)
        {
            Random rnd = new Random();
            int perCent = rnd.Next(Walze1dot7, 110);

            //10 % Chance auf 7 per Walze
            if (perCent <= 10)
            {
                Walze1dot7 = 11;
                s.Text = "7";
            }
            //10 % Chance auf Glocke per Walze
            else if (perCent <= 20 & perCent > 10)
            {
                s.Text = "Glocke";
            }
            //15 % Chance auf Melone
            else if (perCent <= 35 & perCent > 20)
            {
                s.Text = "Melone";
            }
            //15 % Chance auf Pflaume
            else if (perCent <= 35 & perCent > 50)
            {
                s.Text = "Pflaume";
            }
            //20 % Chance auf Orange
            else if (perCent <= 70 & perCent > 50)
            {
                s.Text = "Orange";
            }
            //20 % Chance auf Zitrone
            else if (perCent <= 90 & perCent > 70)
            {
                s.Text = "Zitrone";
            }
            //20 % Chance auf Kirche
            else if (perCent <= 110 & perCent > 90)
            {
                s.Text = "Kirche";
            }
        }

only one 7 should be possible at one roller.

MY PROBLEM:

I winning too much... the random Code gives me too often a successful picture (min. 3 same pictures for one line).

So how can I change my Code that I will loose more often?

EDIT

It is not a duplicate because i know how to generate a random number...What i need is that i dont get to often a winning pictures (3 each line)...

Let's Say i play with 100 € on 2€ per click. after 50 click i got more than 300 € always.

I didn't test it, but I suggest you can do this:

add using System.Collections.Generic; to your file.

procents are now real procents, the statements are optimized, the Random initialisation is out of the loop, and you store what you rolled.

//sorry for the bad performance, i didn't optimize it.
//you could do that by making a list with the strings in it and remove the one you rolled.
List<string> rolled = new List<string>();
Random rnd = new Random();
foreach (var s in Walze1)
{
    again:
    //generate an number with min 0, max 99
    int perCent = rnd.Next(Walze1dot7, 100);

    //10 % Chance, 0 to 9
    if (perCent < 10)
    {
        s.Text = "7";
    }
    //10 % Chance, 10 to 19
    else if (perCent < 20)
    {
        s.Text = "Glocke";
    }
    //10 % Chance, 20 to 29
    else if (perCent < 30)
    {
        s.Text = "Melone";
    }
    //15 % Chance, 30 to 44
    else if (perCent < 45)
    {
        s.Text = "Pflaume";
    }
    //15 % Chance, 45 to 59
    else if (perCent < 60)
    {
        s.Text = "Orange";
    }
    //20 % Chance, 60 to 79
    else if (perCent < 80)
    {
        s.Text = "Zitrone";
    }
    //20 % Chance, 80 to 99
    else if (perCent < 100)
    {
        s.Text = "Kirche";
    }
    if(rolled.Contains(s.Text)){goto Again;}
    rolled.Add(s.Text);
}

Using (bitwise and)& instead of (logical and) && in your if statements is a problem, but it is not the main one. You should also not generate a new Random() every time you call this function - it is an expensive operation and running it often will slow you down.

You said you tested it, but the randomness was not tested. When you are generating random occurrences you should write a test case that sees how random they really are. In your specific case, you can create a Dictionay<string,int> and initialize it with the strings being every string you can randomly select, and then add 1 to it each time you generate that string.

static Dictionary<string,int> CountUses = new Dictionary<string, int>();

  /* do this once  - so they always print in order*/
        CountUses.Add("", 0);
        CountUses.Add("7", 0);
        CountUses.Add("Glocke", 0);
        CountUses.Add("Melone", 0);
        CountUses.Add("Pflaume", 0);
        CountUses.Add("Orange", 0);
        CountUses.Add("Zitrone", 0);
        CountUses.Add("Kirche", 0);

/* use this in your function */
if (!CountUses.ContainsKey(s.Text))
     CountUses.Add(s.Text, 0);

 CountUses[s.Text]++;

Then call your function 10,000,000 times and see what the numbers look like - they should be fairly close.

    for ( int x = 1; x < 10000000; ++x)
        tester(); //function I made to call your code

    foreach (var key in CountUses.Keys)
            Console.WriteLine(String.Format("{0,10} uses of {1,8} = {2:P}", CountUses[key], key, CountUses[key]/ 10000000.0f));

With your code, the results are not well distributed and sometimes empty:

   1376943 uses of          = 13.77%
    998104 uses of        7 = 9.98%
    937056 uses of   Glocke = 9.37%
   1358398 uses of   Melone = 13.58%
         0 uses of  Pflaume = 0.00%
   1814880 uses of   Orange = 18.15%
   1788699 uses of  Zitrone = 17.89%
   1725919 uses of   Kirche = 17.26%

Replacing & with && is different but still not right (close enough to be random differences):

   1358963 uses of          = 13.59%
   1013747 uses of        7 = 10.14%
    891739 uses of   Glocke = 8.92%
   1382211 uses of   Melone = 13.82%
         0 uses of  Pflaume = 0.00%
   1818295 uses of   Orange = 18.18%
   1825153 uses of  Zitrone = 18.25%
   1709891 uses of   Kirche = 17.10%

With the test code it should be very easy to track down your biggest mistake, and then see if the % you get are actually the ones you expect.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM