├── README.md ├── screenshots └── tictactoe.png ├── ttt.py └── ttt3.py /README.md: -------------------------------------------------------------------------------- 1 | python-tictactoe 2 | ================ 3 | 4 | Python TicTacToe game with Tk GUI and minimax AI 5 | 6 | ![Python TicTacToe screenshot](./screenshots/tictactoe.png) 7 | 8 | see: http://www.leaseweblabs.com/2013/12/python-tictactoe-tk-minimax-ai/ 9 | -------------------------------------------------------------------------------- /screenshots/tictactoe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mevdschee/python-tictactoe/706216d86c1e78494afad4ebed123d3351451668/screenshots/tictactoe.png -------------------------------------------------------------------------------- /ttt.py: -------------------------------------------------------------------------------- 1 | # coding=UTF8 2 | 3 | # Python TicTacToe game with Tk GUI and minimax AI 4 | # Author: Maurits van der Schee 5 | 6 | from Tkinter import Tk, Button 7 | from tkFont import Font 8 | from copy import deepcopy 9 | 10 | class Board: 11 | 12 | def __init__(self,other=None): 13 | self.player = 'X' 14 | self.opponent = 'O' 15 | self.empty = '.' 16 | self.size = 3 17 | self.fields = {} 18 | for y in range(self.size): 19 | for x in range(self.size): 20 | self.fields[x,y] = self.empty 21 | # copy constructor 22 | if other: 23 | self.__dict__ = deepcopy(other.__dict__) 24 | 25 | def move(self,x,y): 26 | board = Board(self) 27 | board.fields[x,y] = board.player 28 | (board.player,board.opponent) = (board.opponent,board.player) 29 | return board 30 | 31 | def __minimax(self, player): 32 | if self.won(): 33 | if player: 34 | return (-1,None) 35 | else: 36 | return (+1,None) 37 | elif self.tied(): 38 | return (0,None) 39 | elif player: 40 | best = (-2,None) 41 | for x,y in self.fields: 42 | if self.fields[x,y]==self.empty: 43 | value = self.move(x,y).__minimax(not player)[0] 44 | if value>best[0]: 45 | best = (value,(x,y)) 46 | return best 47 | else: 48 | best = (+2,None) 49 | for x,y in self.fields: 50 | if self.fields[x,y]==self.empty: 51 | value = self.move(x,y).__minimax(not player)[0] 52 | if value 5 | 6 | import sys 7 | if sys.version_info >= (3, 0): 8 | from tkinter import Tk, Button 9 | from tkinter.font import Font 10 | else: 11 | from Tkinter import Tk, Button 12 | from tkFont import Font 13 | from copy import deepcopy 14 | 15 | class Board: 16 | 17 | def __init__(self,other=None): 18 | self.player = 'X' 19 | self.opponent = 'O' 20 | self.empty = '.' 21 | self.size = 3 22 | self.fields = {} 23 | for y in range(self.size): 24 | for x in range(self.size): 25 | self.fields[x,y] = self.empty 26 | # copy constructor 27 | if other: 28 | self.__dict__ = deepcopy(other.__dict__) 29 | 30 | def move(self,x,y): 31 | board = Board(self) 32 | board.fields[x,y] = board.player 33 | (board.player,board.opponent) = (board.opponent,board.player) 34 | return board 35 | 36 | def __minimax(self, player): 37 | if self.won(): 38 | if player: 39 | return (-1,None) 40 | else: 41 | return (+1,None) 42 | elif self.tied(): 43 | return (0,None) 44 | elif player: 45 | best = (-2,None) 46 | for x,y in self.fields: 47 | if self.fields[x,y]==self.empty: 48 | value = self.move(x,y).__minimax(not player)[0] 49 | if value>best[0]: 50 | best = (value,(x,y)) 51 | return best 52 | else: 53 | best = (+2,None) 54 | for x,y in self.fields: 55 | if self.fields[x,y]==self.empty: 56 | value = self.move(x,y).__minimax(not player)[0] 57 | if value