Globale Variablen sollte man nicht verwenden, tust Du eigentlich auch nicht, aber ein Block ganz am Anfang des Programms, mit "Variablen festlegen" ist eigentlich schon falsch. Variablen werden dann initialisiert, wenn man sie braucht, hier also direkt vor der while-Schleife ganz unten.
In `datei_oeffnen_wort_selektieren`: Dateien öffnet man immer mit dem with-Statement und gibt ein Encoding an. Ich bin zuerst darüber gestolpert, dass Du sowohl wort_liste als auch woerter_liste benutzt und ich den Unterschied nicht sofort gesehen habe. In Variablennamen haben Typen nichts verloren.
Über einen Index zu iterieren ist ein Fehler, da man direkt über die Element iterieren kann; der Name `zeichen` ist für einen Index auch falsch.
Code: Alles auswählen
for zeichen in range(0, len(wort) - 1):
wort_liste.append(wort[zeichen])
wird also
oder kurz:
Und später werden wir noch sehen, dass die Liste gar nicht nötig ist. Statt einfach das letzte Zeichen (mutmaßlich des Newline-Zeichen) wegzulassen, benutze rstrip oder strip.
Code: Alles auswählen
def datei_oeffnen_wort_selektieren():
with open("Wörter.txt", encoding="utf8") in input:
woerter = list(input)
wort = random.choice(woerter).lower().strip()
return list(wort)
In `wort_zum_spielen_erstellen`: was soll das _a-Postfix? Bentuze keine Abkürzungen, da man da nur rätseln muß.
Code: Alles auswählen
def wort_zum_spielen_erstellen(loesungswort):
return ["_"] * len(loesungswort))
In `eingabe_wort_in_liste` ist mit den oberen Anmerkungen so trivial, dass es keine eigene Funktion braucht.
Das Hauptprogramm sollte auch in einer Funktion stehen, die man üblicherweise `main` nennt.
Die Schleife ist auch viel zu lang und sollte noch in mehrere Funktionen aufgespalten werden.
Das Flag spielen ist eigentlich unnötig, da man die Schleife als Endlosschleife auch per break verlassen könnte.
Code: Alles auswählen
# Hauptprogramm
def main():
while True:
spiele_runde()
# Abfrage ob weiter gespielt werden soll
weiter_spielen = input("Möchtest du noch eine Runde spielen? J/N ").lower()
print()
print()
if weiter_spielen != "j":
break
Du hast die Bedingung `wort_zum_spielen != loesungswort` in der while-Schleife, was denkst Du liefert die selbe Abfrage beim if gleich drunter?
Der Name `keine_korrekte_eing` hat wieder eine unsinnige Abkürzung. Und auch hier ist das Flag unnötig.
Wenn ein elif das genaue Gegenteil von dem vorher stehenden if-Block ist, benutzt man else.
Die Prüfung, ob nur ascii_letters eingegeben worden sind, ist für den Fall "Ein Zeichen" schon im Fall "Ein Wort" enthalten und muß daher nur einmal im Code stehen. Auch hier gilt wieder bei einer for-Schleife, nicht über einen Index iterieren.
Code: Alles auswählen
def tipp_eingeben():
# Eingabe und Überprüfung der Eingabe
while True:
print()
eingabe = input("Gib einen Buchstaben oder das Lösungswort ein: ").lower()
if eingabe != "":
fehler = 0
# Überprüft den input-String auf Fehler
for zeichen in eingabe:
if zeichen not in string.ascii_letters:
fehler += 1
if fehler == 0:
break
else:
print()
print("Bitte nur Buchstaben oder ganze Wörter eingeben")
return eingabe
Die Schleife kann man noch durch ein isalpha und ein isascii ersetzen, wobei die Frage besteht, ob ein isacii überhaupt gewollt ist.
Code: Alles auswählen
def tipp_eingeben():
# Eingabe und Überprüfung der Eingabe
while True:
print()
eingabe = input("Gib einen Buchstaben oder das Lösungswort ein: ").lower()
if eingabe.isascii() and eingabe.isalpha():
break
print()
print("Bitte nur Buchstaben oder ganze Wörter eingeben")
return eingabe
Das copy ist unnötig, weil Du eingabe_wort gar nicht mehr benötigst, es also unerheblich ist, ob diese Liste nicht verändert wird.
Wenn im if-Block und im else-Block die selbe Funktion gleich zuerst aufgerufen wird, kann man diesen Aufruf auch davor schreiben.
Wenn man sowohl einen Index braucht, als auch die Elemente der Liste, dann benutzt man `enumerate`.
Code: Alles auswählen
def spiele_runde():
versuche = 4
geratene_buchstaben = []
# Zufallswort generieren und Wort mit dem gespielt wird erstellen
loesungswort = datei_oeffnen_wort_selektieren()
wort_zum_spielen = wort_zum_spielen_erstellen(loesungswort)
while versuche > 0 and wort_zum_spielen != loesungswort:
print(" ".join(wort_zum_spielen))
eingabe = tipp_eingeben()
# Überprüfung ob das Wort korrekt ist
if len(eingabe) > 1:
eingabe_wort = list(eingabe)
if eingabe_wort != loesungswort: # Wenn Eingabe nicht richtig ist
versuche -= 1
print(f"Leider falsch, noch {versuche} Versuche")
print()
else:
wort_zum_spielen = eingabe_wort # Übergabe der Liste - für spätere if-Abfrage
# Überprüfung ob der Buchstabe im Lösungswort vorkommt
else: # Wenn eingabe nur ein Zeichen
verschoenerung() # Ausgabe der Sternchen und Zeilenumbruch
if eingabe in loesungswort: # Kontrolle ob Buchstabe vorkommt
for stelle_wort, zeichen in enumerate(loesungswort):
if eingabe == zeichen:
wort_zum_spielen[stelle_wort] = eingabe # Buchstaben an die richtige Stelle schreiben
else:
versuche -= 1 # Versuch wird abgezogen
print(f"{eingabe} kommt nicht vor, noch {versuche} Versuche!!!")
print()
geratene_buchstaben.append(eingabe) # Geratene Buchstaben der Liste hinzufügen
geratene_buchstaben.sort()
print("Benutzte Buchstaben:", " ".join(geratene_buchstaben))
verschoenerung()
# Wenn Wort richtig gratulieren
if wort_zum_spielen == loesungswort:
print(f"Herzlichen Glückwunsch du hast das Wort {''.join(loesungswort)} erraten")
print()
else:
# Wenn keine Versuche mehr Hinweis ausgeben
print("Leider sind alle deine Versuche aufgebraucht!!!")
Wenn man jetzt noch den Code durchgeht und schaut, wo man Listen wirklich braucht, und wo man mit normalen Strings arbeiten könnte, fällt auf, dass nur wort_zum_spielen eine Liste sein muß, weil dort Elemente verändert werden und nur eine Stelle `wort_zum_spielen == loesungswort` diese mit einem String verglichen würde, aber das kann man durch `"_" not in wort_zum_spielen` ersetzen.
Alles in allem sieht das dann so aus:
Code: Alles auswählen
# Hangman Projekt
import random
# Öffnet die Datei und gibt das Lösungswort als Liste zurück
def datei_oeffnen_wort_selektieren():
with open("Wörter.txt", encoding="utf8") in input:
woerter = list(input)
return random.choice(woerter).lower().strip()
# Spielerwort wird erstellt, gibt Liste mit "_" zurück
def wort_zum_spielen_erstellen(loesungswort):
return ["_"] * len(loesungswort)
def verschoenerung():
print("*" * 50)
print()
def tipp_eingeben():
# Eingabe und Überprüfung der Eingabe
while True:
print()
eingabe = input("Gib einen Buchstaben oder das Lösungswort ein: ").lower()
if eingabe.isascii() and eingabe.isalpha():
break
print()
print("Bitte nur Buchstaben oder ganze Wörter eingeben")
return eingabe
def spiele_runde():
versuche = 4
geratene_buchstaben = []
# Zufallswort generieren und Wort mit dem gespielt wird erstellen
loesungswort = datei_oeffnen_wort_selektieren()
wort_zum_spielen = wort_zum_spielen_erstellen(loesungswort)
while versuche > 0 and "_" in wort_zum_spielen:
print(" ".join(wort_zum_spielen))
eingabe = tipp_eingeben()
if len(eingabe) > 1:
# Überprüfung ob das Wort korrekt ist
if eingabe == loesungswort: # Wenn Eingabe nicht richtig ist
break
print(f"Leider falsch, noch {versuche} Versuche")
print()
else:
# Überprüfung ob der Buchstabe im Lösungswort vorkommt
verschoenerung() # Ausgabe der Sternchen und Zeilenumbruch
if eingabe in loesungswort: # Kontrolle ob Buchstabe vorkommt
for stelle_wort, zeichen in enumerate(loesungswort):
if eingabe == zeichen:
wort_zum_spielen[stelle_wort] = eingabe # Buchstaben an die richtige Stelle schreiben
else:
versuche -= 1 # Versuch wird abgezogen
print(f"{eingabe} kommt nicht vor, noch {versuche} Versuche!!!")
print()
geratene_buchstaben.append(eingabe) # Geratene Buchstaben der Liste hinzufügen
geratene_buchstaben.sort()
print("Benutzte Buchstaben:", " ".join(geratene_buchstaben))
verschoenerung()
if versuche == 0:
# Wenn keine Versuche mehr Hinweis ausgeben
print("Leider sind alle deine Versuche aufgebraucht!!!")
else:
# Wenn Wort richtig gratulieren
print(f"Herzlichen Glückwunsch du hast das Wort {loesungswort} erraten")
print()
# Hauptprogramm
def main():
while True:
spiele_runde()
# Abfrage ob weiter gespielt werden soll
weiter_spielen = input("Möchtest du noch eine Runde spielen? J/N ").lower()
print()
print()
if weiter_spielen != "j":
break
if __name__ == '__main__':
main()