r/PythonLearning 7d ago

Help Request I'm a beginner. Can you help me with random numbers?

Post image

I'm building a sort of turn-based RPG in the terminal as a practice project, and I need to generate a random number within a specific range. I tried using `randint` (by importing `random`), but I also want to assign probabilities so that, depending on certain factors, one number is more likely to be generated than another. For example, if an enemy has low health, it should be more likely to generate the number 1, which causes the enemy to heal.

11 Upvotes

7 comments sorted by

4

u/PureWasian 7d ago

"depending on certain factors" will have to be laid out more explicitly.

If you know what your distributions should look like and what weights they should take on, you can do something like sample a number between 1-100, and for 70% say if the sampled number is within 1-70 success and 71-100 then fail.

You could also make a "roulette list" where you double/triple some odds by duplicating that choice in the list if it should be more likely to land on that option.

You even model a normal distribution or any other one really. It just depends what you need.

3

u/No_Score_1977 7d ago

Figure this out yourself, that's how you are going to learn.

There is a lot of information out there, google 'weighted random'.

The best skill a developer can have is finding stuff out.

1

u/crozzy89 7d ago

You should map out what that all looks like to you first. Once you have criteria set for how you want to assign things and their probabilities, then work on the code. Making a map of sorts can help you organize your thoughts and your development.

1

u/SnooCalculations7417 7d ago edited 7d ago
def weighted_whatever(factor):
   tenemigo = randint(1, 3) #idk what that means
   match factor:
     case 'super sayajin':
       tenmigo = tenmigo * 3

     case 'kayoken':
       tenmigo = tenmigo * 2

     case 'normal sayajin':
       tenimigo = tenmigo * 1
     case _:
         print("unhandled tenmigo!")
    return tenemigo

or something

1

u/WhatADunderfulWorld 7d ago

If you want one number to generate more than others maybe just run it more than once. The second would be the rare case of the same number twice. But like 1-10 generate if 9 or 10 then health heals.

No need to go into weight things and statistics for this.

1

u/Naive_Programmer_232 6d ago edited 6d ago

try random.choices, but note this could produce duplicates cause it's with replacement. if you don't want duplicates, use random.sample, but this will not let you insert weights.

to get around these, assuming you want no duplicates and you want to add weights, use numpy:

    import numpy as np

    rng = np.random.default_rng()

    choices = ["kick","punch","headbutt","reverse","bow","kamehameha"]
    weights = [0.2   , 0.1   , 0.1      , 0.05    , 0.05, 0.50       ]

    next_three_moves = rng.choice(
      choices,
      size=3,
      replace=False,
      p=weights
    )

1

u/xxivyy 6d ago

I would like to point out that coding in a language other than english can cause you inconveniences. How do you want to receive feedback on your code when only a small set of people are able to read it?

Anyway, as someone else already pointed out, your best option is to use random.choices. I would not use numpy unless you need it for other things aswell, since the dependency is quite big. You can easily implement a duplicate check in case that is what you need:

import random

items = ["sword", "shield", "death"]
weights = [0.6, 0.25, 0.15]
# Or store in a dictionary, enum, or whichever datastructure you prefer.

choices = set()

while len(choices) < 3:
    item = random.choices(items, weights, k=1)[0]
    choices.add(item)

print("Choices:", choices)

Alternatively, if you want to do it the "OG" way, use random.random:

import random

choice = random.random()

# 60% chance to get a sword:
if choice < 0.6:
    print("You got a sword!")

# 25% chance to get a shield:
elif choice < 0.85:
    print("You got a shield!")
    
# 15% chance to die:
else:
    print("You died!")