转盘物品
转盘概率
转盘规则
①抽空一项后概率平分给剩下所有项(限定视作1份)
②抽到限定后概率只加给剩下的限定
③限定物品抽空后会获得所有物品
代码
列表暴力循环
抽空的物品从列表中删除
import random
import matplotlib
def weighted_random(items, num):
i = 0
l = len(num) # 未抽完的物品数
limit = 3 # 限定物品数
flag = 0 # 未抽到限定
while i < 29:
n = random.uniform(0, 100) # 随机生成[0, 100] 范围内的实数
i += 1
x = 0
for w in items:
# 是本次抽到的物品
if n < w:
num[x] -= 1
# 该物品被抽完
if num[x] == 0:
l -= 1 # 未抽完物品-1
# 抽到限定
if x == 0 or x == 1 or x == 2:
flag = 1
limit -= 1
# 限定抽完
if limit == 0:
return i
for y in range(limit + 1):
if y != x:
items[y] = items[y] + items[x] / limit
if flag == 0: # 不是限定
for y in range(l + 1):
# 若不是该项物品也不是已经抽完的物品
if y != x:
if y < limit:
items[y] = items[y] + (items[x] / (l - limit + 1)) / limit
else:
items[y] = items[y] + items[x] / (l - limit + 1)
# 去掉抽空的物品
num.pop(x)
items.pop(x)
break
n = n - w
x += 1
return i
# 方便计算将物品编号
# list = [('衣服0', 0.4,1), ('黑暗粉1', 0.2,1), ('小红鸮2', 0.4,1), ('传说记忆瓶3', 15,3), ('占星卡牌4', 15,3),
# ('冒险者口袋5', 18,7),('私人阅览证6', 15,2), ('图书券7',18,6), ('金币8',18,6)]
avg = 0
for i in range(100000):
items = [0.4, 0.2, 0.4, 15, 15, 18, 15, 18, 18]
num = [1, 1, 1, 3, 3, 7, 2, 6, 6]
count = weighted_random(items, num)
# print(count)
avg = count + avg
print(avg / 100000)
运行结果
用该方法算出普通转盘结果
只考虑到了单抽的情况,可能有些偏差
欢迎大佬讨论更高效准确的方法