Schleife mit Modulen für RPG-Game

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
didier
User
Beiträge: 11
Registriert: Freitag 18. April 2014, 12:40

Hallo liebes Python-Forum
Ich bin gerade dabei Programmieren und Python zu lernen. Dafür mache ich gerade ein kleines Text-RPG-Spiel und verstehe etwas mit den Schleifen nicht.

Es soll die Möglichkeit geben in verschiedene Räume beliebig oft zu wechseln und darin dinge zu erledigen (rausgehen, reingehen, rausgehen, reingehen).

Für die Räume habe ich je ein einzelnes Modul erstellt. Leider habe ich nicht herausbekommen wie ich so eine "endlose" Schleife herstellen kann ohne dass das Programm beendet wird.

Zu Testzwecken habe ich zwei Module mit for-Anweisungen erstellt, die meiner Meinung nach eigentlich endlos laufen sollten. Nach dem ersten Durchgang wird das Programm aber beendet.

Hier der Code (Name des Moduls: schleifemodul1):

Code: Alles auswählen

# -*- coding: utf-8 -*-

def raum1():
    print "Wir sind im Modul1"
    print "+++111111++++"
    import schleifemodul2
    
raum1()
Name des Moduls: schleifemodul2

Code: Alles auswählen

# -*- coding: utf-8 -*-

def raum2():
    print "Wir sind im Modul2"
    print "+++222222222++++"
    import schleifemodul1
    
raum2()
Hier die Ausgabe in der Powershell:
Wir sind im Modul1
+++111111++++
Wir sind im Modul2
+++222222222++++
Wir sind im Modul1
+++111111++++

Wo genau mache ich einen Denkfehler? Meiner Meinung nach müsste das jetzt ja ein endloser-Loop sein. Oder nicht?

Liebe Grüsse
Didier
BlackJack

@didier: Der Code auf Modulebene wird nur beim ersten importieren ausgeführt. Jeder weitere Import, egal wo im Programm liefert das bereits importierte Modulobjekt.

Import sollten ausserdem oben im Modul stehen, damit man besser sieht welches Modul von welchen anderen abhängig ist, und die Importe sollten nicht zirkulär sein. Wenn ein Modul ein anderes importiert, sollte das importierte Modus seinerseits nicht wieder das importierende Modul importieren. Weder direkt noch indirekt über weitere Module. Das was da tatsächlich passiert und wann welcher Code tatsächlich ausgeführt wird, ist dabei nur schwer zu überblicken.

Das Importieren von Modulen ist keine sinnvolle Möglichkeit um den Programmablauf zu steuern.

Ein Modul pro Raum erscheint mir auch zu stark aufgeteilt.

Wenn Du das mit einer Funktion pro Raum lösen möchtest, dann könntest Du zum Beispiel jede Raumfunktion die Funktion für den nächsten Raum zurückgeben lassen und im Hauptprogramm dann eine Endlosschleife schreiben (``while True:``) in der immer die aktuelle Funktion aufgerufen wird. Was Du auf keinen Fall machen solltest ist aus einem Raum die Funktion für den nächsten Raum direkt aufrufen, denn das geht nicht endlos gut, weil man damit eine Endlosrekursion hat, die irgendwann zum Programmabruch führt.
didier
User
Beiträge: 11
Registriert: Freitag 18. April 2014, 12:40

Hallo BlackJack
Vielen Dank für Deine ausführliche Antwort. Um das beschriebene Konzept wirklich zu verstehen muss ich mich jetzt allerdings ein paar Tage damit beschäftigen. Vor allem mit der "Wahren"-While-Schleife habe ich noch ein wenig Mühe. :o

Melde mich, wenn ich weitergekommen bin.

Liebe Grüsse
Didier
BlackJack

Hier mal das Problem mit direktem rekursivem Aufruf:

Code: Alles auswählen

#!/usr/bin/env python


def room_a():
    print 'Wir sind in Raum A'
    room_b()


def room_b():
    print 'Wir sind in Raum B'
    room_a()


def main():
    room_a()


if __name__ == '__main__':
    main()
Das gibt zwar schön immer die beiden Texte abwechelnd aus, aber bricht sehr schnell mit einem ``RuntimeError: maximum recursion depth exceeded`` ab.

Während das hier tatsächlich ewig läuft (beziehungsweise bis man es abbricht):

Code: Alles auswählen

#!/usr/bin/env python


def room_a():
    print 'Wir sind in Raum A'
    return room_b


def room_b():
    print 'Wir sind in Raum B'
    return room_a


def main():
    current_room = room_a
    while True:
        current_room = current_room()


if __name__ == '__main__':
    main()
didier
User
Beiträge: 11
Registriert: Freitag 18. April 2014, 12:40

super, danke! Muss mir das in aller Ruhe anschauen.

lg
Didier
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich denke, wenn man wirklich mehrere Räume haben möchte, so kommt man um Listen (und möglicherweise auch um Dictionaries) nicht drum herum! Wie will man man diesem Aufbau aus einem Raum, in mehrere andere wechseln? Klar kann ich das über eine Logik bestimmen, also a la:

Code: Alles auswählen

def room_a():
    print 'Wir sind in Raum A'
    user_choice = input("Welcher Raum als nächstes (B oder C)? "
    return room_b if (user_choice.upper() == 'B') else room_c
Aber das wird zu Kaskaden von ``if...elif...else``-Konstrukten führen; dazu sehe ich zig Code-Duplikate bezüglich der Benutzereingabe und den allgemeinen Ablaufregeln vor meinem geistigen "Anfänger"-Auge...

... ich denke man kommt hier um das Abbilden von Räumen und deren Verbindungen in einer Datenstruktur nicht sinnvoller Weise herum.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
didier
User
Beiträge: 11
Registriert: Freitag 18. April 2014, 12:40

Hallo Hyperion
Genau wegen der Übersichtlichkeit dachte ich als Anfänger (mit Klassen und Dictionaries bin ich noch nicht vertraut) wenn ich die Räume in eigenen Modulen abbilde und bei bedarf aus einem Raum heraus aufrufe, könnte ich ganz bequem und übersichtlich die verschiedenen Räume in getrennten Files bearbeiten und laufen lassen. Denn du hast recht, in den Räumen passiert natürlich was und das wird dann schnell unübersichtlich.

Liebe Grüsse
Didier
Antworten