我目前正在尝试创建一种随机获得某个项目(在游戏中表示)的方法,例如一个项目的20%,或50%的百分比甚至1%。我尝试使用下面描述的代码执行此操作:
from random import randint
def Break():
print(".")
def Treasure():
Gen = randint(1,100)
if Gen <= 10:
print("10%")
Break()
Gen = randint(1,100)
if Gen <= 10:
print("10%")
Break()
Gen = randint(1,100)
if Gen <= 10:
print("10%")
Break()
Gen = randint(1,100)
if Gen <= 10:
print("10%")
Break()
Gen = randint(1,100)
if Gen <= 10:
print("10%")
Break()
这种代码方法很有效,问题是即使选择了这里的百分比并且调用了Break(),仍然有可能列出超过一个百分比 所以,如果它说80%那么Break() 它也可以列出50%然后Break()一段时间。
所以我的问题是,我怎么能做到以下几点:
测试代码:(已编辑)
if gen <= 10:
print("10%")
elif gen <= 20:
print("20%")
elif gen <= 30:
print("30%")
elif gen <= 40:
print("30%")
elif gen <= 50:
print("50%")
elif gen <= 60:
print("60%")
elif gen <= 70:
print("70%")
elif gen <= 80:
print("80%")
elif gen <= 90:
print("90%")
这不是最有可能的90%,反过来最少10%吗?
答案 0 :(得分:2)
首先要做的几件事:
资本化很重要; break
和Break
是两件不同的事情
break
是一个关键字,而不是一个函数;称之为break
,而不是break()
break
是退出循环,但不在循环中;也许你的意思是return
而不是?
你级联案件的方式是减少百分比:
gen = randint(1,100)
if gen <= 10:
return "10% (#1)"
gen = randint(1,100)
if gen <= 10:
return "10% (#2)" # 10% of 90% == 9%
gen = randint(1,100)
if gen <= 10:
return "10% (#3)" # 10% of 81% == 8.1%
对于正确的值,您需要累积测试,例如
gen = randint(1, 100)
if gen <= 10:
return "10% (#1)"
elif gen <= 20:
return "10% (#2)"
elif gen <= 30:
return "10% (#3)"
它可能会节省很多恶化,将其包装在类中,如
from bisect import bisect # fast binary search
from random import random
class RandomItemGenerator:
def __init__(self, items=None, probs=None):
# start with no items
self.items = []
self.total = 0.
self.breakpoints = []
# add any initial items
if items is not None:
for item, prob in zip(items, probs):
self.add_item(item, prob)
def add_item(self, item, prob):
self.items.append(item)
self.total += prob
self.breakpoints.append(self.total)
def __call__(self):
if self.items:
value = random() * self.total
index = bisect(self.breakpoints, value)
return self.items[index]
else:
raise ValueError("you haven't got any items yet")
然后您的代码看起来像
make_treasure = RandomItemGenerator()
make_treasure.add_item("sword", 80)
make_treasure.add_item("sword +1", 19)
make_treasure.add_item("ring +2", 1)
我们可以测试
from collections import Counter
# generate 10,000 items
test = Counter(make_treasure() for i in range(10000))
# check number of each item generated
print(test.most_common())
给出类似
的内容[('sword', 8002), ('sword +1', 1887), ('ring +2', 111)]
编辑:返回函数的示例:
def sword_fn():
# your stuff goes here
def dagger_fn():
# your stuff goes here
def wand_fn():
# your stuff goes here
make_fn = RandomItemGenerator()
make_fn.add_item(sword_fn, 80)
make_fn.add_item(dagger_fn, 19)
make_fn.add_item(wand_fn, 1)
which = make_fn() # pick a function
which() # run the function
我的上一条评论使用了等效的简写,例如
make_fn = RandomItemGenerator([sword_fn, dagger_fn, wand_fn], [80, 19, 1])
与上面的四行完全相同,我创建实例然后添加项目。
答案 1 :(得分:0)
你可以尝试这样的事情:
def Break():
print(".")
def FindAnotherName():
Gen = randint(1,100)
if Gen <= 10:
print("10%")
Break()
return True
else:
return False
def Treasure():
i = 0
finished = False
while (i < 5 && finished == False):
finished = FinAnotherName()
i = i + 1