#python
#python
Вопрос:
Я создаю текстовую приключенческую игру на python. Как только игра начнется, я хотел бы создать экземпляр класса с именем «Character», который является объектом персонажа игрока. Я хотел бы, чтобы пользователь мог выбирать расу персонажа, которого он хочет играть. Пока у меня есть:
class Race:
def __init__(self, name, passive, hp):
self.name = name
self.passive = passive
self.hp = hp
и
class Lizard(Race):
def __init__(self, name, passive, hp):
super().__init__(name, passive, hp)
self.name = 'Lizardman'
self.passive = 'Regrowth'
self.hp = 20
def regrowth(self):
if 0 < self.hp <= 18:
self.hp = 2
и
def race_select():
races = ['Lizard']
while True:
for i, j in enumerate(races):
print(f"[{i 1}]", j)
choice = int(input('Pick a race:'))
if choice <= len(races):
print('You are a ', races[choice - 1])
return races[choice - 1]
else:
continue
Если я правильно понимаю, если бы я хотел, чтобы раса была ящерицей, мне все равно пришлось бы делать
character = Lizard('Lizardman', 'Regrowth', 20)
Есть ли простой способ позволить пользователю выбрать расу и объект, который будет создан соответствующим образом? Спасибо
Комментарии:
1. Чтобы ответить на оба ваших вопроса, прямо сейчас это вроде как работает, но я должен настроить его так, чтобы он выводил правильные вещи, чтобы он работал только в том случае, если есть один выбор расы. Я просто немного сбит с толку, потому что мне было интересно, есть ли какой-нибудь способ сделать так, чтобы я мог просто сказать character = Lizard() без указания каких-либо параметров, потому что я уже дал параметры в коде класса Lizard (он же ‘Lizardman’, ‘Regrowth’, 20… кажется немного повторяющимся делать это дважды)
2. Что касается параметров, вы можете просто иметь пустое
__init__
значение для Lizard и просто передать жестко закодированные «Lizardman», «Regrowth», 20, …. в super() .
Ответ №1:
Простым решением было бы сопоставить имя классу с помощью словаря. В качестве простого примера:
race_map = {"lizard": Lizard,
"human": Human} # I'm adding a theoretical other class as an example
choice = input('Pick a race:')
race_initializer = race_map.get(choice, None) # Get the chosen class, or None if input is bad
if race_initializer is None:
# They entered bad input that doesn't correspond to a race
else:
new_creature = race_initializer(their_name, their_passive, their_hp)
new_creature
теперь это новый объект выбранного класса.
Возможно, вы захотите стандартизировать ввод, используя choice.lower()
, чтобы гарантировать, что заглавные буквы не имеют значения, когда они вводят свой выбор.
Я изменил его, чтобы разрешить указывать расу по имени строки вместо числа. Если вам нужно число, вы можете сохранить свой список, но применить ту же идею. Что-то вроде:
race_list = races = [('Lizard', Lizard), ('human', Human)]
choice = int(input('Pick a race:'))
try:
race_initializer = race_list[choice][1] # 1 because the class object is the second in the tuple
new_creature = race_initializer(their_name, their_passive, their_hp)
except IndexError:
# Bad input
Я включил имя в race_list
, чтобы вы могли перебирать список и распечатывать ассоциации index-> name для выбора пользователем.
Вы также можете захотеть использовать более надежную структуру, чем обычный кортеж, для хранения сопоставлений name-> initializer, но это хорошо работает в простых случаях.
Комментарии:
1. Потрясающее спасибо за прояснение этого. Просто чтобы убедиться, будет ли код, которым вы поделились, помещен внутрь функции? Можете ли вы создать экземпляр класса внутри функции, и вы можете возиться с ним вне этой функции?
2. @Schnibs Этот код определенно может быть внутри функции. Если вы хотите
new_creature
выйти за пределы функции, в которой он был создан, вы могли бы простоreturn
использовать объект из функции или использовать функцию как метод класса «environment», в котором хранятся все объекты, используемые в игре, иappend
new_creature
список существ, поддерживаемых классом. Это действительно зависит от того, как вы планируете структурировать вещи.