0

I've been working on a slots script for my Twitch bot and for some damn reason, it is extremely heavily weighted towards the first two options. I've even removed all the balancing stuff and made it so it's just a 1 in 6 chance to spawn each of the 6 emotes.

Also, disclaimer, I've literally never worked with python before, so please forgive my awful code.

rangeb = ["Kappa", "DansGame", "SMOrc", "OSfrog", "KAPOW", "KappaPride"] 

intcap = 6
kappa = 6
kapow = 5
osfrog = 4
smorc = 3
dansgame = 2


total1 = random.randrange(1, intcap)

total2 = random.randrange(1, intcap)

total3 = random.randrange(1, intcap)

if total1 >= kappa:
    emote1 = 5
elif total1 >=kapow:
    emote1 = 4
elif total1 >=osfrog:
    emote1 = 3
elif total1 >=smorc:
    emote1 = 2
elif total1 >=dansgame:
    emote1 = 1
else:
    emote1 = 0

if total2 >= kappa:
    emote2 = 5
elif total2 >=kapow:
    emote2 = 4
elif total2 >=osfrog:
    emote2 = 3
elif total2 >=smorc:
    emote2 = 2
elif total2 >=dansgame:
    emote2 = 1
else:
    emote2 = 0

if total3 >= kappa:
    emote3 = 5
elif total3 >=kapow:
    emote3 = 4
elif total3 >=osfrog:
    emote3 = 3
elif total3 >=smorc:
    emote3 = 2
elif total3 >=dansgame:
    emote3 = 1
else:
    emote3 = 0

Parent.SendTwitchMessage(rangeb[emote1])
Parent.SendTwitchMessage(rangeb[emote2])
Parent.SendTwitchMessage(rangeb[emote3])

The idea is to have it "spin," generate 3 emotes and display them seperately in chat, then tell the user if they won. Thing is, it almost always displays one of the first 3 emotes, Kappa, DansGame, or SMorc. Ideally the percentage values of each emote should be 30,25,20,12,8,5, with 30 being Kappa and 5 being KappaPride. No damn idea why it never picks them truly randomly.

Andrew Guy
  • 9,310
  • 3
  • 28
  • 40
rxbots
  • 87
  • 1
  • 8
  • Computers can't really generate "truly" random data.Random is random.It can generate 100 of 9's in a row and it can still be considered random. –  Sep 27 '17 at 05:48
  • Your list ordering doesn't appear to match up with what the indices seem to suggest they should. For example, "Kappa" is at index 0, but the kappa branch in `if`/`else` sets the index at 5. I don't actually know why you're using this `if`/`elif` structure anyway, when you could just use the indices directly and avoid the confusion. – roganjosh Sep 27 '17 at 05:52
  • The idea was to have it generate a random number between 1 and 100. Then the whole if/elif ladder splits them apart, so say the Kappa which has a 30% win chance is triggered if the generated number is less than 30. – rxbots Sep 27 '17 at 06:15
  • It is not a contradiction. "truly randomly" is not the same as "uniformly distributed". Every time you draw randomly, there is some underlying distribution (uniform, normal, exponential, ...). Numpy has a functionality where you can specify your values and assign them probabilities: https://stackoverflow.com/a/4266645/6699237 – akoeltringer Sep 27 '17 at 07:19

1 Answers1

1

NumPy's random module provides a choice function that will pick a solution with assigned probabilities (the items in p must sum to 1):

import numpy as np
choice1 = np.random.choice(["Kappa", "DansGame", "SMOrc", "OSfrog", "KAPOW", "KappaPride"], p=[ 0.3 ,  0.25,  0.2 ,  0.12,  0.08,  0.05])`.

If you want to stick to the plain random module that comes with Python, a solution is to repeat the entries in proportion to their likeliness of outcome:

import random

l = []
l.extend(["Kappa"]*30)
l.extend(["DansGame"]*25)
l.extend(["SMOrc"]*20)
l.extend(["OSfrog"]*12)
l.extend(["KAPOW"]*8)
l.extend(["KappaPride"]*5)

choice1 = random.choice(l)

You can have a code that is easier to maintain by coupling the definition in the following way:

name_list = [('Kappa', 30), ('DansGame', 25), ('SMOrc', 20), ('OSfrog', 12), ('KAPOW', 8), ('KappaPride', 5)]
l = []
for name, number in data:
    l.extend([name]*number)
Pierre de Buyl
  • 7,074
  • 2
  • 16
  • 22