Понедельник, 25 Ноября 2024, 10:01

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Реализация ввода действий игрока в консоли на Python
cakeliekcrapДата: Понедельник, 08 Февраля 2021, 14:33 | Сообщение # 1
уже был
Сейчас нет на сайте
Всем доброго времени суток. Пишу для универа текстовую игру на python, среда разработки PyCharm. Проект - текстовая игра, в которой игроку нужно самому писать действия в консоль. У меня есть несколько классов, Player - класс, в котором происходит инициализация игрока, Trader - инициализация торговцев и Town - здесь описана реализация игровых городов. Хотелось бы узнать совета, как лучше реализовать сам набор действий игрока в консоль. Сейчас у меня эта система реализована крайне топорно: у меня есть списки на каждое действие, в которых я описываю максимально возможные варианты действий, затем в основной программе я просто на условных операторах проверяю совпадение введеного текста со словами в списках. Например:

Код

While True:
    player_action = input("Что Вы хотите сделать?")
    if player_action in goToButcher:
        butcher.talk()


Таких действий и ветвлений может быть много, а бесконечные if-elif выглядят очень нечитаемо и неудобно. К тому же есть случаи, когда вместо input("Что Вы хотите сделать?") нужно вывести например input("Введите номер товара"). Вообщем хотелось бы услышать советы по поводу того, как бы лучше все это реализовать, какие-нибудь алгоритмы или что-то в этом роде. Использую в проекте ООП
PsychoДата: Понедельник, 08 Февраля 2021, 21:28 | Сообщение # 2
Психоламер
Сейчас нет на сайте
Цитата cakeliekcrap ()
Таких действий и ветвлений может быть много, а бесконечные if-elif выглядят очень нечитаемо и неудобно

В этом случае я бы посоветовал решить вопрос через switch-case, но его в питоне нет

Можешь хранить функции в словаре и вызывать их по имени в зависимости от данных которые ввел пользователь. Что то типа:

Код
class Main:

    @staticmethod
    def main():
  dict = {'attack': Main.player_attack, 'defend': Main.player_defend}
  
  action = input('Type your action : ')
  if action in dict:
   dict[action]()
  else:
   print('Unknown action!')
  
    @staticmethod
    def player_attack():
  print('Attack')
  
    @staticmethod
    def player_defend():
  print('Defend')
  
Main.main()


Сообщение отредактировал Psycho - Понедельник, 08 Февраля 2021, 22:04
maker-rusДата: Среда, 10 Февраля 2021, 13:03 | Сообщение # 3
Гений
Сейчас нет на сайте
Цитата cakeliekcrap ()
Таких действий и ветвлений может быть много, а бесконечные if-elif выглядят очень нечитаемо и неудобно. К тому же есть случаи, когда вместо input("Что Вы хотите сделать?") нужно вывести например input("Введите номер товара"). Вообщем хотелось бы услышать советы по поводу того, как бы лучше все это реализовать, какие-нибудь алгоритмы или что-то в этом роде. Использую в проекте ООП


Поищи следующие паттерны проектирования: Game Loop, Command, Factory / Abstract Factory, Observer. Советую еще прочитать про то, что такое композиция и не злоупотреблять наследованием. Это если кратко. Если подробно расписать. То тебе нужно отделить команды и сделать их отдельными объектами. Игровой цикл также выделить в отдельный игровой объект.
Выглядит это примерно так:
Код

# Интерфейс команды (в питоне обычный класс)
class Command:
    def __init__(self, text_input):
        self.text_input = text_input

    def execute(self):
        pass

Код

# Реализация паттерна GameLoop
class GameLoop:
    def __init__(self, commands={}):
        self.commands = commands
        self.exec_command = []

    def handle_input(self):
        text_command = str(input("> "))
        text_args = text_command.split()
        self.exec_command.append(self.commands.get(text_args[0], None)(text_args[1:]))

    def update(self):
        for command in self.exec_command:
            command.execute()

Код

# Пример команды передвижения
class MoveCommand(Command):
    def __init__(self, text_input):
        super().__init__(text_input)

    def execute(self):
        print(f"we move..., args: {self.text_input}")

Создать абстрактные классы для создания городов, монстров. В случае с питоном, такого сделать нельзя, но вместо этого можно определить единственный родительский класс, определить в нем пустые методы. Далее этот класс наследовать для каждой реализации такого генератора городов / монстров / жителей.
Код

# Абстрактный класс игровых юнитов
class EnemyUnit:
    def attack(self, target):
        pass

    def special_skill(self, target):
        pass

Код

# Реализация класса монстра, тип игровой юнит
class Monster(EnemyUnit):
    def __init__(self, name=None, attack_damage=0, shield_def=0):
        self.name = name
        self.attack_damage = attack_damage
        self.shield_def = shield_def

    def attack(self, target):
        print(f"Graaaaahhhh... Attack unit: {target}")

    def special_skill(self, target):
        print(f"Uldrahora-muntilora dumba-umba spell attack unit: {target}")

Код

# Реализация фабрики (Factory)
class MonsterFactory:
    @staticmethod
    def create_monster(name):
        template_monsters = {'troll': Monster('troll', 10, 3), 'wolf': Monster('wolf', 3, 1)}
        return template_monsters.get(name, None)


Теперь создавать монстров и управлять ими можно следующим образом:
Код

troll = MonsterFactory.create_monster('troll')
troll.attack('player')


Далее, тебе необходимо создать бесконечный while цикл, в котором вызывать получение команды и обновление состояния игрового мира в зависимости от реализации GameLoop.
Вот небольшой пример:
Код

game = GameLoop({'move': MoveCommand})
while True:
    game.handle_input()
    game.update()


Пример показан исходя из паттернов проектирования перечисленных выше. Останутся вопросы - задавай.
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг