Перемещение игровой комнаты в комнату на основе текста Python

Я новичок в кодировании и работаю над текстовой игрой, перемещающейся из комнаты в комнату. Код работает в pycharm, но согласно программе мгновенной обратной связи, в которую я ввел его, он дал несколько советов по нему, и я не совсем уверен, как его улучшить. Вот что это дало мне:

  1. Строка Большого зала — ключ к основному словарю. Измените код, чтобы он не был ключевым в основном словаре.
  2. Он сказал, что не может классифицировать мой код (не уверен, что это значит), мне нужна команда def main ()?
  3. Объедините несколько команд печати в одну функцию
  4. Упростите условие, используя несложные условия. С простыми операторами, которые не ищут внутри строки 5. Лучше использовать while True: и зарезервированное слово break для остановки цикла, когда вам нужно, чтобы он остановился.

настройка данных

rooms = {'Great Hall': {'name': 'Great Hall', 'South': 'Bedroom', 'North': 'Dungeon', 'West': 'Library', 'East': 'Kitchen'},
     'Bedroom': {'name': 'Bedroom', 'East': 'Cellar', 'North': 'Great Hall'},
     'Cellar': {'name': 'Cellar', 'West': 'Bedroom'},
     'Library': {'name': 'Library', 'East': 'Great Hall'},
     'Kitchen': {'name': 'Kitchen', 'West': 'Great Hall', 'North': 'Dining Room'},
     'Dining Room': {'name': 'Dining Room', 'South': 'Kitchen'},
     'Dungeon': {'name': 'Dungeon', 'South': 'Great Hall', 'East': 'Gallery'},
     'Gallery': {'name': 'Gallery', 'West': 'Dungeon'},
     }
directions = ['North', 'South', 'East', 'West']
current_room = rooms['Great Hall']

# game loop
while True:
   # display current location
   print()
   print('You are in the {}.'.format(current_room['name']))

  # get user input
  command = input('nWhat direction do you want to go? ').strip()
  # movement
  if command in directions:
     if command in current_room:
         current_room = rooms[current_room[command]]
     else:
        # bad movement
        print("You can't go that way.")
  # Exit game
  elif command.lower() in ('q', 'quit'):
      break
  # bad command
  else:
     print("I don't understand that command.")

1 ответ
1

В целом, я не думаю, что код настолько плох, учитывая его цель; но если вы хотите расширить свою игру, я думаю, что самая большая проблема — это структура данных.

Было бы очень легко потерять какую-то комнату или назвать ее по-другому, если вам придется каждый раз повторяться, поэтому я предлагаю вам использовать класс для представления комнаты:

class Room:
    name: str
    north: 'Room'
    east: 'Room'
    south: 'Room'
    west: 'Room'

    def __init__(self, name, north=None, east=None, south=None, west=None):
        self.name = name
        self.north = north
        self.east = east
        self.west = west
        self.south = south

        if north:
            north.south = self
        if east:
            east.west = self
        if south:
            south.north = self
        if west:
            west.east = self

    def go_to(self, direction):
        if direction in ['north','east','south','west']:
            return getattr(self, direction) 
        else:
            return None

    def __str__(self):
        return self.name

Я использую типы, потому что это очень полезно для выявления проблем, пока не стало слишком поздно. В Python, если у вас есть рекурсивный тип (например, Room), вам нужно использовать кавычки, но это просто синтаксическая запись.

По умолчанию в комнате нет комнат на север, восток, юг, запад (отсюда и =None) но главное, что происходит в __init__ заключается в том, что когда вы добавляете комнату, она автоматически устанавливает противоположное направление. Таким образом, если одна комната переходит в другую на востоке, другая комната делает обратное на западе. Таким образом мы уменьшаем ошибки в направлениях. Если это не относится к какой-то комнате, вы сможете переопределить это, используя другой класс (SelfLockingRoom который закрывает все остальные направления при входе, например).

В __str__ метод заключается в том, чтобы просто обработать отображение комнаты в самой комнате; в какой-то момент у вас может быть больше, чем просто имя для отображения.

Я также добавляю метод go_to, это ответственность комнаты, чтобы решить, куда идти, учитывая направление; в будущем у вас может быть TrapRoom который расширяет Room и в случае направления «Восток» будет творить, например, гадости. В getattr просто чтобы не писать if direction=='north': return self.north но было бы так же, а может быть, даже яснее.

На самом деле, если игра будет развиваться дальше, вам могут потребоваться более сложные правила, чтобы решить, что делать с заданным направлением, поэтому, вероятно, вам понадобится класс House:

class House:
    current_room: Room
    rooms: list[Room]  # at the moment is not used but could be in the future?

    def __init__(self, current_room: Room, rooms: list[Room]):
        self.current_room = current_room
        self.rooms = rooms

    def go_to(self, direction):
        if next_room := self.current_room.go_to(direction):
            self.current_room = next_room
        return next_room

На данный момент это не очень полезно, но я думаю, что будет.

Чтобы инициализировать дом, вы просто создаете комнаты:

house_rooms = [cellar := Room('Cellar'), library := Room('Library'), dining_room := Room('Dining Room'),
               gallery := Room('Gallery'), bedroom := Room('Bedroom', east=cellar),
               dungeon := Room('Dungeon', east=gallery),
               kitchen := Room('Kitchen', north=dining_room),
               great_hall := Room('Great Hall', south=bedroom, north=dungeon, west=library, east=kitchen)]

house = House(current_room=great_hall, rooms=house_rooms)

(Как видите, я не повторяю имена или направления)

С игровым циклом все в порядке, мы можем собрать несколько полезных методов на случай, если вы захотите расширить их в будущем:

def prompt(text: str):
    print(text)


def ask(text: str) -> str:
    return input(text).strip()

и это будет ваш игровой цикл (я всегда уменьшаю направление, чтобы вы могли писать «Восток-восток» или «ВОСТОК»).

commands = {
    "directions": ['north', 'south', 'east', 'west'],
    "quit": ['q', 'quit']
}

def game_loop():
    prompt(f"nYou are in the {house.current_room}")
    command = ask('nWhat direction do you want to go? ').lower()
    if command in commands["directions"]:
        if not house.go_to(command):
            prompt("You can't go that way.")
    elif command in commands["quit"]:
        return False
    else:
        prompt("I don't understand that command.")
    return True


if __name__ == '__main__':
    while game_loop():
        pass

  • 1

    Здесь много хороших советов, достойных поддержки. Но не используйте __getattribute__() для простых ситуаций, когда вам просто нужно получить атрибут по имени. Это слишком низкий уровень, подходящий только при особых обстоятельствах. Правильный инструмент getattr.

    — FMc


  • Ты прав! Спасибо, ответ отредактировал.

    — Фабио Ф.


Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *