Seite 1 von 1

Denkblockade

Verfasst: Sonntag 2. April 2023, 15:17
von @nog
Hallo Leute...
ich versuche mir in meiner Freizeit Python beizubringen.
Dabei bin ich auf python-lernen.de gestoßen.

Aber bei dem Hangman-Spiel verstehe ich etwas nicht.
An der Stelle bei x += 1 habe ich so meine Probleme.
Ich weiß was passiert wenn ich das weglasse.
Aber nicht was /wie genau passiert, mit dem hochzählen...
Müsste es nicht immer nur ein Buchstabe weiter nach rechts (einer nach dem anderen) ausgegeben werden?
Stattdessen weiß das Programm direkt wo im Wort der nächste Buchstabe ist der gefunden wurde. (Egal an welcher Position)

Vielleicht findet sich jemand, der sich meiner erbarmt
und mir das so erklären kann, als ob er es einem 5jährigen erklärt :mrgreen:

Code: Alles auswählen

# Weil das Zufallsmodul benötigt wird
import random

# Wörter aus denen das Programm per Zufall auswählen kann
woerter = 'Hund Katze Maus Haus raus'.split()   # .split() wandelt die Zeichenkette in eine Liste um

# aus der woerter-Liste ein zufälliges Wort auswählen
ratewort = random.choice(woerter)

# die erratenen Wörter speichern und zusammen mit den nicht erratenen (die _ ) ausgeben
erraten = []

# die Nutzereingabe
nutzereingabe = ""

# die Versuche das Wort zu erraten begrenzen
fehlversuche = 7

#print(ratewort)

print('"Hangman"')
print()
print("Du hast genau 7 Versuche das gesuchte Wort zu erraten.")
print("Mit der Eingabe bye kannst du das Spiel beenden.")
print()

'''
# für die einzelnen Buchstaben des "ratewortes" nur Unterstriche ausgeben
# zusätzlich soll ein Leerzeichen nach dem Unterstrich kommen, damit es deutlich ist wieviele Buchstaben das "ratewort" hat

# jeden einzelnen Buchstaben im "ratewort" durchlaufen
# zum testen jeden Buchstaben danach mit Leerzeichen ausgeben

# für jede Ausgabe soll ein Unterstrich mit zusätzlichem Leerzeichen ausgegeben werden

# # # nur zum Test! # # #
for buchstaben in ratewort:
    print(buchstaben, " ", end='_') # end='' ->Zeichenkette, die nach dem letzten Wert angehängt wird, standardmäßig ein Zeilenumbruch

# nur die Unterstriche anzeigen lassen, wo ersichtlich wird, wieviele Buchstaben das Ratewort hat
    # quasi für die erste Runde
    for buchstaben in ratewort:
        print("", end='_ ')    
'''
for buchstaben in ratewort:
    erraten.append('_')

# da das Spiel mehrere Runden läuft wird eine Schleife benötigt
while nutzereingabe != "bye":   # der Nutzer kann mit "bye" das Spiel abbrechen
    for ausgabe in erraten:
        print(ausgabe, end=' ') # nur die Unterstriche anzeigen lassen, wo ersichtlich wird, wieviele Buchstaben das Ratewort hat
    print()
    nutzereingabe = input("Dein Vorschlag: ")
    
    # das Ratewort Buchstabe für Buchstabe über eine for-Schleife durchlaufen lassen
    # um zu überprüfen ob der Spieler-Buchstabe vorkommt
    x = 0 # Hilfsvariable um die Position des aktuellen Buchstaben in der Liste zu erkennen
    for buchstaben in ratewort:
        if buchstaben.lower() == nutzereingabe.lower(): # mit .lower() werden alle Eingaben zu Kleinbuchstaben umgewandelt
            print("Treffer!")
            erraten[x] = buchstaben
        x += 1 # damit der erratene Buchstabe an der Position bleibt, wo er hingehört
        '''
        - Mit erraten[x] = buchstaben wird die Stelle x in der Liste erraten mit dem vom Spieler
          eingegebenen Buchstaben ersetzt
        - Lasse ich x += 1 weg, dann kommt der Buchstabe immer an erster Stelle.
          Weil vorher ja X auf 0 gesetzt wurde, sprich an die ERSTE Stelle in der Liste "erraten"
          
        - Wieso wird bei x += 1 der vom Spieler eingegebene Buchstabe, auf die richtige Position
          in der Liste erraten gesetzt?
          Müsste es nicht immer nur ein Buchstabe weiter nach rechts (einer nach dem anderen) ausgegeben werden?
        '''
    print()
    
    # Kontrolle ob gewonnen
    if '_' in erraten:
        fehlversuche -= 1
        if fehlversuche == 0:
            print("Schade - verloren!")
            print("Das gesuchte Wort war:", ratewort)
            break
    else:
        print("Gewonnen! Das gesuchte Wort war:", ratewort)
        break

Re: Denkblockade

Verfasst: Sonntag 2. April 2023, 16:36
von /me
Lassen wir den ganzen Rest rundherum mal weg. Die for-Schleife läuft über jedes Zeichen im Text und erhöht in der Schleife gleichzeitig noch die Variable für den Index um je 1.

Code: Alles auswählen

i = 0 
for buchstabe in 'Python':
    print(f'index {i}: buchstabe {buchstabe}')
    i += 1
Das gibt

Code: Alles auswählen

index 0: buchstabe P
index 1: buchstabe y
index 2: buchstabe t
index 3: buchstabe h
index 4: buchstabe o
index 5: buchstabe n
Die Ausgabe sollte eigentlich klar sein oder gibt es hier noch Verständnisschwierigkeiten?

Normalerweise verwendet man in Python keinen manuell zu aktualisierenden Zähler, sondern verwendet stattdessen `enumerate`:

Code: Alles auswählen

for i, buchstabe in enumerate('Python'):
    print(f'index {i}: buchstabe {buchstabe}')

Re: Denkblockade

Verfasst: Sonntag 2. April 2023, 16:42
von sparrow
@nog: Hier ist einmal irgendwann von jemandem Code gezeigt worden, dass auf einem Tutorial von dort basiert. Ich glaube es war Tic Tac Toe. Er war grottenschlecht. Deshalb von meiner Seite eine klare Warnung von der Seite.

Und auch hier ist das nicht schön gelöst.
Erst fügt er so lange _ am eine Zeichenkette `erraten`an, wie das Lösungswort Buchstaben hat.
Nach einem Rateversuch durchläuft er die Buchstaben des gesetzten Wortes. Der Wert in `x` wird dabei hochgezählt um es als Index auf `erraten` zu verwenden. Stimmt der geratene Buchstabe mit dem Buchstaben im Lösungswort überein, wird der Index in in `erraten` durch den Buchstaben ersetzt.

Die Umsetztung und Namensgebung ist schlecht. Kommt die so aus dem Tutorioal.
`for buchstaben in ratewort:` ist falsch, wein hier keine Buchstaben an den Namen buchstaben gebunden werden sondern _ein_ Buchstabe. Nicht Mehrzahl. Namen sind wichtig. Und deshalb ist `x` auch kein guter Name.

Re: Denkblockade

Verfasst: Sonntag 2. April 2023, 16:47
von Sirius3
›erraten‹ wird etliche Zeilen vor dem Ort, wo es eigentlich gebraucht wird, definiert. Das macht das Verstehen sehr schwierig, weil man große Teile des Programms im Blick haben muß.
`fehlversuche` wird auf 7 gesetzt, im Text taucht die 7 aber nochmal auf, so dass man zwei Stellen im Programm ändern muß, wenn sich an der Anzahl der Versuche etwas ändert.
›nutzereingabe‹ wird mit einem leeren String initialisiert. Das ist ein Problem mit der while-Schleife, weil die nur losläuft, wenn man einer Variable einen Dummy-Wert gegeben hat. Deshalb ist es besser eine while-True-Schleife zu verwenden.
Wenn man "bye" eingibt, wird trotzdem ein Fehlversuch gezählt.
›x‹ ist ein schlechter Name für einen Index. Und so einen Index zählt man auch nicht selbst, sondern benutzt ›enumerate‹.
Zur Frage: es wird ja jeder Buchstabe des Wortes mit Deiner Eingabe verglichen, und die Position des Vergleichs wird parallel dazu gezählt. Deshalb ist auch die Position in ›erraten‹ immer richtig.

Code: Alles auswählen

import random

woerter = 'Hund Katze Maus Haus raus'.split()
ratewort = random.choice(woerter)

fehlversuche = 7

print('"Hangman"')
print()
print(f"Du hast genau {fehlversuche} Versuche das gesuchte Wort zu erraten.")
print("Mit der Eingabe bye kannst du das Spiel beenden.")
print()

erraten = []
for buchstaben in ratewort:
    erraten.append('_')

while True:
    print(" ".join(erraten))
    nutzereingabe = input("Dein Vorschlag: ")
    if nutzereingabe == "bye":
        # der Nutzer kann mit "bye" das Spiel abbrechen
        break
    
    for index, buchstaben in enumerate(ratewort):
        if buchstaben.lower() == nutzereingabe.lower():
            print("Treffer!")
            erraten[index] = buchstaben
    print()
    
    # Kontrolle ob gewonnen
    if "_" in erraten:
        fehlversuche -= 1
        if fehlversuche == 0:
            print("Schade - verloren!")
            print("Das gesuchte Wort war:", ratewort)
            break
    else:
        print("Gewonnen! Das gesuchte Wort war:", ratewort)
        break

Re: Denkblockade

Verfasst: Sonntag 2. April 2023, 17:30
von @nog
Danke für die guten Antworten. *Daumen hoch*

Wegen der Warnung von "Sparrow" das diese Online-Lern-Seite schlecht sei,
habt Ihr da Vorschläge für mich wo ich mich da "besser" bilden kann?

Habe auch vom Rheinwerk Verlag das Buch Let's Code Python gekauft.
Mal sehen wann es da ist^^...

Wünsche euch erstmal einen schönen Abend ;)