Python 3: so entfernen Sie Elemente aus einer Liste in einem text-basierten Spiel?

Ich habe auf einer Zork-wie text-basiertes adventure-Spiel, als ein persönliches Projekt, um eine Art „Crash-Kurs“ unterrichten Sie mich python. Ich bin neu in der coding im Allgemeinen, so bin ich fuzzy auf die Grundlagen.

Habe ich den Punkt erreicht, in meinem Spiel, wo ich kann, erfolgreich navigieren die Karte habe ich erstellt, und können neue Räume/Gegenstände frei. Zur Zeit arbeite ich an der Herstellung der „Inventar“ – system ordnungsgemäß funktioniert.

Derzeit habe ich ein Wörterbuch namens „roominv“ in meinem Zimmer Klasse, die arbeitet als das Inventar für jeden spezifischen Raum. Ich habe auch ein Wörterbuch namens „Tasche“ in die player-Klasse, die funktioniert wie die Spieler-Inventar.

Derzeit das Spiel ist buggy und unfertig, so abholen ein Element, das Sie haben, Holen ALLE die Elemente, die aktuell in Ihrem Zimmer, aber das ist nicht das, was ich habe Probleme mit.

Ich kann nicht herausfinden, wie leer die roominv Wörterbuch-sobald der Spieler nimmt sich die Gegenstände in diesem Raum. Jetzt können Sie die Elemente der player-Tasche, aber es erstellt eine Kopie ohne entfernen Sie Sie aus der roominv.

Habe ich versucht mit del, delattr, und pop, aber entweder bin ich nicht richtig (was ich nehme) oder das ist nicht der richtige Weg. Ich habe auch versucht .entfernen Sie die ich Links in dem code unten. Es gibt diese Fehlermeldung

Traceback (most recent call last):
  File "C:/Users/Daniel/Desktop/PythonPR/Flubbo'sLatestBuild.py", line 104, in <module>
    player = Player("Jeff", 100, [], 'introd', command)
  File "C:/Users/Daniel/Desktop/PythonPR/Flubbo'sLatestBuild.py", line 97, in __init__
    addToInventory(self.room.roominv)
  File "C:/Users/Daniel/Desktop/PythonPR/Flubbo'sLatestBuild.py", line 82, in addToInventory
    Room.roominv.remove(item)
AttributeError: type object 'Room' has no attribute 'roominv'

Dies ist die gleiche Fehlermeldung, die angezeigt wird, wenn mit del oder delattr.
Irgendwelche Tipps, Ratschläge oder pseudo-code wäre sehr geschätzt werden, und wenn werde ich nur über dieses die komplett falsche Weg bitte lassen Sie mich wissen, haha.

Um das Spiel zu starten, müssen Sie geben entweder n, w, e, oder s 3 mal (Fehler), Sie können dann zu Fuß rund um mit diesen Schlüsseln oder Abholung der Gegenstände in einem Raum mit „Produkte“.

world = {}
command = input('>>> ')


class Items:
    def __init__(self, name, info, weight, position):
        self.name = name
        self.position = position
        self.info = info
        self.weight = weight


class Weapon(Items):
    def __init__(self, name, info, damage, speed, weight, position):
        super().__init__(name, info, weight, position)
        self.damage = damage
        self.speed = speed


sword = Weapon("Sword", "A sharp looking sword. Good for fighting goblins!", 7, 5, 5, 0)
knife = Weapon("Knife", "A wicked looking knife, seems sharp!", 5, 7, 3, 5)
stick = Weapon("Stick", "You could probably hit someone with this stick if you needed to", 2, 3, 3, 2)
shackkey = Items("Shack Key", "A key! I wonder what it opens.", .01, 3)
cottagekey = Items("Cottage Key", "An ornate key with an engraving of a small cottage on one side", .01, 5)
Moonstone = Items("Moonstone", "A smooth white stone that seems to radiate soft white light", .05, 6)
flower = Items("Flower", "A beautiful wildflower", .001, 1)


class Room:

    def __init__(self, name, description, exits, actions, roominv):  # Runs every time a new room is created
        self.name = name
        self.description = description
        self.exits = exits
        self.actions = actions
        self.roominv = roominv


world['introd'] = Room('introd', "You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.", {'n' or 'north' or 'go north': "clearing"}, {"Search the ground", "Go North"}, {'sword': sword})


world['clearing'] = Room('clearing', "You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. \
To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.", {'s' or 'south' or 'go south': "introd", 'e' or 'east' or 'go east': "forest path"}, {"Take flower", "Go south", "Go East"}, {'flower': flower})



class Player:

    def __init__(self, name, health, bag, room_name, move):
        self.name = name
        self.health = health
        self.bag = bag
        self.room = world[room_name]
        self.move = move

        def travel(self, direction):
            if direction not in self.room.exits.keys():
                print("You can't go that way!")
            else:
                new_room_name = self.room.exits[direction]
                print("moving to", new_room_name)
                self.room = world[new_room_name]
                print(self.room.description)
                print(self.room.actions)

        def addToInventory(item):
            self.bag.append(item)
            Room.roominv.remove(item)

        command = input('>>> ')
        while command != "":
            command = input('>>> ')
            if command in {'n', 'e', 's', 'w', 'north', 'south', 'east', 'west', 'go north', 'go south', 'go east', 'go west'}:
                travel(self, command)
            elif command == 'look':
                print(self.room.description)
                print('Exits', self.room.exits.keys())
            elif command == '':
                print('You have to say what it is you want to do! Unfortunately due to a bug you must now restart the game. We are working on fixing this as soon as possible. Sorry!')
            elif command == 'search':
                print(self.room.roominv)
            elif command == 'Take Items':
                addToInventory(self.room.roominv)
            elif command == 'Inventory':
                print(self.bag)
            else:
                print('Invalid command')


player = Player("Jeff", 100, [], 'introd', command)

Auch fühlen sich frei, um Kritik zu meinem code! Ich versuche zu lernen und Ratschläge/Kommentare von erfahreneren Personen wäre toll.

  • Wenn Sie auf der Suche für Menschen, die bereit und in der Lage zu geben, einen Allgemeinen Blick über Ihren code, den ich empfehlen könnte, code überprüfen, aber dies würde zu sein, sobald Sie Ihr Projekt beenden. Sie kann aber die Kritik mit dem code und so.
  • Nicht wirklich auf der Suche für Sie, dass, nur gesagt, dass es am Ende wie ein nachträglicher Einfall. Ich bin auf der Suche nach Hilfe mit einem bestimmten problem in meinem Inventar-system, wie in meinem post. Danke aber! Ich werde auf jeden Fall check out code-review, nachdem mein Spiel ist ein bisschen mehr abgeschlossen.



3 Replies
  1. 2

    Sich zwar nicht um einen code-review, werde ich ein paar Hinweise für die Fehlerbehebung andere Fehler auch, aber zuerst, das problem auf der hand:

    Room.roominv.remove(item)

    Room ist eine Klasse, nicht ein Objekt, und so können Sie nicht Fragen, für seine roominv
    stattdessen müssen Sie self.room.roominv jedoch, dass wird nicht funktionieren, da .remove ist nicht Mitglied der dict schlage ich die folgenden änderungen:

    Ihre 'Take Items' Befehl:

    elif command.split()[0] == 'Take':
        for key in list(self.room.roominv.keys()):
            if self.room.roominv[key].name == command.split()[1]:
                addToInventory(key)

    Damit werden dem Anwender nur die spezifischen Elemente zur Verfügung und erlaubt dem Benutzer, um anzugeben, welche Artikel, die Sie abholen wollen.

    Werden und dann die addToInventory Funktion:

    def addToInventory(self,key):
        self.bag.append(self.room.roominv[key])
        del self.room.roominv[key]

    Dieser Griff wird beim löschen nur den bestimmten Artikel, wenn es mehrere Elemente in einem Raum.

    Den del Schlüsselwort löscht einen gegebenen Schlüssel/Element-paar aus einem Wörterbuch.


    Bezug auf deine anderen Probleme, Ihre Fehler hier:

    elif command == '':
        print('You have to say what it is you want to do! Unfortunately due to a bug you must now restart the game. We are working on fixing this as soon as possible. Sorry!')

    kann behoben werden, indem einfach das, was command war:

    elif command == '':
        print('You have to say what it is you want to do!')
        command = '#'

    Zum reparieren benötigen, geben Sie die Anweisung mehrfach, ich schlage vor, Sie tun das folgende:

    Entfernen command = input('>>> ') von der Spitze Ihres Codes.

    Ersetzen command = input('>>> ') über die while command != "" Schleife mit command = ' '

    und aktualisieren Sie Ihre Player sich nicht nehmen, ein move (dies bedeutet editting die __init__ – Funktion sowie die Erstellung von player an der Unterseite des Codes: player = Player("Jeff", 100, [], 'introd'))


    Schließlich, Erbsenzählerei, warum nicht Ihr while Schleife in einer Funktion?, all dies führt zu:

    class Player:
        def __init__(self, name, health, bag, room_name):
            self.name = name
            self.health = health
            self.bag = bag
            self.room = world[room_name]
    
        def travel(self, direction):
            if direction not in self.room.exits.keys():
                print("You can't go that way!")
            else:
                new_room_name = self.room.exits[direction]
                print("moving to", new_room_name)
                self.room = world[new_room_name]
                print(self.room.description)
                print(self.room.actions)
    
        def addToInventory(self, key):
            self.bag.append(self.room.roominv[key])
            del self.room.roominv[key]
    
        def play(self):
            command = " "
            while command != "":
                command = input('>>> ')
                if command in {'n', 'e', 's', 'w', 'north', 'south', 'east', 'west', 'go north', 'go south', 'go east', 'go west'}:
                    self.travel(command)
                elif command == 'look':
                    print(self.room.description)
                    print('Exits', self.room.exits.keys())
                elif command == '':
                    print('You have to say what it is you want to do!')
                    command = '#'
                elif command == 'search':
                    print(self.room.roominv)
                elif command.split()[0] == 'Take':
                    itemTaken = False
                    for key in list(self.room.roominv.keys()):
                        if self.room.roominv[key].name == command.split()[1]:
                            self.addToInventory(key)
                            itemTaken = True
                    if not itemTaken:
                        print("I can't find that")
                elif command == 'Inventory':
                    print(self.bag)
                else:
                    print('Invalid command')
    
    player = Player("Jeff", 100, [], 'introd')
    player.play()

    Diese änderungen führen würde, benötigen ein paar anderen änderungen, wie beim Blick auf Ihr Inventar haben, drucken Sie die .names von jedem Element, sondern als das Objekt selbst.

    Gibt es auch änderungen mehr gemacht werden könnte, dass mit einer vollständigen code-review, aber dafür sollten Sie veröffentlichen Sie Ihren code auf Code-Review, beachten Sie, dass Code-Review sollte nur verwendet werden, für komplette, funktionierende code, so stellen Sie sicher, es gibt keine game-breaking bugs vor der Veröffentlichung gibt.

    Einem Beispiel ausführen:

    >>> n
    moving to clearing
    You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.
    {'Go East', 'Take flower', 'Go south'}
    >>> s
    moving to introd
    You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.
    {'Search the ground', 'Go North'}
    >>> n
    moving to clearing
    You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.
    {'Go East', 'Take flower', 'Go south'}
    >>> s
    moving to introd
    You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.
    {'Search the ground', 'Go North'}
    >>> search
    {'sword': <__main__.Weapon object at 0x00000000040B9470>}
    >>> Take sword
    I can't find that
    >>> Take Sword
    >>> Inventory
    [<__main__.Weapon object at 0x00000000040B9470>]
    >>> search
    {}
    >>> 
  2. 0

    little_birdie Recht, wenn Sie sagt Sie versuchen, Zugriff auf ein Attribut der Klasse room statt die man von einer Instanz von Room.

    Weiterhin Ihre roominv ist ein dict. Nur list habe die Methode remove().
    Zum löschen eines Schlüssels aus einem dict verwenden:

    del dict_name[key]

    Ich sah nur, dass Sie nicht nur wählen wollen einzelne Elemente, sondern alle auf einmal.
    Daher können Sie verwenden:

    self.room.roominv.clear()

    Hier ist ein kleines Beispiel , die helfen könnten, Sie bekommen Ihre Sachen erledigt werden.

    Was Sie wahrscheinlich tun möchten, ist so etwas wie dieses:

    def addToInventory(item):
        self.bag.append(item)
        del self.room.roominv.clear()
    • Danke für die Antwort, ich habe versucht, die del dict_name[key] – Methode, jedoch wird es wieder die Fehlermeldung „TypeError: unhashable type: ‚dict'“ ich glaube, weil ich bin mit meiner Welt dict zu finden, um die roominv dict. Ich sehe in deinem Beispiel, dass Sie entfernen die Welt von dict von Ihrem Zimmer aus Instanzen, aber Wenn ich mich nicht Irre, ist es notwendig, mein code für die navigation-system zu arbeiten.
    • Wenn Sie möchten, um es zu löschen von word gehen mit del Welt[room_name].roominv.clear (), während nur ein Verweis auf die room_name in der player-Klasse.
  3. 0

    Ihre addInventory Methode ist falsch. Zuerst müssen Sie die Instanz-variable self.room anstelle der Klasse Room selbst. Zweitens, wenn das, was Sie wollen, ist die Aufklärung des ganzen roominv Wörterbuch, das Sie versuchen sollten:

    def addToInventory(item):
        self.bag.append(item)
        self.room.roominv.clear()  # this will clear the roominv dictionary

    UPDATE

    Wenn Sie wollen, Sie zu löschen ein einzelnes element aus roominv Sie tun können:

    self.room.roominv.pop(key, None)

    Dass None wird verhindert, dass die pop-von der Aufzucht eine KeyError im Falle der Schlüssel ist nicht im dict

    • Dies funktioniert für entfernt das Element aus der roominv aber es scheint, wie es auch dem entfernen aus dem Spiel als ganzes. Wenn ich drucken Sie die player-Tasche nach dem ausführen des Befehls erscheint es leer. Danke aber das ist Fortschritt!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.