from tkinter import * from tkinter import messagebox import random HUMANPLAYER = 0 AIPLAYER =1 class theGame: def __init__(self): self.board = "1 2 3 4 5 6 7 8 9".split() self.player = 0 self.playerSymbol = ["X","O"] self.gameOver = False def getResult(self): #Check for winner first # check for rows if self.board[0] == self.board[1] and self.board[1] == self.board[2]: return 1 if self.board[3] == self.board[4] and self.board[3] == self.board[5]: return 1 if self.board[6] == self.board[7] and self.board[6] == self.board[8]: return 1 #check for colmns if self.board[0] == self.board[3] and self.board[3] == self.board[6]: return 1 if self.board[1] == self.board[4] and self.board[4] == self.board[7]: return 1 if self.board[2] == self.board[5] and self.board[5] == self.board[8]: return 1 #check diagonals if self.board[0] == self.board[4] and self.board[4] == self.board[8]: return 1 if self.board[2] == self.board[4] and self.board[4] == self.board[6]: return 1 for i in self.board: if i in "123456789": return 0 return 2 def isValidMove(self,move): if not (move >= 1 and move <= 9): return False if self.board[move-1] in "123456789": return True return False def makeMove(self,move): if(self.isValidMove(move)): self.board[move-1] = self.playerSymbol[self.player] def switchPlayers(self): self.player = (self.player + 1) % 2 def getSymbol(self,loc): if loc >= 0 and loc <=8: return self.board[loc] return -1 def getmoves(self,board): moves = [] for i in range(len(board)): if board[i] in "123456789": moves.append(i) return moves def winning(self,b,player): for i in range(0,9,3): if b[i] == b[i+1] and b[i+1] == b[i+2] and b[i] == self.playerSymbol[player]: return True for i in range(0,3): if b[i] == b[i+3] and b[i+3] == b[i+6]and b[i] == self.playerSymbol[player]: return True if b[0] == b[4] and b[4] == b[8]and b[0] == self.playerSymbol[player]: return True if b[2] == b[4] and b[4] == b[6]and b[2] == self.playerSymbol[player]: return True return False def minmax2(self,p): moves = [] possibleMoves = self.getmoves(self.board) if(self.winning(self.board,HUMANPLAYER)): return {"score":-10} if(self.winning(self.board,AIPLAYER)): return {"score":10} if len(possibleMoves) == 0: return {"score":0} for i in range(len(possibleMoves)): move = {} move["index"] = self.board[possibleMoves[i]] self.board[possibleMoves[i]] = self.playerSymbol[p] if p == AIPLAYER: result = self.minmax2(HUMANPLAYER) #print "Result human",result move["score"] = result["score"] else: result = self.minmax2(AIPLAYER) #print "Result ",result move["score"] = result["score"] self.board[possibleMoves[i]] = move["index"] moves.append(move) bestMove = 0; if p == AIPLAYER: bestscore = -10000; for i in range(len(moves)): if(moves[i]["score"] > bestscore): bestscore = moves[i]["score"] bestMove = i else: bestscore = 10000; for i in range(len(moves)): if(moves[i]["score"] < bestscore): bestscore = moves[i]["score"] bestMove = i return moves[bestMove] def makeAIMove(self): # Rule 1 return int(self.minmax2(self.player)["index"])-1 if not self.playerSymbol[0] in self.board and not self.playerSymbol[1] in self.board: return 0 for i in range(1,10): if self.isValidMove(i): self.makeMove(i) result = self.getResult() self.board[i-1] = str(i) if result == 1: return i-1 for i in range(1,10): if self.isValidMove(i): self.board[i-1] = self.playerSymbol[(self.player+1)%2] result = self.getResult() self.board[i-1] = str(i) if result == 1: return i-1 rm = random.randint(0,8) while not self.isValidMove(rm+1): rm = random.randint(0,8) return rm class tictactoe: def __init__(self,wnd): self.mainw = wnd self.frame = Frame(wnd) self.buttons = [] self.frame.pack() self.thisgame = theGame() for i in range(3): for j in range(3): btn = Button(self.frame,text=" ",width=10,height=4,command=lambda x=i*3+j: self.btnClick(x)) self.buttons.append(btn) btn.grid(row = i , column=j) def btnClick(self,btn=0): if self.thisgame.isValidMove(btn+1): self.thisgame.makeMove(btn+1) symb = self.thisgame.getSymbol(btn) if symb == 'X' or symb == 'O': self.buttons[btn].configure(text=symb) result = self.thisgame.getResult() if result == 1: messagebox.showinfo("Result","Player " + str(self.thisgame.player+1) + " won") self.mainw.destroy() if result == 2: messagebox.showinfo("Result","It is a tie") self.mainw.destroy() if result == 0: self.thisgame.switchPlayers() m = self.thisgame.makeAIMove() print ("AI said",m) self.thisgame.makeMove(m+1) symb = self.thisgame.getSymbol(m) if symb == 'X' or symb == 'O': self.buttons[m].configure(text=symb) result = self.thisgame.getResult() if result == 1: messagebox.showinfo("Result","Player " + str(self.thisgame.player+1) + " won") self.mainw.destroy() if result == 2: messagebox.showinfo("Result","It is a tie") self.mainw.destroy() if result == 0: self.thisgame.switchPlayers() mainwnd = Tk() app = tictactoe(mainwnd) mainwnd.mainloop() ''' def printBoard(b): if len(b) != 9: return print(b[0]+"|"+b[1]+"|"+b[2]) print("-----") print(b[3]+"|"+b[4]+"|"+b[5]) print("-----") print(b[6]+"|"+b[7]+"|"+b[8]) print("") def getResult(b): #Check for winner first # check for rows if b[0] == b[1] and b[1] == b[2]: return 1 if b[3] == b[4] and b[3] == b[5]: return 1 if b[6] == b[7] and b[6] == b[8]: return 1 #check for colmns if b[0] == b[3] and b[3] == b[6]: return 1 if b[1] == b[4] and b[4] == b[7]: return 1 if b[2] == b[5] and b[5] == b[8]: return 1 #check diagonals if b[0] == b[4] and b[4] == b[8]: return 1 if b[2] == b[4] and b[4] == b[6]: return 1 for i in b: if i in "123456789": return 0 return 2 def isValidMove(b,move): if not (move >= 1 and move <= 9): return False if b[move-1] in "123456789": return True return False # create the initial board board = "1 2 3 4 5 6 7 8 9".split() player = 1 playerSymbol = ["X","O"] printBoard(board) while getResult(board) == 0: #game is still on #switch players player = (player + 1) % 2 #make a move move = 0 #Get a valid move from the current player while not isValidMove(board,move): move = int(input(f"Player {player+1}, Make your next move> ")) board[move-1] = playerSymbol[player] printBoard(board) if getResult(board) == 2: print ("This game ended in a draw!") else: print (f"Player {player+1}, Won this game") '''