#!/usr/bin/env python
import Tkinter as tk
import tkMessageBox as mb
class ttt:
turn = 0
players = ['Spieler 2', 'Spieler 1']
colors = [ 'orange', 'cyan']
signs = ['O', 'X' ]
fields = [ [ [] for i in range (3) ] for i in range (3) ]
hitten = [ [ [] for i in range (3) ] for i in range (3) ]
def next_turn ( self ):
'''Prepares next turn
Sets turn counter and title widget'''
self.turn += 1
self.title.configure ( text = '%d. Zug\n%s' % (self.turn, self.players[self.turn%2]), bg = self.colors[self.turn%2] )
def check_win_cond ( self ):
'''Validates win conditions
Test diagonals, rows and columns for three identical, valid values'''
# win conditions: diagonals
if self.hitten[0][0] == self.hitten[1][1] and self.hitten[0][0] == self.hitten[2][2] and self.hitten[0][0] in self.signs:
return True
if self.hitten[0][2] == self.hitten[1][1] and self.hitten[0][2] == self.hitten[2][0] and self.hitten[0][2] in self.signs:
return True
# win conditions: lines
for i in range ( 3 ):
if self.hitten[0][i] == self.hitten[1][i] and self.hitten[0][i] == self.hitten[2][i] and self.hitten[0][i] in self.signs:
return True
# win conditions: columns
for i in range ( 3 ):
if self.hitten[i][0] == self.hitten[i][1] and self.hitten[i][0] == self.hitten[i][2] and self.hitten[i][0] in self.signs:
return True
return False
def hit_field ( self, event ):
'''Callback function
Tests whether a field has previously been hitten and
marks the field as hitten, if not hitten before, with
the player's sign.
Afterwards next_turn is called or the game is won'''
widget = event.widget
a, b = 0, 0
for i in range ( len ( self.fields ) ):
if widget in self.fields[i]:
a = i
b = self.fields[i].index ( widget )
if not self.hitten[a][b] in self.signs:
self.hitten[a][b] = self.signs[self.turn%2]
self.fields[a][b].configure ( text = self.signs[self.turn%2], bg = self.colors[self.turn%2] )
if not self.check_win_cond():
self.next_turn()
else:
mb.showinfo ( 'Winner', 'And the winner is\n%s' % self.players[self.turn%2] )
self.root.destroy()
def __init__ ( self, root ):
'''Main Window'''
self.root = root
self.title_frame = tk.Frame ( self.root, bg = 'red' )
self.title_frame.pack ( side = 'top', fill = 'x' )
self.title = tk.Label ( self.title_frame, text = '' )
self.title.pack ( side = 'top' )
self.game_frame = tk.Frame ( self.root )
self.game_frame.pack ( side = 'top', fill = 'both' )
for i in range ( len ( self.fields ) ):
for j in range ( len ( self.fields[i] ) ):
self.fields[i][j] = tk.Label ( self.game_frame, text = ' ', width = 10, height = 5, relief = 'ridge' )
self.fields[i][j].grid ( row = i, column = j )
self.fields[i][j].bind ( '<Button-1>', self.hit_field )
self.q_frame = tk.Frame ( self.root, relief = 'ridge' )
self.q_frame.pack ( side = 'bottom', fill = 'x' )
qbutton = tk.Button ( self.q_frame, text = "Quit", command = self.root.destroy )
qbutton.pack ( side = 'right' )
self.next_turn()
if __name__ == '__main__':
root = tk.Tk ( className = 'Tic Tac Toe' )
window = ttt ( root )
root.mainloop()