Я новичок в кодировании и работаю над текстовой игрой, перемещающейся из комнаты в комнату. Код работает в pycharm, но согласно программе мгновенной обратной связи, в которую я ввел его, он дал несколько советов по нему, и я не совсем уверен, как его улучшить. Вот что это дало мне:
- Строка Большого зала — ключ к основному словарю. Измените код, чтобы он не был ключевым в основном словаре.
- Он сказал, что не может классифицировать мой код (не уверен, что это значит), мне нужна команда def main ()?
- Объедините несколько команд печати в одну функцию
- Упростите условие, используя несложные условия. С простыми операторами, которые не ищут внутри строки 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 ответ
В целом, я не думаю, что код настолько плох, учитывая его цель; но если вы хотите расширить свою игру, я думаю, что самая большая проблема — это структура данных.
Было бы очень легко потерять какую-то комнату или назвать ее по-другому, если вам придется каждый раз повторяться, поэтому я предлагаю вам использовать класс для представления комнаты:
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
Здесь много хороших советов, достойных поддержки. Но не используйте
__getattribute__()
для простых ситуаций, когда вам просто нужно получить атрибут по имени. Это слишком низкий уровень, подходящий только при особых обстоятельствах. Правильный инструмент getattr.— FMc
Ты прав! Спасибо, ответ отредактировал.
— Фабио Ф.