字典更适合您的需求,而不是使用列表;唯一的问题是标准字典是 not 有序的,这意味着如果您循环浏览其项目,您将永远不会获得相同顺序的键/值对。标准库模块提供了OrderedDict,这是一个高级类,可以像字典一样工作,同时始终记住插入数据的顺序。
除了建议和明智的建议“不要将内置函数用作变量名”之外,您应该真正避免变量名中的“字符廉价”:它们对可读性没有帮助和调试:使用太短的名称“获得”的十分之一秒很容易变成痛苦的寻找错误的几分钟(如果不是几小时!)。
最后,global 语句应该只在非常特殊的情况下使用,它的使用率很高discouraged。
import random
from collections import OrderedDict
# create the valid range for every ability, while keeping the insertion order;
# it's been more than 20 years since I've played tabletop role playing, these
# are just ranges I put in randomly
ability_ranges = OrderedDict([
("Strength", (3, 20)),
("Dexterity", (5, 18)),
("Constitution", (2, 20)),
("Intelligence", (3, 18)),
("Wisdom", (1, 18)),
("Charisma", (4, 16)),
])
print("Dungeons and Dragons 5e Character Creator\n")
def stats_roll():
# create a new dictionary object that will be filled in with new statistics
stats = {}
for ability, (minimum, maximum) in ability_ranges.items():
# create random statistics, remember that randrange is always between
# the minimum and the maximum *minus* one: randrange(0, 2) will only
# return 0 or 1
stats[ability] = random.randrange(minimum, maximum + 1)
# return the complete statistics
return stats
stats = stats_roll()
def stats_assignment(stats):
print("Current stats:")
for ability in ability_ranges.keys():
while True:
# use a while loop to avoid raising exceptions if the user does not
# input a number or the number is not between the range of the ability
random_value = stats[ability]
ability_min, ability_max = ability_ranges[ability]
new_value = input("Which stat will you assign to {} (current: {}, <Enter> to confirm)? ".format(
ability, random_value))
if not new_value:
# if the user presses <Enter> without typing anything it means
# that he/she is ok with the random chosen value
stats[ability] = random_value
break
if new_value.isdigit():
new_value = int(new_value)
if ability_min <= new_value <= ability_max:
# if the value is between the allowed range, use it and go on!
stats[ability] = new_value
break
# at this point the user has entered a value outside the allowed range
# or has typed something that cannot be interpreted as a number
print("{} is not a valid value for {} (has to be between {} and {})!\n".format(
new_value, ability, ability_min, ability_max))
# run the assignment function using the existing statistics as a parameter; the
# function will modify the data of the "stats" object in place
stats_assignment(stats)
print("\nYour character statistics:")
for key in ability_ranges.keys():
print(" {}: {}".format(key, stats[key]))