Verzweifle an Tic Tac Toe

Fragen zu Tkinter.
Infrared
User
Beiträge: 18
Registriert: Montag 31. August 2009, 16:43

Liebe Member,
Ich hoffe ihr könnt mir da ein wenig weiter helfen.
Ich arbeite bereits seit längerem an einem Tic Tac Toe:

Code: Alles auswählen

#Standarteinstellungen - keine Veraenderungen noetig
#
#



from Tkinter import *
import time

global anzeige
global masterstring
masterstring = " "

def Rechner (master):
    global anzeige
    global B1
    global B2
    global B3
    global B4
    global B5
    global B6
    global B7
    global B8
    global B9




    frame = Frame(master)
    frame.pack()

    frame0 = Frame(frame)
    frame0.pack(side=TOP)

    frame1 = Frame(frame)
    frame1.pack(side=TOP)

    frame2 = Frame(frame)
    frame2.pack(side=TOP)

    frame3 = Frame(frame)
    frame3.pack(side=TOP)
    
    frame4 = Frame(frame)
    frame4.pack(side=TOP) 
    
    frame5 = Frame(frame) 
    frame5.pack(side=TOP)
    
    frame6 = Frame(frame)
    frame6.pack(side=TOP)
    
    frame7 = Frame(frame)
    frame7.pack(side=TOP)
    
    frame8 = Frame (frame)
    frame8.pack(side=RIGHT)
    
    frame9 = Frame (frame)
    frame9.pack(side=LEFT)
    
    frame10 = Frame (frame)
    frame10.pack(side=LEFT)
    
    
    





    B1 = Button(frame1, text="", bg="#F2FFFF", width=10, height=5, borderwidth = 5, command=eins)
    B1.pack(side=LEFT)
    
    B2 = Button(frame1, text=" ", bg="#F2FFFF", width=10, height=5, borderwidth = 5, command=zwei)
    B2.pack(side=LEFT)

    B3 = Button(frame1, text=" ", bg="#F2FFFF", width=10, height=5, borderwidth = 5, command=drei)
    B3.pack(side=LEFT)
    
    B4 = Button(frame2, text=" ", bg="#F2FFFF", width=10, height=5, borderwidth = 5, command=vier)
    B4.pack(side=LEFT)
    
    B5 = Button(frame2, text=" ", bg="#F2FFFF", width=10, height=5, relief="sunken", borderwidth = 5, command=fuenf)
    B5.pack(side=LEFT)
    
    B6 = Button(frame2, text=" ", bg="#F2FFFF", width=10, height=5, borderwidth = 5, command=sechs)
    B6.pack(side=LEFT)
    
    B7 = Button(frame3, text=" ", bg="#F2FFFF", width=10, height=5, borderwidth = 5, command=sieben)
    B7.pack(side=LEFT)

    B8 = Button(frame3, text=" ", bg="#F2FFFF", width=10, height=5, borderwidth = 5, command=acht)
    B8.pack(side=LEFT)

    B9 = Button(frame3, text=" ", bg="#F2FFFF", width=10, height=5, borderwidth = 5, command=neun)
    B9.pack(side=LEFT)
    
    B10 = Button(frame4, text="Spieler 1", width=10, height=5, borderwidth = 5, command=player1)
    B10.pack(side=LEFT)
    
    B11 = Button(frame4, text="Spieler 2", width=10, height=5, borderwidth = 5, command=player2)
    B11.pack(side=LEFT)



def player1():
    player = "X"

def player2():
    player = "O"


global player
player = " "




def eins():
    global B5
    global B6
    B1.configure(text=player, bg="#FF9999")
    
def zwei():
    global B5
    global B6
    B2.configure(text=player, bg="#FF9999")
    
def drei():
    global B5
    global B6
    B3.configure(text=player, bg="#FF9999")
    
def vier():
    global B5
    global B6
    B4.configure(text=player, bg="#FF9999")
    
def fuenf():
    global B5
    global B6
    B5.configure(text=player, bg="#FF9999")

def sechs():
    global B5
    global B6
    B6.configure(text=player, bg="#FF9999")
    
def sieben():
    global B5
    global B6
    B7.configure(text=player, bg="#FF9999")
    
def acht():
    global B5
    global B6
    B8.configure(text=player, bg="#FF9999")
    
def neun():
    global B5
    global B6
    B9.configure(text=player, bg="#FF9999")

#Sonstige Definitionen und Anpassungen
#
#
    
def add_to_string(pWert):
    global masterstring
    global anzeige

    masterstring = masterstring + str(pWert)
    anzeige.configure(text = masterstring)
    print masterstring


root = Tk()
Rechner(root)
root.geometry( '240x300+250+250')
root.mainloop()
So. Ich war in der Hoffnung das durch den Klick auf einen Button er automatisch erkennt, dadurch das man vorher auf Spieler 1 oder 2 klickt ein X bzw. ein O in den Button zu setzen. Das ist mir erst einmal wichtig.
Er brauch erst garnicht erkennen ob man gewonnen oder verloren hat. (Falls es jemand weiß, kann er es natürlich dazuposten :D )
Das Grundgerüst wie es dort ist möchte ich auf jeden Fall beibehalten.
Ich wüsste nur gern was ich falsch gemacht habe oder was ich dafür noch ergänzen muss.

Außerdem wäre es ganz hilfreich nicht dauernt auf Spieler 1 und 2 zu klicken, sondern das der Computer von alleine zwischen X und O wechselt.

Aber wie gesagt: Am wichtigsten ist das die X und O's ersteinmal erscheinen. :)

Schon einmal vielen Dank fürs durchlesen.

Mfg
Infrared
Wer einem eine Bratwurst brät, hat ein Bratwurst-bratgerät !?!

Mfg
Infrared
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Nur fürs Zeitmanagement: Bedeutet "seit längerem" seit dem Informatikunterricht letzte Woche und ist die Hausaufgabe wieder bis Freitag zu erledigen? :P
Das Leben ist wie ein Tennisball.
Infrared
User
Beiträge: 18
Registriert: Montag 31. August 2009, 16:43

was? :?
Wer einem eine Bratwurst brät, hat ein Bratwurst-bratgerät !?!

Mfg
Infrared
Infrared
User
Beiträge: 18
Registriert: Montag 31. August 2009, 16:43

kann mir wirklich keiner helfen
oder kommt "das beste zum schluss" ?
Wer einem eine Bratwurst brät, hat ein Bratwurst-bratgerät !?!

Mfg
Infrared
BlackJack

Ich denke der Knackpunkt dürfte folgender Satz sein: "Das Grundgerüst wie es dort ist möchte ich auf jeden Fall beibehalten."

Da kann Dir wirklich keiner helfen. ;-)
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Um das mal auf den Punkt zu bringen:

Code: Alles auswählen

In [2]: code.count("global")
Out[2]: 33
Daneben ist der Code fuerchterlich redundant.

Das ``global`` in Zeile 114 sollte vor Zeile 111 und 108 stehen. Daneben fehlt die Logik in den "Klick"-Funktionen, um zu erkennen, welcher Spieler aktiv ist.

Sag mal gehoerst du zu http://www.python-forum.de/topic-20047.html und http://www.python-forum.de/topic-20035.html ? Wenn ja schick doch bitte mal deinen Lehrer vorbei. Dieser Programmierstil ist unter aller Sau.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Der Code sollte weiterhelfen ^^

Code: Alles auswählen

import Tkinter as tk
import itertools
import functools

class MTTT(type):
    def __init__(cls, *args, **kwds):
        def fk(b, a, r):
            bt = getattr(b, MTTT.btnmmkr(a, r))
            if b.fld[a,r] not in TTT.PLYS:
                p = b.gplyr()
                bt.configure(text=p)
                b.ntplyr()
                b.fld[a,r] = p
        
        flds = dict(zip(itertools.product(range(cls.SZ), repeat=2),
                    itertools.repeat(" ")))
        [setattr(cls, MTTT.nmmkr(x,y), fk) for x,y in flds]
         
        type.__init__(cls, *args, **kwds)
    
    def __call__(cls, rt, *args, **kwds):
        inst = type.__call__(cls, *args, **kwds)
        
        inst.fld = dict(zip(itertools.product(range(TTT.SZ), repeat=2),
                            itertools.repeat(" ")))
        for (d,o), of in inst.fld.iteritems():
            nm = MTTT.btnmmkr(d, o)
            
            setattr(inst, nm, tk.Button(rt,
                                        text=of,
                                        bg="#F2FFFF",
                                        width=10,
                                        height=5,
                                        borderwidth=5,
                                        command=functools.partial(getattr(inst, MTTT.nmmkr(d, o)), d, o)))
            getattr(inst, nm).grid(row=d,column=o)
            
        inst.plyr = 0
        
        return inst

    @staticmethod
    def nmmkr(a, b):
        nm = ["null", "one", "deux"]
        return "on_%s_%s" % (nm[a], nm[b])
    
    @staticmethod
    def btnmmkr(a, b):
        return "btn_%s" % MTTT.nmmkr(a, b)

class TTT(object):
    __metaclass__ = MTTT
    SZ = 3
    PLYS = ["x", "o"]
    
    def gplyr(self):
        return TTT.PLYS[self.plyr]
    
    def ntplyr(self):
        self.plyr = (self.plyr + 1) % len(TTT.PLYS)


def main():
    root = tk.Tk()
    t = TTT(root)
    root.geometry('350x300+250+250')
    root.mainloop() 

if __name__ == "__main__":
    main()
Das Leben ist wie ein Tennisball.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Die Verwendung von ´´global´´ wird von der Python Community strafrechtlich verfolgt. Auch dein Lehrer muss sich vermutlich auf eine Anzeige wegen Anstiftung zur Verwendung von ´´global´´ einstellen. In der Vergangenheit sind ähnliche Klagen der Community schon sehr erfolgreich gewesen und mit hohen Schadensersatzzahlungen pro ´´global´´-Statement belohnt worden.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Hmm gkuhl bring mich nicht auf dumme Ideen :twisted:

Das Problem ist ganz einfach, dass man gegen Python kaempft, wenn man _so_ ausufernd ``global`` verwendet.

Man schiesst sich damit ziemlich schnell selbst in den Fuss und wenn etwas nicht klappt, werden einfach noch ein paar ``global`` verteilt bis es endlich klappt, statt nach der Loesung zu suchen. Und das sieht man auch im Code vom OP.

@EyDu: Hattest du einen Scherzkeks zum Abendessen? :twisted:
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

cofi hat geschrieben:@EyDu: Hattest du einen Scherzkeks zum Abendessen? :twisted:
Ich musste mich für eine halbe Stunde mal ablenken. Ganz zufrieden bin ich mit meiner Lösung allerdings noch nicht. Anstatt in Zeile 35 die Koordinaten zu übergeben, könnte man auch (natürlich mit REs) aus den Funktionsnamen die Werte schließen.
Das Leben ist wie ein Tennisball.
Infrared
User
Beiträge: 18
Registriert: Montag 31. August 2009, 16:43

gkuhl hat geschrieben:Die Verwendung von ´´global´´ wird von der Python Community strafrechtlich verfolgt. Auch dein Lehrer muss sich vermutlich auf eine Anzeige wegen Anstiftung zur Verwendung von ´´global´´ einstellen. In der Vergangenheit sind ähnliche Klagen der Community schon sehr erfolgreich gewesen und mit hohen Schadensersatzzahlungen pro ´´global´´-Statement belohnt worden.
achso. :roll: Bestimmt irgegndwann mal.


Aber wirklich weiter bin ich mit dem code auf nicht EyDu.
Von mir aus ändert auch das Grundgerüst :D
aber ich komm nicht weiter
Wer einem eine Bratwurst brät, hat ein Bratwurst-bratgerät !?!

Mfg
Infrared
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Infrared hat geschrieben:Von mir aus ändert auch das Grundgerüst :D
aber ich komm nicht weiter
Damit wir qualifiziert weiterhelfen können solltest du uns mitteilen, wie denn überhaupt dein Wissensstand in Bezug auf Programmierung allgemein und Python speziell ist. Bei dem bisherigen Aufbau deines Programms sieht man sehr schnell, dass dir wohl elementare Grundlagen fehlen die du erst einmal verstehen musst.

Gruß,
Matthias
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Schon besser: http://paste.pocoo.org/show/137466/

An der PEP8-Konformität sollte ich noch arbeiten ... :lol:
Das Leben ist wie ein Tennisball.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Infrared

Willkommen in unserm Forum!

Das folgende Skript ist meine Variante des Tic-Tac-Toe's:
http://paste.pocoo.org/show/137516/

Die Spielauswertung muss aber noch programmiert werden!

Viel Spass beim Programmieren mit Python & Tkinter :D

Gruss wuf :wink:
Take it easy Mates!
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Und noch eine Variante. :)
http://paste.pocoo.org/show/137864/

Es fehlen natuerlich Auswertung, KI, Netzwerk...
Laeuft bei mir unter Python 2.6 und 3.1 .

:wink:
yipyip
Infrared
User
Beiträge: 18
Registriert: Montag 31. August 2009, 16:43

schuldigung das ich erst einmal nicht zurück schreiben konnte.
Aber die fertigen scripts und antworten haben mich ein ganzes stück weiter gebracht. danke

:D
Wer einem eine Bratwurst brät, hat ein Bratwurst-bratgerät !?!

Mfg
Infrared
Infrared
User
Beiträge: 18
Registriert: Montag 31. August 2009, 16:43

habe da doch noch eine frage:
wie erkennt python, ob jemand gewonnen hat oder nicht? sprich, wie kann man den inhalt eines buttons auslesen?? :shock:
Wer einem eine Bratwurst brät, hat ein Bratwurst-bratgerät !?!

Mfg
Infrared
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo Infrared

Den Inhalt eines Button-Widgets kannst du auf zwei Arten auslesen:

Code: Alles auswählen

inhalt = button_obj.cget("text")
oder

Code: Alles auswählen

inhalt = button_obj["text"]
Gruss wuf :wink:
Take it easy Mates!
BlackJack

Sollte man aber nicht machen. Die GUI ist nicht dazu da sich Daten zu merken, das sollte man besser in der Programmlogik unabhängig von der GUI machen.
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Wollte eigentlich das Gleiche wie BlackJack sagen...

Hier meine erweiterte Version mit Auswertung:
http://paste.pocoo.org/show/138580/

Fehlen nur noch KI und Netzwerk...

:wink:
yipyip
Antworten