#!/usr/bin/env python

from Tkinter import *

lines = [(0, 3, 6), (1, 4, 7), (2, 5, 8),
         (0, 1, 2), (3, 4, 5), (6, 7, 8),
         (0, 4, 8), (2, 4, 6)]

def winningmove(board, side):
    for a, b, c in lines:
        line = board[a] + board[b] + board[c]
        if line.count(side) == 2 and ' ' in line:
            return (a, b, c)[line.index(' ')]

def gamewinner(board):
    for a, b, c in lines:
        if board[a] == board[b] == board[c] != ' ':
            return board[a]

class TicBoard(Frame):
    def __init__(self, parent, myside):
        Frame.__init__(self, parent)
        self.buttons = []
        self.myside = myside
        self.playerside = (myside == 'X') and 'O' or 'X'
        for y in range(3):
            row = Frame(self)
            for x in range(3):
                button = Button(row, width=2, height=1, font='helvetica 48',
                                command=lambda i=x+y*3: self.played(i))
                button.pack(side=LEFT)
                self.buttons.append(button)
            row.pack(side=TOP)
        controls = Frame(self)
        start = Button(controls, text='start a new game', command=self.start)
        quit = Button(controls, text='quit', command=self.quit)
        start.pack(side=LEFT)
        quit.pack(side=LEFT)
        controls.pack(side=TOP)
        self.start()

    def start(self):
        for button in self.buttons:
            button.config(text=' ', state=ACTIVE, relief=RAISED)
        self.board = [' '] * 9
        self.done = 0
        if self.myside == 'X':
            self.go()

    def finish(self, winner):
        for button in self.buttons:
            button.config(state=DISABLED, relief=FLAT)
        self.done = 1

    def move(self, move, side):
        self.buttons[move].config(text=side, state=DISABLED,
                                  relief=FLAT, disabledforeground='black')
        self.board[move] = side
        winner = gamewinner(self.board)
        if winner or ' ' not in self.board:
            self.finish(winner=winner)

    def played(self, move):
        self.move(move, self.playerside)
        if not self.done:
            self.go()

    def go(self):
        winner = winningmove(self.board, self.myside)
        blocker = winningmove(self.board, self.playerside)
        if winner:
            self.move(winner, self.myside)
        elif blocker:
            self.move(blocker, self.myside)
        elif self.board[4] == ' ':
            self.move(4, self.myside)
        else:
            self.move(self.board.index(' '), self.myside)

Tk().withdraw()
win = Toplevel()
win.title('Tic-Tac-Toe')
board = TicBoard(win, 'X')
board.pack()
mainloop()
