Как внедрить предметы в каждую комнату в текстовом приключении на python3? - PullRequest
0 голосов
/ 15 октября 2019

Я довольно новичок в работе, но я хотел кое-что узнать об этом, и поэтому я начал писать текстовое приключение на Python3.

После долгого времени, прочитав много предложений и методов о том, какДля начала я решил пойти с cmd-модулем для разбора и классами для комнат и прочего. Я не хочу записывать так много данных о приключениях в код, поэтому я наткнулся на идею использовать модуль json для аутсорсинга. До сих пор мне удавалось переключаться между комнатами, и теперь я хочу, чтобы в них были предметы.

Я попытался добавить еще один атрибут в класс комнаты, который должен быть списком предметов, доступных в этой конкретной комнате. Теперь я застрял на том, как сделать экземпляры этих предметов в комнате, чтобы распечатать их описание в следующем порядке:

1.) Room name 
2.) Room description
3.) Item1 description
4.) Item2 description
5.) ...

1.) и 2.) были напечатаны уже сdo_look ()

Вот основной игровой цикл:

import cmd
from rooms import get_room

class Play(cmd.Cmd):
    """Base class for the game"""
    def __init__(self):
        cmd.Cmd.__init__(self)
        cmd.Cmd.prompt = '> '
        self.location = get_room(1)    
        self.do_look()

    def move(self, direction):
        new_id = self.location.exit_to(direction)
        if new_id is None:
            print('You can not go there')
        else:
            self.location = get_room(new_id)
            self.do_look()

    def do_look(self, *args):
        """Print the Room description."""
        print(self.location.name)
        print("")
        print(self.location.desc)
        print("")

    def do_north(self, *args): #Example direction command
        """Move north"""
        self.move('north')

if __name__ == '__main__':
    play = Play()
    play.cmdloop()

А вот модуль комнат (с уже добавленным атрибутом "items"):

import json

def get_room(_id):
    # ret = None
    with open(str(_id) + '.json', 'r') as f:
        jsontext = f.read()
        d = json.loads(jsontext)
        # d["_id"] = _id 
        ret = Room(**d)
    return ret

class Room:
    def __init__(self, _id = 0, name = '', desc = '' exits = {}, items = []):
        self._id = _id
        self.name = name
        self.desc = desc
        self.exits =  exits
        self.items = items

    def exit_to(self, _dir):
        if _dir in self.exits:
            return self.exits[_dir]
        else:
            return None

И типичный .json выглядит так (Имя файла: 1.json):

{   
    "_id" : "1", 
    "name" : "The First Room",
    "desc" : "You wake up in the First Room ...",
    "exits" : {"north" : 4},
    "items" : ["puppet", "gun"]
    }

Я также создал модуль предметов, но я не знаю, как подключить его к комнатам:

class Item:
    def __init__(self, name, desc, desc_in_room):
        self.name = name
        self.desc = desc
        self.desc_in_room = desc_in_room


""" This is the first and unfinished attempt to deal with it,
    but I think this is not gonna work:"""

def make_item(self, _id):
     with open(str(_id) + '.json', 'r') as f:
        jsontext = f.read()
        d = json.jsonloads(jsontext)
            for i in d["items"]:
                with open(str(i) + '.json', 'r') as fil:
                    itemtext = f.read()
                    item_dict = json.jsonloads(itemtext)
                    """Dont know..."""
    return ret

Так что любые советы о том, как извлечь «марионетку» из списка внутри dict и преобразовать его в экземпляр Item и напечатать его описания, будут приветствоваться!

1 Ответ

0 голосов
/ 15 октября 2019

Прелесть Python в том, что есть библиотека для большинства обычных операций - и множество необычных. В вашем случае JsonPickle выглядит хорошим выбором. Вы можете создать шаблон json из комнаты, затем изменить его где угодно и повторно гидрировать по мере необходимости. Я написал пример для вас ниже;

first

pip-install jsonpickle

, затем выполните код ниже

import jsonpickle
import pprint


class Item:
    def __init__(self, name, desc, desc_in_room):
        self.name = name
        self.desc = desc
        self.desc_in_room = desc_in_room

    def __str__(self):
        return f"{self.name}, {self.desc}, {self.desc_in_room}"


class Room:
    def __init__(self, _id=0, name='', desc='', exits=None, items=None):
        self._id = _id
        self.name = name
        self.desc = desc
        self.exits = exits if exits is not None else {}
        self.items = items if items is not None else []

    def exit_to(self, _dir):
        if _dir in self.exits:
            return self.exits[_dir]
        else:
            return None


if __name__ == '__main__':
    myroom = Room(1, "First", "An eerie door leads to your destiny",
                  items=[Item("Item1", "Hammer", "Large and heavy"), Item("Item2", "Sword", "Old and rusty")])

    frozen = jsonpickle.encode(myroom)
    print(frozen)

    # YIELDS
    """{"_id": 1, "desc": "An eerie door leads to your destiny", "exits": {}, "items": 
    [{"desc": "Hammer", "desc_in_room": "Large and heavy", "name": "Item1", "py/object": "__main__.Item"}, 
    {"desc": "Sword", "desc_in_room": "Old and rusty", "name": "Item2", "py/object": "__main__.Item"}], 
    "name": "First", "py/object": "__main__.Room"}"""

    # CHANGE AT WILL
    modified = """{"_id": 1, "desc": "An eerie door leads to your destiny", "exits": {}, "items": 
    [{"desc": "Feather", "desc_in_room": "Harmless", "name": "Item1", "py/object": "__main__.Item"}, 
    {"desc": "Sword", "desc_in_room": "Old and rusty", "name": "Item2", "py/object": "__main__.Item"}], 
    "name": "Second", "py/object": "__main__.Room"}"""

    new_room = jsonpickle.decode(modified)  # type: Room
    print(new_room.name)
    for i in new_room.items:
        print(i)

    # YIELDS the Following. Note the new name for the room and for the Hammer
    """
    Second
    Item1, Feather, Harmless
    Item2, Sword, Old and rusty
    """
...