Pokerspiel

Fragen zu Tkinter.
Antworten
Benutzeravatar
Arthur
User
Beiträge: 23
Registriert: Sonntag 12. November 2006, 18:07

ich hab angefangen ein Pokerspiel zu programmieren, jedoch nur mit Tkinter und ohne pygame.

das is der Code den bisher zusammenhab:

Code: Alles auswählen

from Tkinter import*

class Karten:
    def __init__(self, canvas):
        canvas.create_rectangle(9,9,109,159,fill='#FFFFFF', outline='#000000')
        canvas.create_rectangle(119,9,219,159,fill='#FFFFFF', outline='#000000')
        canvas.create_rectangle(229,9,329,159,fill='#FFFFFF', outline='#000000')
        canvas.create_rectangle(339,9,439,159,fill='#FFFFFF', outline='#000000')
        canvas.create_rectangle(449,9,549,159,fill='#FFFFFF', outline='#000000')
        canvas.create_rectangle(175,169,275,319,fill='#FFFFFF', outline='#000000')
        canvas.create_rectangle(285,169,385,319,fill='#FFFFFF', outline='#000000')

class Money:                                              #giebt die Informationen über blinds und einsatz
    def __init__(self, master, canvas, m, e, bb):
        self.einsatz=canvas.create_text(450,200,text='Einsatz: '+ str(e)+ ' Schlotties', fill='#FFFF00')
        self.bigblind=canvas.create_text(80, 210, text='Bigblind: ' + str(bb) + ' Schlotties', fill='#FFFF00')
        self.smallblind=canvas.create_text(80, 190, text='Smallblind: ' + str(bb/2) + ' Schlotties', fill='#FFFF00')
        self.konto=Label(master, text='Konto: '+ str(m) +' Schlotties', fg='#FFFF00', bg='#000050')
        self.konto.grid(column=6, row=2)
    def destroy(self, canvas):
        self.konto.destroy()
        canvas.delete(self.einsatz)
        canvas.delete(self.bigblind)
        canvas.delete(self.smallblind)        

class Quitfrage:
    def __init__(self, master):
        self.top=Toplevel(master)
        self.frage=Label(self.top, text='Wollen sie das Spiel\nwirklich beenden?', font='Arial 10')
        self.frage.grid(row=0, column=0, columnspan=2)
        self.ja=Button(self.top, text='JA', command=root.destroy)
        self.ja.grid(row=1, column=0)
        self.nein=Button(self.top, text='NEIN', command=self.top.destroy)
        self.nein.grid(row=1, column=1)
        

class Gui:
    def __init__(self, master):
        mp=2000
        mk=mp
        e=0
        bb=50
        def raiseP(e, mp):        #<------
            if self.raiseE.get()=='':
                r=0                  #********
            else:
                r=int(self.raiseE.get())
            e=e+r
            mp=mp-r
            self.money.destroy(self.kartentisch)
            self.money=Money(self.frame, self.kartentisch, mp, e, bb)
        def callP():
            pass
        def checkP():
            p='c'
        def foldP():
            pass
        def shureC():
            self.shureT=Quitfrage(master)            
        self.frame=Frame(master, bg='#000050')
        self.frame.grid()
        self.kartentisch=Canvas(self.frame, bg='#002F20', width=560, height=330, borderwidth=1, relief=SOLID)
        self.kartentisch.grid(column=0, row=1, columnspan=8)
        self.karten=Karten(self.kartentisch)
        self.money=Money(self.frame, self.kartentisch, mp, e, bb)
        self.raiseE=Entry(self.frame, justify=RIGHT)
        self.raiseE.grid(column=1, row=2)
        self.raiseB=Button(self.frame, text='Raise!', command=raiseP(e, mp))
        self.raiseB.grid(column=2, row=2)
        self.callB=Button(self.frame, text='Call!', command=callP)
        self.callB.grid(column=3, row=2)
        self.checkB=Button(self.frame, text='Check!', command=checkP)
        self.checkB.grid(column=4, row=2)
        self.foldB=Button(self.frame, text='Fold!', command=foldP)
        self.foldB.grid(column=5, row=2)
        self.quitB=Button(self.frame, text='Quit', command=shureC)
        self.quitB.grid(column=7, row=2)


root=Tk()
root.title('Poker')
game=Gui(root)
root.mainloop
momentan versuche ich eine möglichkeit zu finden wie ich den einsatz erhöhen kann. dafür die funktion raiseP (bei <-----).
Am Anfang habe ich eine klasse Money kontruiert. um sie dann zu aktualisiern lösche ich sie zu erst und ertelle sie dann neu mit aktuellen Parametern.

das problem ist er scheint die funktion schon einmal auszufüren wenn ich das programm starte denn wenn ich bei ******* für r zb 17 einsetze steht der einsatz (e) von anfang an auf 17 und nicht 0. auch führt er die funktion nicht erneut aus wenn ich eine zahl bei raiseE eingebe und auf den Button klicke.
ist das ein grundsätzlicher gedanken/aufbau fehler oder hab ich irgendwo einfach nur was verdreht.

schon mal danke


Arthur
BlackJack

Arthur hat geschrieben:das problem ist er scheint die funktion schon einmal auszufüren wenn ich das programm starte denn wenn ich bei ******* für r zb 17 einsetze steht der einsatz (e) von anfang an auf 17 und nicht 0. auch führt er die funktion nicht erneut aus wenn ich eine zahl bei raiseE eingebe und auf den Button klicke.
ist das ein grundsätzlicher gedanken/aufbau fehler oder hab ich irgendwo einfach nur was verdreht.
In Zeile 68 führst Du die Funktion aus. Und an `command` wird der Rückgabewert der Funktion gebunden, das ist `None`. Darum passiert auch nichts wenn Du den Button drückst.

Grundsätzlich ist es immer eine gute Idee Programmlogik und GUI zu trennen. Ich würde das Pokerspiel erst einmal ohne GUI implementieren. Dann lässt es sich auch isoliert testen und man kann sich später die GUI aussuchen, auswechseln oder sogar mehrere anbieten.
Benutzeravatar
Arthur
User
Beiträge: 23
Registriert: Sonntag 12. November 2006, 18:07

wieso ist der rückgabe wert 'None'?

die Funktion shureC in Zeile 58 funzt doch auch ohne probelme

ich sehe da kein sonderlichen unterschied :(
BlackJack

Arthur hat geschrieben:wieso ist der rückgabe wert 'None'?
In Python hat jede Funktion einen Rückgabewert. Wenn man nicht irgendwo explizit mit ``return`` etwas zurückgibt und der Programmablauf das Ende einer Funktion erreicht, dann wird `None` zurückgegeben
die Funktion shureC in Zeile 58 funzt doch auch ohne probelme
Die Funktion `raiseP()` könnte auch ohne Probleme funktionieren (wenn sie nicht andere Fehler enthalten würde), nur wird sie nicht als `command` an den Knopf gebunden.
ich sehe da kein sonderlichen unterschied :(
An `command` bei den `Button`-Objekten musst Du die *Funktion* binden und nicht die Funktion *aufrufen* und ihren *Rückgabewert* an `command` binden.

Code: Alles auswählen

In [1]: def f():
   ...:     print 'Hallo'
   ...:

In [2]: a = f  # Die Funktion an `a` binden.

In [3]: b = f()  # Funktion ausführen und Rückgabewert an `b` binden.
Hallo

In [4]: print a  # Das ist die Funktion.
<function f at 0xb79c8e2c>

In [5]: print b  # Das ist der Rückgabewert.
None

In [6]: a()  # Funktion kann man später aufrufen.
Hallo

In [7]: b()  # `None` aber nicht.
---------------------------------------------------------------------------
exceptions.TypeError           Traceback (most recent call last)

/home/marc/<ipython console>

TypeError: 'NoneType' object is not callable
Eine Funktion die an einen Button gebunden wird, darf übrigens auch keine Argumente entgegennehmen. Die GUI weiss ja nicht was da für Werte übergeben werden sollen, wenn Du den Button drückst.
Benutzeravatar
Arthur
User
Beiträge: 23
Registriert: Sonntag 12. November 2006, 18:07

ahh... thx

ich denke ich hab jetzt verstanden.

brauche aber noch n bischen für ne sinnvolle lösung...
Benutzeravatar
Arthur
User
Beiträge: 23
Registriert: Sonntag 12. November 2006, 18:07

ich habe mich zur übergabe der allgemeinen bzw spieler-speziellen werte für ein dictionary entschieden. dazu hab ich momentan als beispiel folgende funtion:

Code: Alles auswählen

class Player:
    def raiser(self, m, e, r):
        e=e+r
        m=m-r
        dictio={"%s":{'zug':'raise', 'konto':m, 'raise':r}} %self
        return dictio
in Zeile 5 möchte ich das er als key den namen des jewiegen spielers eingiebt. So wie ich jetzt gemacht habe giebt er mich jedoch den fehler:

TypeError: unsupported operand type(s) for %: 'dict' and 'instance'

was kann ich stattdessen als "einsetzter" nehmen einfach nur self eizugeben macht er nich und bei self in stringzeichen ist es einfach nur 'self' und nicht zb. martin wenn mann den spieler martin genannt hat
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

@Arthur:
es würde mich freuen wenn du deinen code dann mal vorstellst ich spiele recht gerne poker ^^. Danke. für dein prob habe ich keine lösung weil ich noicht verstehe wie das aufgebaut ist. ausser:

Code: Alles auswählen

dictio=[spielername,{'zug':'raise', 'konto':m, 'raise':r}]

dictio[0] == spielername
dictio[1]['zug'] ....
das ist aber sinnloss weil es ja schon dictio heißt und damit dann kein dic mehr ist :-D
BlackJack

Arthur hat geschrieben:

Code: Alles auswählen

class Player:
    def raiser(self, m, e, r):
        e=e+r
        m=m-r
        dictio={"%s":{'zug':'raise', 'konto':m, 'raise':r}} %self
        return dictio
in Zeile 5 möchte ich das er als key den namen des jewiegen spielers eingiebt. So wie ich jetzt gemacht habe giebt er mich jedoch den fehler:

TypeError: unsupported operand type(s) for %: 'dict' and 'instance'

was kann ich stattdessen als "einsetzter" nehmen einfach nur self eizugeben macht er nich und bei self in stringzeichen ist es einfach nur 'self' und nicht zb. martin wenn mann den spieler martin genannt hat
Die Ausnahme sagt's eigentlich schon: Du versuchst ``%`` auf das Dictionary, was links von dem Operator steht und das `Player`-Objekt, das rechts vom Operator steht, anzuwenden. Das funktioniert offensichtlich nicht. Du willst den ``%`` als Formatierungsoperator auf einer Zeichenkette und einem Objekt benutzen. Also muss links eine Zeichenkette und rechts das Objekt stehen.

Code: Alles auswählen

        dictio={'%s' % self: {'zug': 'raise', 'konto': m, 'raise': r}}
Wobei das alles ein wenig (zu) kompliziert aussieht.
Benutzeravatar
Arthur
User
Beiträge: 23
Registriert: Sonntag 12. November 2006, 18:07

danke für die hilfe, wusste nicht , das das % immer direct hinter den string muss...

Das ganze hat den sinn ohne globals auszukommen und da man in einer funktion nur ein return benutzen kann muss ich irgendwie mehrere werte auf einmal übergeben -> Dict
BlackJack

Arthur hat geschrieben:danke für die hilfe, wusste nicht , das das % immer direct hinter den string muss...
Das ist einfach ein binärer Operator wie +, -, * oder /, die beziehen sich immer auf die Ausdrücke/Objekte die direkt links und rechts davon stehen.
Das ganze hat den sinn ohne globals auszukommen und da man in einer funktion nur ein return benutzen kann muss ich irgendwie mehrere werte auf einmal übergeben -> Dict
Ja aber muss der Kontostand wirklich von aussen reinkommen und zurückgegeben werden? Das ist doch eher ein Attribut eines `Player`. Und was Du da mit `e` machst hat keinen Effekt.
Benutzeravatar
Arthur
User
Beiträge: 23
Registriert: Sonntag 12. November 2006, 18:07

jo hast irgendwie schon recht... ich muss da noch ma was dran machen... danke für den tipp
Benutzeravatar
Arthur
User
Beiträge: 23
Registriert: Sonntag 12. November 2006, 18:07

ich habe mal noch eine ganz andere Frage:

kann ich irgendwie die default einstellungen für die Farben ändern???

so dass z.b alle Widgets standartmäßig erstmal blau als background erhalten und nicht grau???

ich habs mit

Code: Alles auswählen

Widget.background='#001050'


versucht, funktioniert aber nicht
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

Hi Arthur,
das geht mit Tk.tk_setPalette:
>>> help(Tk.tk_setPalette) hat geschrieben: Help on method tk_setPalette in module Tkinter:

tk_setPalette(self, *args, **kw) unbound Tkinter.Tk method
Set a new color scheme for all widget elements.

A single color as argument will cause that all colors of Tk
widget elements are derived from this.
Alternatively several keyword parameters and its associated
colors can be given. The following keywords are valid:
activeBackground, foreground, selectColor,
activeForeground, highlightBackground, selectBackground,
background, highlightColor, selectForeground,
disabledForeground, insertBackground, troughColor.
:wink:
Gruß, jj
Benutzeravatar
Arthur
User
Beiträge: 23
Registriert: Sonntag 12. November 2006, 18:07

danke! :D

ich hab mir bei einigen selbstversuchen schon die finger wund getippt...
Antworten