# tk_Tk10_TIC_TAC_TOE_style.py
#weigu.lu/c/python

from tkinter import *    # Python 2.7 "from Tkinter import *"
from tkinter import ttk  # Python 2.7 "import ttk"
    
def b11():    
    b11V.set(buttXO.get())
    bcount.set(bcount.get()+1)
    butt_11.state(["disabled"])
    evaluate()
    
def b12():
    b12V.set(buttXO.get())
    bcount.set(bcount.get()+1)
    butt_12.state(["disabled"])
    evaluate()
    
def b13():
    b13V.set(buttXO.get())
    bcount.set(bcount.get()+1)
    butt_13.state(["disabled"])
    evaluate()
    
def b21():
    b21V.set(buttXO.get())
    bcount.set(bcount.get()+1)
    butt_21.state(["disabled"])
    evaluate()
    
def b22():
    b22V.set(buttXO.get())
    bcount.set(bcount.get()+1)
    butt_22.state(["disabled"])
    evaluate()
    
def b23():
    b23V.set(buttXO.get())
    bcount.set(bcount.get()+1)
    butt_23.state(["disabled"])
    evaluate()
    
def b31():
    b31V.set(buttXO.get())
    bcount.set(bcount.get()+1)
    butt_31.state(["disabled"])
    evaluate()
    
def b32():
    b32V.set(buttXO.get())
    bcount.set(bcount.get()+1)
    butt_32.state(["disabled"])
    evaluate()
    
def b33():
    b33V.set(buttXO.get())
    bcount.set(bcount.get()+1)
    butt_33.state(["disabled"])
    evaluate()
    
def evaluate():
    bcount2 = bcount.get()
    if (bcount2%2)==1:
        if b11V.get()!='X':
            butt_11['style'] = 's2.TButton'
        if b12V.get()!='X':    
            butt_12['style'] = 's2.TButton'
        if b13V.get()!='X':    
            butt_13['style'] = 's2.TButton'
        if b21V.get()!='X':    
            butt_21['style'] = 's2.TButton'
        if b22V.get()!='X':    
            butt_22['style'] = 's2.TButton'
        if b23V.get()!='X':    
            butt_23['style'] = 's2.TButton'
        if b31V.get()!='X':    
            butt_31['style'] = 's2.TButton'
        if b32V.get()!='X':    
            butt_32['style'] = 's2.TButton'
        if b33V.get()!='X':    
            butt_33['style'] = 's2.TButton'
        buttXO.set('O')    
    else:    
        if b11V.get()!='O':
            butt_11['style'] = 's1.TButton'
        if b12V.get()!='O':
            butt_12['style'] = 's1.TButton'
        if b13V.get()!='O':
            butt_13['style'] = 's1.TButton'
        if b21V.get()!='O':    
            butt_21['style'] = 's1.TButton'
        if b22V.get()!='O':    
            butt_22['style'] = 's1.TButton'
        if b23V.get()!='O':    
            butt_23['style'] = 's1.TButton'
        if b31V.get()!='O':    
            butt_31['style'] = 's1.TButton'
        if b32V.get()!='O':    
            butt_32['style'] = 's1.TButton'
        if b33V.get()!='O':    
            butt_33['style'] = 's1.TButton'
        buttXO.set('X')    
    # evaluate rows
    if  (b11V.get()=='O') & (b12V.get()=='O') & (b13V.get()=='O'):
        redwins()
    if  (b11V.get()=='X') & (b12V.get()=='X') & (b13V.get()=='X'):
        greenwins()
    if  (b21V.get()=='O') & (b22V.get()=='O') & (b23V.get()=='O'):
        redwins()
    if  (b21V.get()=='X') & (b22V.get()=='X') & (b23V.get()=='X'):
        greenwins()
    if  (b31V.get()=='O') & (b32V.get()=='O') & (b33V.get()=='O'):
        redwins()
    if  (b31V.get()=='X') & (b32V.get()=='X') & (b33V.get()=='X'):
        greenwins()
    # evaluate columns
    if  (b11V.get()=='O') & (b21V.get()=='O') & (b31V.get()=='O'):
        redwins()
    if  (b11V.get()=='X') & (b21V.get()=='X') & (b31V.get()=='X'):
        greenwins()
    if  (b12V.get()=='O') & (b22V.get()=='O') & (b32V.get()=='O'):
        redwins()
    if  (b12V.get()=='X') & (b22V.get()=='X') & (b32V.get()=='X'):
        greenwins()
    if  (b13V.get()=='O') & (b23V.get()=='O') & (b33V.get()=='O'):
        redwins()
    if  (b13V.get()=='X') & (b23V.get()=='X') & (b33V.get()=='X'):
        greenwins()
    # evaluate diagonal
    if  (b11V.get()=='O') & (b22V.get()=='O') & (b33V.get()=='O'):
        redwins()
    if  (b11V.get()=='X') & (b22V.get()=='X') & (b33V.get()=='X'):
        greenwins()
    if  (b13V.get()=='O') & (b22V.get()=='O') & (b31V.get()=='O'):
        redwins()
    if  (b13V.get()=='X') & (b22V.get()=='X') & (b31V.get()=='X'):
        greenwins()        
    if bcount2==9:    
        if (resultVar.get()!='red wins!!') & (resultVar.get()!='green wins!!'):
            label_2['style'] = 'TLabel'
            resultVar.set('Game over: Nobody wins')
        
def redwins():
    label_2['style'] = 's1.TLabel'
    resultVar.set('red wins!!')
    
def greenwins():
    label_2['style'] = 's2.TLabel'
    resultVar.set('green wins!!')  

def newgame():
    buttXO.set('X')
    bcount.set(0)
    b11V.set('')
    b12V.set('')
    b13V.set('')
    b21V.set('')
    b22V.set('')
    b23V.set('')
    b31V.set('')
    b32V.set('')
    b33V.set('')
    resultVar.set('')
    butt_11.state(["!disabled"])
    butt_12.state(["!disabled"])
    butt_13.state(["!disabled"])
    butt_21.state(["!disabled"])
    butt_22.state(["!disabled"])
    butt_23.state(["!disabled"])
    butt_31.state(["!disabled"])
    butt_32.state(["!disabled"])
    butt_33.state(["!disabled"])
    butt_11['style'] = 's1.TButton'
    butt_12['style'] = 's1.TButton'
    butt_13['style'] = 's1.TButton'
    butt_21['style'] = 's1.TButton'
    butt_22['style'] = 's1.TButton'
    butt_23['style'] = 's1.TButton'
    butt_31['style'] = 's1.TButton'
    butt_32['style'] = 's1.TButton'
    butt_33['style'] = 's1.TButton'
    
mainWin = Tk()
mainWin.title('TIC TAC TOE')
mainWin.columnconfigure(0, weight=1)         # numbering beginns with 0 for old Tk widgets 
mainWin.rowconfigure(0, weight=1)            

b11V = StringVar()    
b12V = StringVar()    
b13V = StringVar()    
b21V = StringVar()    
b22V = StringVar()    
b23V = StringVar()    
b31V = StringVar()    
b32V = StringVar()    
b33V = StringVar()    

buttXO = StringVar()
buttXO.set('X')
bcount = IntVar()
bcount.set(0)

resultVar = StringVar()    

mainFrame = ttk.Frame(mainWin, borderwidth=10, relief='ridge', padding="10 10 20 20")
mainFrame.grid(column=0, row=0, sticky=(W, N, E, S))
mainFrame.columnconfigure(1, weight=5)       # numbering beginns with 1 for newer Ttk widgets 
mainFrame.columnconfigure(2, weight=5)
mainFrame.columnconfigure(3, weight=5)
mainFrame.rowconfigure(1, weight=1)
mainFrame.rowconfigure(2, weight=1)
mainFrame.rowconfigure(3, weight=1)
mainFrame.rowconfigure(4, weight=1)
mainFrame.rowconfigure(5, weight=1)
mainFrame.rowconfigure(6, weight=1)

label_1 = ttk.Label(mainFrame, text='player green begins:')
label_1.grid(column=1, row=1, sticky=(N), columnspan=3)
label_2 = ttk.Label(mainFrame, textvariable=resultVar, style='s1.TLabel')
label_2.grid(column=1, row=5, sticky=(N), columnspan=7)

butt_11 = ttk.Button(mainFrame, textvariable=b11V, command=b11, style='s1.TButton', width= 3)
butt_11.grid(column=1, row=2, sticky=(N))
butt_12 = ttk.Button(mainFrame, textvariable=b12V, command=b12, style='s1.TButton', width= 3)
butt_12.grid(column=2, row=2, sticky=(N))
butt_13 = ttk.Button(mainFrame, textvariable=b13V, command=b13, style='s1.TButton', width= 3)
butt_13.grid(column=3, row=2, sticky=(N))
butt_21 = ttk.Button(mainFrame, textvariable=b21V, command=b21, style='s1.TButton', width= 3)
butt_21.grid(column=1, row=3, sticky=(N))
butt_22 = ttk.Button(mainFrame, textvariable=b22V, command=b22, style='s1.TButton', width= 3)
butt_22.grid(column=2, row=3, sticky=(N))
butt_23 = ttk.Button(mainFrame, textvariable=b23V, command=b23, style='s1.TButton', width= 3)
butt_23.grid(column=3, row=3, sticky=(N))
butt_31 = ttk.Button(mainFrame, textvariable=b31V, command=b31, style='s1.TButton', width= 3)
butt_31.grid(column=1, row=4, sticky=(N))
butt_32 = ttk.Button(mainFrame, textvariable=b32V, command=b32, style='s1.TButton', width= 3)
butt_32.grid(column=2, row=4, sticky=(N))
butt_33 = ttk.Button(mainFrame, textvariable=b33V, command=b33, style='s1.TButton', width= 3)
butt_33.grid(column=3, row=4, sticky=(N))
butt_new = ttk.Button(mainFrame, text='new game', command=newgame)
butt_new.grid(column=1, row=6, sticky=(N), columnspan=3)

s = ttk.Style()
s.configure('s1.TButton', background='white', font=('Helvetica', 18, 'bold'))
s.configure('s2.TButton', background='white', font=('Helvetica', 18, 'bold'))
s.configure('s1.TLabel', foreground='red', font=('Helvetica', 18, 'bold'))
s.configure('s2.TLabel', foreground='green', font=('Helvetica', 18, 'bold'))
s.map('s1.TButton', foreground=[('disabled', 'green')], background=[('disabled', 'white'),('active', 'green')], relief=[('!pressed', 'ridge')])
s.map('s2.TButton', foreground=[('disabled', 'red')], background=[('disabled', 'white'),('active', 'red')], relief=[('!pressed', 'ridge')])

# Padding
for child in mainFrame.winfo_children():
    child.grid_configure(padx=5, pady=5)
    
mainWin.mainloop()
