Hangman - Anfänger fragt an

Code-Stücke können hier veröffentlicht werden.
Graf Wasserrutsche
User
Beiträge: 37
Registriert: Donnerstag 17. Juli 2008, 06:59
Wohnort: Köln
Kontaktdaten:

Guten Tag zusammen!

Ich bin gänzlich neu in der Pythonwelt und habe mich, nach ein wenig A Byte Of Python und googlen mal daran getraut Hangman zu schreiben. Einige Teile habe ich von der Funktionsweise her aus Codeschnippseln im Internet, doch wüsste ich nun gerne wie man alles optimieren kann, weil ich einige Sachen mit Sicherheit zu umständlich gemacht habe bzw. diese auch anders gehen würen.

Wäre es möglich das ihr euch den Code mal anschaut und mir sagt, was anders, oder auch besser gehen würde? Was für eine Übung könntet ihr mir empfehlen, damit ich von den Basics etwas weg komme?

Vielen Dank schonmal!

Code: Alles auswählen

import random

datei = open('wort.txt', 'r')
var = datei.read()
wort_liste = var.split(" ")
wort = random.choice(wort_liste)

versuche = 5
erraten = ''

print 'Hangman Ver. 0.1'
print
print '1) Spielen'
print '2) Beenden'
print '3) Administration'
print 
i = raw_input('Waehlen Sie: ')

if i == '1':
    versuche = int(versuche)
    while versuche > 0:
        daneben = 0
        for buchstaben in wort:
            if buchstaben in erraten:
                print buchstaben,
            else:
                print '_',
                daneben += 1
            
        if daneben == 0:
            print
            print 'Sie haben gewonnen!'
            nochmal = raw_input('Moechten Sie noch einmal spielen? (j/n)')
            if nochmal == 'j':
                versuche = 5
                erraten = ''
                datei = open('wort.txt', 'r')
                var = datei.read()
                wort_liste = var.split(" ")
                wort = random.choice(wort_liste)
            else:
                break
    
        print    
        raten = raw_input('Bitte geben Sie einen Buchstaben ein:')
    
        if len(raten) > 1:
            raten = raw_input('Bitte geben Sie einen EINZELNEN Buchstaben ein:')
        else:
            erraten += raten

        if raten not in wort:
            versuche -= 1
            print 'Dieser Buchstabe ist nicht vorhanden'
            if versuche == 0:
                print
                print 'Sie haben verloren!'
                print
                nochmal = raw_input('Moechten Sie noch einmal spielen? (j/n)')
                if nochmal == 'j':
                    versuche = 5
                    erraten = ''
                    wort = random.choice(wort_liste)
                    datei = open('wort.txt', 'r')
                    var = datei.read()
                    wort_liste = var.split(" ")
                    wort = random.choice(wort_liste)
elif i == '3':
    print
    print 'Herzlich Willkommen in der Administration!'
    print
    print 'Welche Werte moechten Sie veraendern?'
    print
    print '1) Wort der Wortliste hinzufuegen'
    print '2) Wort aus der Wortliste loeschen'
    print 
    t = raw_input('Waehlen Sie: ')
             
    if t == '1':
        print
        var = raw_input('Welches Wort moechten Sie hinzufuegen? ')
        datei = open('wort.txt', 'a')
        datei.writelines(' '+var)
    elif t == '2':
        print
        datei = open('wort.txt', 'r')
        gesamt = datei.read()
        print gesamt
        print
        var = raw_input('Welches Wort moechten Sie loeschen? ')
        if var in gesamt:
            gesamt = gesamt.replace(var+' ', '')
            print gesamt
        datei = open('wort.txt', 'w')
        datei.write(gesamt)
        print 'Wort wurde geloescht'
BlackJack

Ein zu grosser Haufen Quelltext und alles auf Modulebene. Das sollte in sinnvoll aufgeteilten Funktionen verschwinden.

Man sollte keinen Quelltext unnötig wiederholen. So etwas kann schnell auseinanderlaufen, wenn man etwas ändert, weil man immer daran denken muss die Änderungen überall im Programm zu machen.

Ich sehe kein einziges `datei.close()` -- Dateien, die man öffnet, sollte man auch wieder schliessen.
Graf Wasserrutsche
User
Beiträge: 37
Registriert: Donnerstag 17. Juli 2008, 06:59
Wohnort: Köln
Kontaktdaten:

BlackJack hat geschrieben:Ein zu grosser Haufen Quelltext und alles auf Modulebene. Das sollte in sinnvoll aufgeteilten Funktionen verschwinden.

Man sollte keinen Quelltext unnötig wiederholen. So etwas kann schnell auseinanderlaufen, wenn man etwas ändert, weil man immer daran denken muss die Änderungen überall im Programm zu machen.

Ich sehe kein einziges `datei.close()` -- Dateien, die man öffnet, sollte man auch wieder schliessen.
Welche Zeilen könnte ich denn sinnvoll in Funktionen unterbringen? Das Auslesen der Textdatei z.B.?

An das datei.close() werde ich mich in Zukunft halten.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Graf Wasserrutsche hat geschrieben:
BlackJack hat geschrieben: Welche Zeilen könnte ich denn sinnvoll in Funktionen unterbringen? Das Auslesen der Textdatei z.B.?
Naja, Du kannst da sehr generisch vorgehen! z.B. das "Raten" als solches. Wieso nicht in eine funtkion "raten()"? Ähnlich kannst Du bei der restlichen Funktionalität vorgehen.
Graf Wasserrutsche
User
Beiträge: 37
Registriert: Donnerstag 17. Juli 2008, 06:59
Wohnort: Köln
Kontaktdaten:

So, ich habe jetzt einige kleinere Teile des Codes in Funktionen untergebracht, nur rätsel ich immernoch, wie ich die Funktion raten() an sich schreiben soll, damit das Konzept, wie ich es bis jetzt verwende erhalten bleibt.

Oder wäre es eher angebracht, die Funktion bzw. die Funktionalität komplett neu zu schreiben?

Hier der neue Code:

Code: Alles auswählen

import random

versuche = 5
erraten = ''

print 'Hangman Ver. 0.1\n'
print '1) Spielen'
print '2) Beenden'
print '3) Administration\n'

i = raw_input('Waehlen Sie: ')

def zufall():
    datei = open('wort.txt', 'r')
    var = datei.read()
    wort_liste = var.split(" ")
    wort = random.choice(wort_liste)
    datei.close()
    return wort

def wort_add(var):
    datei = open('wort.txt', 'a')
    datei.writelines(' '+var)
    datei.close()
    print 'Wort wurde hinzugefuegt!'
    
def wort_del(var):
    datei = open('wort.txt', 'r')
    gesamt = datei.read()
    if var in gesamt:
        gesamt = gesamt.replace(var+' ', '')
    else:
        print 'Wort ist nicht vorhanden!'
    datei = open('wort.txt', 'w')
    datei.write(gesamt)
    datei.close()
    print 'Wort wurde geloescht'    

if i == '1':
    wort = zufall()
    while int(versuche) > 0:
        daneben = 0
        for buchstaben in wort:
            if buchstaben in erraten:
                print buchstaben,
            else:
                print '_',
                daneben += 1
            
        if daneben == 0:
            print '\nSie haben gewonnen!'
            nochmal = raw_input('Moechten Sie noch einmal spielen? (j/n)')
            if nochmal == 'j':                
                wort = zufall()
            else:
                break
    
        print    
        raten = raw_input('Bitte geben Sie einen Buchstaben ein:')
    
        if len(raten) > 1:
            raten = raw_input('Bitte geben Sie einen EINZELNEN Buchstaben ein:')
        else:
            erraten += raten

        if raten not in wort:
            versuche -= 1
            print 'Dieser Buchstabe ist nicht vorhanden'
            if versuche == 0:
                print '\nSie haben verloren!\n'
                nochmal = raw_input('Moechten Sie noch einmal spielen? (j/n)')
                if nochmal == 'j':
                    versuche, erraten = eigenschaften()
                    wort = zufall()
elif i == '3':
    print '\nHerzlich Willkommen in der Administration!\n'
    print 'Welche Werte moechten Sie veraendern?\n'
    print '1) Wort der Wortliste hinzufuegen'
    print '2) Wort aus der Wortliste loeschen\n'
    t = raw_input('Waehlen Sie: ')
             
    if t == '1':
        wort_add(raw_input('\nWelches Wort moechten Sie hinzufuegen?'))
    elif t == '2':
        wort_del(raw_input('\nWelches Wort moechten Sie loeschen?\n'))
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Also ganz zu Beginn ist Deine Funktion zufall() wenig performant. Du lädst Die Datei ja zig mal! Da Du aber eh alle Wörter im Speicher hältst, lies die Daten einmal ein und merke Dir die Worte in einer List!

Dann reicht es später folgendes aus (ungestet):

Code: Alles auswählen

from random import shuffle

# list later from file
words = ["some", "different", "words", ...]

def get_rand_word(words):
    shuffle(words)
    return words.pop()
Nun zum Raten: Wie genau ist der Ablauf? Skizziere ihn dir mal einfach so. (zufälliges wort ermitteln, Buchstaben eingeben usw)

Ich denke in der Raten-Funtkion sollte es wohl eine Schleife geben, in der die Verusche abgehandelt werden. Die Eingabe eines Buchstabens würde ich in eine separate Funktion auslagern, um besser auf Fehleingaben reagieren zu können. Naja, dann fehlt noch die Auswertung. Das wäre wohl sicher Code, der in der raten()-Funktion stehen sollte.

Ich hoffe das bringt Dich weiter.
Graf Wasserrutsche
User
Beiträge: 37
Registriert: Donnerstag 17. Juli 2008, 06:59
Wohnort: Köln
Kontaktdaten:

So, lieber ultra spät als nie :)

Also, habe das jetzt mit Hilfe der Tipps so umgestrickt bzw. neu geschrieben. Einige Funktionen wie das Menü, oder Reaktionen auf die Eingabe sind noch nicht drin, wollte nur fragen ob ich das Prinzip jetzt besser verstanden habe bzw. das Ergebnis ein besseres ist?

Code: Alles auswählen

from random import shuffle

datei = open('wort.txt', 'r')
var = datei.read()
words = var.split(" ")
datei.close()

def get_words(words):
    shuffle(words)
    return words.pop()

def input_char():
    char = raw_input("\nBitte geben Sie einen Buchstaben ein:")
    return char

def output_word(wort, wortliste, daneben):
    for stelle in wort:
        if stelle in wortliste:
            print stelle,
        else:
            print "_",
            daneben += 1
    return daneben

def guess_char(wortliste, versuche, fehler):
    wort = get_words(words)
    
    while fehler < versuche:
        char = input_char()
        daneben = 0  
        
        if char in wort:
            print "Dieser Buchstabe ist richtig!"
            if char not in wortliste:
                wortliste += char
                if output_word(wort, wortliste, daneben) == 0:
                    print "\nSie haben das Wort erraten!"
                    break
            else:
                print "Dieser Buchstabe ist schon vorhanden!"     
        else:
            print "Dieser Buchstabe ist falsch!"
            fehler += 1        
              
guess_char('', 5, 0)
[url=http://myspace.com/deathmetalvictory][myspace][/url][url=http://grunzgewitter.blogspot.com][blog][/url][url=http://twitter.com/AgatheBauer][twitter][/url]
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Auf jeden Fall schonmal besser als der erste Code ...

Die Funktionen get_words() und input_char() würde ich mir sparen.
Da es genügt, einmal shuffle() aufzurufen (und nicht bei jedem Holen eines Wortes erneut), könnte man das direkt nach dem Laden aus der Datei machen. Dann wäre get_words() (besser wäre auch: get_word()) funktional identisch mit words.pop() und das kannst du dann auch gleich so verwenden.

Entsprechendes gilt für input_char(). Es ist funktional identisch mit raw_input(), also kannst du es auch gleich dabei belassen.
Graf Wasserrutsche
User
Beiträge: 37
Registriert: Donnerstag 17. Juli 2008, 06:59
Wohnort: Köln
Kontaktdaten:

So, die Funktion get_words() habe ich jetzt ganz normal in den Code eingefügt, das konnte ich nachvollziehen.

Der Übersichtlichkeit halber und auf Grund des Tipps von Hyperion habe ich die input_chars() dennoch als Funktion außerhalb gelassen, um auf Fehleingaben zu reagieren.

Die Länge der Variable ist ja kein Problem, nur weiß ich nicht wie man z.B. die Groß- und Kleinschreibung unterscheiden kann. Gibt es da eine extra Funktion für? Und gibt es eine Möglichkeit meine bisherige Fallunterscheidung noch einfacher zu schreiben?

Ich entschuldige mich jetzt schonmal für die ganzen blöden Fragen :)

Code: Alles auswählen

from random import shuffle

datei = open('wort.txt', 'r')
var = datei.read()
words = var.split(" ")
datei.close()

def input_char(char):    
    if len(char) > 1:
        char = raw_input('Bitte geben Sie einen EINZELNEN Buchstaben ein:')
    elif char == '':
        char = raw_input('Bitte geben Sie einen Buchstaben ein:')     
    return char 

def output_word(wort, wortliste, daneben):
    for stelle in wort:
        if stelle in wortliste:
            print stelle,
        else:
            print "_",
            daneben += 1
    return daneben

def guess_char(wortliste, versuche, fehler, words):   
    shuffle(words)
    wort = words.pop()
    while fehler < versuche:
        char = input_char(raw_input('\nBitte geben Sie einen Buchstaben ein:'))
        daneben = 0  
        
        if char in wort:
            print "Dieser Buchstabe ist richtig!"
            if char not in wortliste:
                wortliste += char
                if output_word(wort, wortliste, daneben) == 0:
                    print "\nSie haben das Wort erraten!"
                    break
            else:
                print "Dieser Buchstabe ist schon vorhanden!"     
        else:
            print "Dieser Buchstabe ist falsch!"
            fehler += 1
            if fehler == 5:
                print "\nSie haben verloren!"      
              
guess_char('', 5, 0, words)
[url=http://myspace.com/deathmetalvictory][myspace][/url][url=http://grunzgewitter.blogspot.com][blog][/url][url=http://twitter.com/AgatheBauer][twitter][/url]
BlackJack

`wortliste` ist ja wohl eher eine Buchstabenliste. Aber man sollte in vielen Fällen den Datentyp aus dem Namen heraus halten. Effizienter wäre es nämlich ein `set` zu verwenden und dann hätte man ein `set` das an einen Namen gebunden ist, der "liste" enthält. Das ist verwirrend.

Dann solltest Du Dir mal Deine Argunentlisten anschauen. Du übergibst da teilweise Werte von aussen, die eigentlich als Argumente keinen Sinn machen. Gibt es Gründe warum jemand etwas anderes als 0 für `daneben` in `output_word()` oder '' und 0 für `wortliste` und `fehler` in `guess_char()` übergeben sollte? Warum kann man das tun?

`guess_char()` müsste von der Semantik her `guess_chars()` heissen, weil man ja nicht nur einen, sondern alle Buchstaben damit raten kann.

`input_char()` sollte wirklich die komplette Eingabe übernehmen und nicht schon eine Eingabe bekommen, ausserdem wäre es sinnvoller, wenn die Funktion *wirklich* sicherstellen würde, dass nur ein einzelner Buchstabe eingegeben werden kann. So kann man die Nachfrage ja immer noch falsch beantworten.

Es gibt noch eine hart kodierte 5 die durch `versuche` ersetzt werden sollte.

Mit der Gross- und Kleinschreibung würde ich so verfahren, dass sowohl die Worte als auch die Eingaben konsequent in Gross- oder Kleinbuchstaben umgewandelt werden. Da gibt's Methoden auf Zeichenketten für.
Graf Wasserrutsche
User
Beiträge: 37
Registriert: Donnerstag 17. Juli 2008, 06:59
Wohnort: Köln
Kontaktdaten:

So, Vorschläge angenommen und umgesetzt :)

Bezüglich der String-Methoden habe ich noch eine Frage.

Entweder ich habe es übersehen, oder bin zu dumm, aber ich habe in der Referenz keine Methode gefunden die einfach alle Buchstaben in Kleinbuchstaben umwandelt.
Nur eine die alles in Großbuchstaben umwandelt und eine, die immer in die umgekehrte Größe umwandelt.

Stimmt das, oder gibt es noch eine extra für Kleinschreibung?

Habt ihr noch Ideen, welche Funktionen in das Spiel eingebaut werden könnten, oder wie einige Passagen verbessert bzw. vereinfacht werden könnten?

Code: Alles auswählen

from random import shuffle

datei = open('wort.txt', 'r')
var = datei.read()
words = var.split(" ")
datei.close()

def hangman_show(a, b):
    hangman = ["-----", "|/  |", "|   o  ", "|  \O/  ", "|  / \   "]
    for i in range(a, b):
        print hangman[i]

def input_char():  
    char = raw_input('\nBitte geben Sie einen Buchstaben ein:')   
    while len(char) > 1 or char == '':
        char = raw_input('Bitte geben Sie einen EINZELNEN Buchstaben ein:') 
    char = char.upper()
    return char.swapcase()

def output_word(wort, buchstaben):
    daneben = 0
    for stelle in wort:
        if stelle in buchstaben:
            print stelle,
        else:
            print "_",
            daneben += 1
    return daneben

def guess_chars(versuche, words):   
    shuffle(words)
    wort = words.pop()
    fehler = 0
    buchstaben = ''
    while fehler < versuche:
        char = input_char() 
        
        if char in wort:
            print 'Dieser Buchstabe ist richtig!'
            if char not in buchstaben:
                buchstaben += char
                if output_word(wort, buchstaben) == 0:
                    print '\nSie haben das Wort erraten!'
                    break
            else:
                print 'Dieser Buchstabe ist schon vorhanden!'     
        else:
            print 'Dieser Buchstabe ist falsch!'
            hangman_show(0,fehler+1)
            fehler += 1
            if fehler == versuche:
                print '\nSie haben verloren!'      

nochmal = ''    
while nochmal == 'j':
    guess_chars(5, words)
    nochmal = raw_input('Wollen Sie noch einmal spielen? (j/n)')
[url=http://myspace.com/deathmetalvictory][myspace][/url][url=http://grunzgewitter.blogspot.com][blog][/url][url=http://twitter.com/AgatheBauer][twitter][/url]
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Graf Wasserrutsche hat geschrieben: Bezüglich der String-Methoden habe ich noch eine Frage.

Entweder ich habe es übersehen, oder bin zu dumm, aber ich habe in der Referenz keine Methode gefunden die einfach alle Buchstaben in Kleinbuchstaben umwandelt.
Die Doku ist an der Stelle etwas irreführend. Alle Methoden, die du auf Strings anwenden kannst, finden sich unter 3.6.1 "String-methods".
EDIT: Die gesuchte Methode heißt wenig überraschend lower().
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Na, wir mag wohl das gegenteil von upper heissen?

Code: Alles auswählen

>>> "Hallo Welt".lower()
'hallo welt'
Falls du nochmal was suchtst: dir("sdf"), dir(str), help(str)
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Graf Wasserrutsche
User
Beiträge: 37
Registriert: Donnerstag 17. Juli 2008, 06:59
Wohnort: Köln
Kontaktdaten:

Rebecca hat geschrieben:Na, wir mag wohl das gegenteil von upper heissen?

Code: Alles auswählen

>>> "Hallo Welt".lower()
'hallo welt'
Falls du nochmal was suchtst: dir("sdf"), dir(str), help(str)
Oh, okay -_-

Danke.
[url=http://myspace.com/deathmetalvictory][myspace][/url][url=http://grunzgewitter.blogspot.com][blog][/url][url=http://twitter.com/AgatheBauer][twitter][/url]
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

hallo!

hier noch ein kleines beispiel, das (hoffentlich) so in ordnung ist.
es funktioniert auf jeden fall.

hangmann.py:
http://paste.pocoo.org/show/87793/
data.py (wenn man spielen will, bitte vorerst nicht reinschauen!):
http://paste.pocoo.org/show/87797/

ich hoffe, das ist hilfreich.

mfg
roschi

PS: auch wenn dieser thread schon eine weile nicht mehr beposted wurde, vielleicht hilft es ja doch jemandem.
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
BlackJack

@roschi: Es gibt `random.choice()`. Oder `random.shuffle()` und dann eine Schleife über die Worte, damit bei einem Programmlauf nichts doppelt vorkommt.

Das Leerzeichen am Ende von `guess_state` könnte man auch einfach entfernen, dann braucht man es nicht im Folgenden überall besonders behandeln. Oder man schreibt das Programm gleich so, dass das gar nicht erst angehängt wird. Zum Beispiel so:

Code: Alles auswählen

    guess_state = ' '.join('-' * len(w) for w in word.split())
Wobei `word` für etwas, das auch ein ganzer Satz sein kann, ein nicht so passender Name ist.

Als Verbesserungsvorschlag: `guess_state` aus dem gesuchten Wort bzw. Satz bilden, in dem alle Buchstaben durch Unterstriche ersetzt werden und alles andere aus dem Wort oder Satz übernommen wird. So kann man auch Satzzeichen und Bindestriche zum Raten verwenden. Zum Beispiel 'Tim Berners-Lee' in der Rubrik Internetpersönlichkeiten oder "O'Reilly" bei Verlagen.

Die magische 6 sollte aus der Anzahl der Bilder bestimmt werden.

Und Funktionen sind eine praktische Sache um Quelltext in handliche Einzelteile zu zerlegen.
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

hallo!

danke fuer die vorschlaege, BlackJack!
ich habe den code verbessert, und hoffe, dass ich nichts vergessen habe :)

hangmann.py: http://paste.pocoo.org/show/88183/
data.py: http://paste.pocoo.org/show/88184/

:D

mfg
roschi

PS:
pylint gibt mir 9,19/10 Punkte. es meckert etwas, weil ich keine doc-strings habe, aber sonst scheint alles okay zu sein.

[edit]noch ein paar typos ausgebessert[/edit]
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Hangman mit GUI...
Nicht sauberste Programmierung, dafür wars eines meiner ersten Programme ;-)

Code: Alles auswählen

from turtle import *
from Tkinter import *
from random import *
from tkMessageBox import *

class Hangman:
    def __init__(self, w):
        self.woerter = w

        self.such_wort = self.wort()

        self.l = []
        num = 0
        self.fake = 0
        self.r = 0

        self.win = Tk()
        self.win.title("Hangman")

        self.word_frame = Frame(self.win)
        self.cv_frame = Frame(self.win)

        self.word_frame.pack()
        self.cv_frame.pack()

        for i in self.such_wort:
            if i == "-":
                self.l.append(Label(self.word_frame, text="-"))
            elif i == " ":
                self.l.append(Label(self.word_frame, text=" "))
            else:
                self.l.append(Label(self.word_frame, text="_"))
            self.l[num].c = i
            self.l[num].pack(side =LEFT)
            num += 1

        self.cv = Canvas(self.cv_frame, width=250, height=300, bg="gray")
        self.cv.pack()

        self.pen = RawPen(self.cv)                                  # Galgen
        self.pen.width(2)
        self.pen.tracer(0)

        self.win.bind("<Any-KeyPress>", self.key)

        self.win.mainloop()

    def wort(self):
        return choice(self.woerter)

    def key(self, event):
        c = event.char

        x = 0

        if c.upper() in self.such_wort:
            for i in self.l:
                if i.c == c.upper():# or i.c == c or i.c == c:
                    i.config(text=i.c)
                    self.r += 1
        else:
            x = 1

        if c.lower() in self.such_wort:
            for i in self.l:
                if i.c == c.lower():# or i.c == c or i.c == c:
                    i.config(text=i.c)
                    self.r += 1
        else:
            x += 1

        if x == 2:
            self.fake += 1
            self.draw()

        if self.r == len(self.such_wort):
            showinfo("Hang-Man", "Gewonnen!")

    def draw(self):
        if self.fake == 1:
            self.staender_1()
        elif self.fake == 2:
            self.staender_2()
        elif self.fake == 3:
            self.senk_stab_3()
        elif self.fake == 4:
            self.wag_stab_4()
        elif self.fake == 5:
            self.dia_stab_5()
        elif self.fake == 6:
            self.senk_stab_6()
        elif self.fake == 7:
            self.kopf_7()
        elif self.fake == 8:
            self.koerper_8()
        elif self.fake == 9:
            self.arm_l_9()
        elif self.fake == 10:
            self.arm_r_10()
        elif self.fake == 11:
            self.bein_l_11()
        elif self.fake == 12:
            self.bein_r_12()
            for i in self.l:
                i.config(text=i.c)
            showinfo("Hang-Man", "Aufgehangen!")

    def staender_1(self):
        self.pen.up()
        self.pen.goto(-100, -130)
        self.pen.down()
        self.pen.goto(-60, -80)

    def staender_2(self):
        self.pen.goto(-20, -130)

    def senk_stab_3(self):
        self.pen.goto(-60, -80)
        self.pen.goto(-60, 50)

    def wag_stab_4(self):
        self.pen.goto(20, 50)

    def dia_stab_5(self):
        self.pen.up()
        self.pen.goto(-30, 50)
        self.pen.down()
        self.pen.goto(-60, 10)

    def senk_stab_6(self):
        self.pen.up()
        self.pen.goto(20, 50)
        self.pen.down()
        self.pen.goto(20, 30)

    def kopf_7(self):
        self.pen.circle(-15)

    def koerper_8(self):
        self.pen.up()
        self.pen.goto(20, 0)
        self.pen.down()
        self.pen.goto(20, -70)

    def arm_l_9(self):
        self.pen.up()
        self.pen.goto(20, -20)
        self.pen.down()
        self.pen.goto(-10, -40)

    def arm_r_10(self):
        self.pen.up()
        self.pen.goto(20, -20)
        self.pen.down()
        self.pen.goto(50, -40)

    def bein_l_11(self):
        self.pen.up()
        self.pen.goto(20, -70)
        self.pen.down()
        self.pen.goto(0, -100)

    def bein_r_12(self):
        self.pen.up()
        self.pen.goto(20, -70)
        self.pen.down()
        self.pen.goto(40, -100)
            
w = ["Keks",
              "Schildkroete",
              "Kirchturm",
              "Zirkuswagen",
              "Hausstaub",
              "Giraffenkaefig",
              "Schaukelpferd",
              "Regenwaldvernichtung",
              "Forellen schmecken gut",
              "Pfuetze",
              "Mueller",
              "Mausefalle",
              "Pfefferkuchenhaeuschen",
              "Christbaum",
              "Ostereier verstecken und suchen",
              "Schornsteinfeger"
     ]

h = Hangman(w)
@roschi: ich hab mal deine Wörter benutzt^^
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hua ... das sieht ... grausam aus ;-)

Also mal im Ernst:
- keine Trennung von GUI und Funktionalität (ok, bei nem kleinen Projekt könnte man darüber hinwegsehen)

- sonderbare Klasseneinteilung und vor allem "Missbrauch" des Konstruktors (dann doch eher __cal__(self, ...))

- die draw-Methode ist wenig übersichtlich

- was folgt ist auch ziemlich unübersichtlich. Dort könnte man mit einer wohldefinierten Datenstruktur des "Hangmans" wesentlich besseren Code schreiben (kürzer, übersichtlicher und leichter anpassbar)

Tja, so viel auf die Schnelle.

Ich weiß ja nicht, was vorher im Thread zu als Tipps gegeben worden ist, aber das hier sieht mir nicht nach Fortschritt aus :-D
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Hyperion hat geschrieben:Hua ... das sieht ... grausam aus ;-)

Also mal im Ernst:
- keine Trennung von GUI und Funktionalität (ok, bei nem kleinen Projekt könnte man darüber hinwegsehen)

- sonderbare Klasseneinteilung und vor allem "Missbrauch" des Konstruktors (dann doch eher __cal__(self, ...))

- die draw-Methode ist wenig übersichtlich

- was folgt ist auch ziemlich unübersichtlich. Dort könnte man mit einer wohldefinierten Datenstruktur des "Hangmans" wesentlich besseren Code schreiben (kürzer, übersichtlicher und leichter anpassbar)

Tja, so viel auf die Schnelle.

Ich weiß ja nicht, was vorher im Thread zu als Tipps gegeben worden ist, aber das hier sieht mir nicht nach Fortschritt aus :-D
Ich habe selber schon bemerkt, dass der Quellcode ein Chaos ist, aber ich habe das Teil auch schon vor ~1 Jahr geschrieben^^

mfg
Antworten