Сужение диапазона генерации случайных чисел

Ниже представлен код, создающий 4 случайных предмета. Каждый предмет может обладать определенной редкостью: редкий, супер-редкий, эпический, мистический, легендарный (расположены в порядке увеличения редкости).

Требуется добиться следующего поведения: редкость первого предмета выбирается случайно без ограничений, а каждого следующего - случайно, но не меньше предыдущего.

import random

rare = 0.5
superrare = 0.28
epic = 0.15
mythic = 0.05
legendary = 0.02
q = 'rare'
a = 'superrare'
b = 'epic'
c = 'mythic'
d = 'legendary'
t = 0
while t != 4:
    if random.random() < 0.5:
        print("rare")
        q += '1'
        t += 1
        if q == 'rare1':
            rare = 0.0
    elif random.random() < 0.28:
        print(a)
        a += '1'
        t += 1
        if a == 'superrare1' or q == 'rare':
            superrare -= 0.28
            rare -= 0.5
    elif random.random() < 0.15:
        print(b)
        b += '1'
        t += 1
        if b == 'epic1' or a == 'superrare' or q == 'rare':
            epic -= 0.15
            superrare -= 0.28
            rare = 0.5
    elif random.random() < 0.05:
        print(c)
        c += '1'
        t += 1
        if c == 'mythic1' or b == 'epic' or a == 'superrare' or q == 'rare':
            mythic -= 0.05
            epic -= 0.15
            superrare -= 0.28
            rare -= 0.5
    elif random.random() < 0.02:
        print(d)
        t += 1
        if d == 'legendary':
            d = '0'

Внимание: текст вопроса является вольной интерпретацией задачи, изначально изложенной так:

"Как сделать выпадение только 4 редкости не хочу чтобы редкость понижалась допустим если epic не хочу что бы было rare"

Возможны "неточности перевода".


Ответы (2 шт):

Автор решения: Alexey Trukhanov

Берем список парных кортежей, в котором записаны пары вероятность выпадения:название редкости. С помощью random.choices() собираем список из четырех редкостей, учитывая веса вероятностей. Сортируем по вероятностям. Печатаем.

import random

rarity = [
    (0.02, 'legendary'),
    (0.05, 'mythic'),
    (0.15, 'epic'),
    (0.28, 'superrare'),
    (0.5, 'rare')
]

print(*[r[1] for r in sorted(random.choices(rarity, weights=[r[0] for r in rarity], k=4), reverse=True)], sep='\n')
→ Ссылка
Автор решения: Amgarak

Я не менял ваш код, но добавил вам простенькое и наглядное условие для редкости. Суть в чем, мы сохраняем уже выпавшие редкости и в последующих циклах, нам уже не упадёт редкость ниже той, что уже выпадала:

import random

rare = 0.5
superrare = 0.28
epic = 0.15
mythic = 0.05
legendary = 0.02
q = 'rare'
a = 'superrare'
b = 'epic'
c = 'mythic'
d = 'legendary'
t = 0
ra = set()
while t != 4:
    
    if random.random() < 0.5:
        if  "rare" not in ra and\
           "superrare1" not in ra\
            and "epic1" not in ra\
            and "mythic1" not in ra\
            and "legendary" not in ra:
            ra.add("rare")
            print("rare")
        
            q += '1'
            t += 1
            if q == 'rare1':
                rare = 0.0
    elif random.random() < 0.28:
        if  "superrare1" not in ra\
            and "epic1" not in ra\
            and "mythic1" not in ra\
            and "legendary" not in ra:
            ra.add("superrare1")
            print(a)
            a += '1'
            t += 1
            if a == 'superrare1' or q == 'rare':
                superrare -= 0.28
                rare -= 0.5
    elif random.random() < 0.15:
        if  "epic1" not in ra\
            and "mythic1" not in ra\
            and "legendary" not in ra:
            ra.add("epic1")
            print(b)
            b += '1'
            t += 1
            if b == 'epic1' or a == 'superrare' or q == 'rare':
                epic -= 0.15
                superrare -= 0.28
                rare = 0.5
    elif random.random() < 0.05:
        if  "mythic1" not in ra\
            and "legendary" not in ra:
            ra.add("mythic1")
            print(c)
            c += '1'
            t += 1
            if c == 'mythic1' or b == 'epic' or a == 'superrare' or q == 'rare':
                mythic -= 0.05
                epic -= 0.15
                superrare -= 0.28
                rare -= 0.5
    elif random.random() < 0.02:
        if  "legendary" not in  ra:
            ra.add("legendary")
            print(d)
            t += 1
            if d == 'legendary':
                d = '0'
→ Ссылка