tkinter TicTacToe

Fragen zu Tkinter.
Antworten
Knon
User
Beiträge: 3
Registriert: Dienstag 24. Juli 2012, 15:15

hi leute, hab vor kurzem angefangen python zu lernen und wollte einfach so mal TicTacToe programmiern aber iwie hab ich keinen plan wie ich
vorgehen soll.
habs jetzt einfach mal so gemacht, weis jetzt nur nicht wie ich prüfen sollte wer gewonnen hat?

Code: Alles auswählen


from Tkinter import *

class TicTacToe:
    def __init__(self, orig):
        self.roundcount = 0
        orig.resizable(False, False)
        orig.title('TicTacToe')       
        self.played = True
        self.win = False
        self.window = Frame(orig, width=400, height=400)
        self.window.pack()
        self.__makeField()
                                    
    def __makeField(self):
        self.Xfields = []
        self.Ofields = []
        for y in range(3):
            for x in range(3):
                button = Button(self.window, width=2, height=1,text='', fg='red')
                button.grid(column=x, row=y)   
                button.bind("<Button-1>", self.setFieldPoint)
                                                      
    def setFieldPoint(self, event):
        if event.widget['text']:
            print "Feld schon besetzt"
        else:
            if self.roundcount % 2 == 0:
                event.widget['text'] = "X"
                self.Xfields.append(event.widget)
            else:
                event.widget['text'] = "O"
                self.Ofields.append(event.widget)
                
            self.roundcount += 1
              
if __name__ == '__main__':
    root = Tk()
    struktur = TicTacToe(root)
    root.mainloop()

bitte dringends um hilfe :K
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du brauchst eine passende Datenstruktur für Dein Spiel! Man kann das z.B. so angehen:

Code: Alles auswählen

board = [0] * 9
"""
>>> [0, 0, 0, 0, 0, 0, 0, 0, 0]
"""
# Die Indizes 0 - 2 stellen die erste Reihe dar,
# 3 - 5 die zweite und 6 - 8 dementsprechend die dritte.
board[0] = 1
board[1] = 4
board[3] = 1
board[2] = 4
board[6] = 1
"""
>>> [1, 4, 4, 1, 0, 0, 1, 0, 0]
"""
# schnell eine Funktion geschrieben, die das ganze "netter"
# darstellt:
def show_board(board):
    print(Keyboard[:3], board[3:6], board[6:], sep="\n")

show_board(board)
""" 
>>>
[1, 4, 4]
[1, 0, 0]
[1, 0, 0]
"""
# man erkennt hier schon recht schön, dass der Spieler mit den "Einsen"
# gewonnen hat. Man kann das prüfen, indem man einfach die passenden
# Felder des Spielbretts aufsummiert:
board[0] + board[3] + board[6]
"""
>>> 3
"""
# Das geht doch sicher schöner!
sum(board[index] for index in (0, 3, 6))
# Nun noch schnell alle Kombinationen von Indizes zusammenstellen,
# die potenziell zu einem Sieg führen können. 
# Das sind ...
winning_combis = (
# ... alle horizonatlen
(0, 1, 2),
(3, 4, 5),
(6, 7, 8),
# ... alle vertikalen
(0, 3, 6),
(1, 4, 7),
(2, 5, 8),
# und noch die beiden diagonalen
(0, 4, 8),
(2, 4, 6)
)
# jetzt können wir leicht alle prüfen:
for combi in winning_combis:
    print(sum(board[index] for index in combi))
"""
>>> 9
1
1
3
4
4
1
5
"""
# Das geht noch kompakter als List-Comprehension:
[sum(board[index] for index in combi) for combi in  winning_combis]
"""
>>> [9, 1, 1, 3, 4, 4, 1, 5]
"""
# Nun können wir mittels `in` testen, ob eine bestimmte Summe in der
# Auswertung enthalten ist, z.B. die 3:
3 in (sum(board[index] for index in combi) for combi in  winning_combis)
"""
>>> True
"""
# Damit wüssten wir, dass Spieler 1 gewonnen hat. Spieler 2 gewinnt mit
# der 12 (-> 3 * 4)
# Nun verpacken wir das noch in eine Funktion:
def check_win(marker, board):      
    return marker * 3 in (sum(board[index] for index in combi) 
                          for combi in  winning_combis)

check_win(1, board)
"""
>>> True
"""
check_win(4, board)
"""
>>> False
"""
So, das mal so als Grundidee. Du brauchst eben noch ein Mapping zwischen den "Markern" und der späteren Darstellung, evtl. so:

Code: Alles auswählen

marker_mapping = {
    0: ".",
    1: "O",
    4: "X"
}

[marker_mapping[field] for field in board]
"""
>>> ['O', 'X', 'X', 'O', '.', '.', 'O', '.', '.']
"""
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Knon
User
Beiträge: 3
Registriert: Dienstag 24. Juli 2012, 15:15

vielen dank für die schnelle antwort hat mir sehr geholfen,

eig ist es ned mal so kompliziert es mit der summe zu überprüfen, aber erst mal darauf kommen :)

aber noch ne frage wie funktioniert das mit dem sep='\n' in älteren versionen 2.7 oder so??
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Code: Alles auswählen

from __future__ import print_function
ab Python 2.6, alles andere wuerde ich nicht mehr "aelter" nennen.
Knon
User
Beiträge: 3
Registriert: Dienstag 24. Juli 2012, 15:15

danke genau danach hab ich gesucht :)

sollte man eig. schon standard alles in python3 programmiern oder ist das ned so schlimm wenn ich ne andere version benutze?
BlackJack

@Knon: Da gehen die Meinungen auseinander. Fakt ist das noch nicht alle Module und Pakete von Drittanbietern auf Python 3 portiert sind und das es auch noch nicht auf breiter Front das Standardpython bei Linux-Distributionen ist.

Ausserdem ist Python 2.7 auch ganz offiziell noch ein aktuelles, gepflegtes Python und wenn man die Dokumentation auf http://docs.python.org/ aufruft bekommt man 2.7 angezeigt und muss erst zur aktuellen 3er weiter klicken, wenn man die haben möchte.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Knon hat geschrieben: eig ist es ned mal so kompliziert es mit der summe zu überprüfen, aber erst mal darauf kommen :)
Naja, das mit der Summe ist mir vor einigen Jahren mal eingefallen, als ich darüber nachdachte. (Es sind sicherlich auch schon andere vor mir darauf gekommen)

Wenn man da nicht drauf kommt, muss man es eben anders angehen. Man kann dann einfach testen, ob alle drei Symbole hinter den Tripeln gleich sind. Das ginge z.B. mit `set`, um ein neues Set aus den Symbolen zu erzeugen. Die Größe muss 1 sein, damit ein Spieler gewonnen hat.

Oder man nutzt `str.join` und prüft eben gegen "XXX" oder "OOO" mittels "==".

In beiden Fällen würde man die innere Schleife in etwa so nutzen können:

Code: Alles auswählen

set(board[index] for index in combi) == 1
# oder
"".join(board[index] for index in combi) in ("XXX", "OOO")
Iirc hatte sma mal einen Tic Tac Toe Ansatz hier vorgestellt... evtl. hatte er noch eine andere Idee.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten