import tkinter as tk
from tkinter import messagebox
import random
class TicTacToe:
def __init__(self, master):
self.master = master
self.master.title("Tic Tac Toe")
self.master.resizable(False, False) # Make window non-resizable
# Initialize variables
self.player_vs_bot = tk.BooleanVar(value=True) # Option to play with the
computer
self.current_player = 'X'
self.board = [[' ' for _ in range(3)] for _ in range(3)]
self.buttons = []
# Create label to display player turn
self.turn_label = tk.Label(master, text=f"Player {self.current_player}'s
Turn", font=('Arial', 12))
self.turn_label.grid(row=0, columnspan=3, pady=5)
# Create check button to choose player vs bot
self.bot_checkbox = tk.Checkbutton(master, text="Play against Computer",
variable=self.player_vs_bot,
onvalue=True, offvalue=False,
command=self.reset_board)
self.bot_checkbox.grid(row=4, columnspan=3, pady=5)
# Set random background and button colors
self.set_background_color()
# Create buttons for the game board
for i in range(3):
row = []
for j in range(3):
button = tk.Button(master, text='', font=('Arial', 20), width=5,
height=2,
command=lambda i=i, j=j: self.place_symbol(i,
j), fg='black')
button.grid(row=i+1, column=j, padx=5, pady=5)
row.append(button)
self.buttons.append(row)
if self.player_vs_bot.get() and self.current_player == 'O':
self.bot_play()
def place_symbol(self, row, col):
if self.board[row][col] == ' ':
self.board[row][col] = self.current_player
self.buttons[row][col].config(text=self.current_player,
state='disabled') # Disable button after selection
if self.check_winner():
messagebox.showinfo("Winner", f"Player {self.current_player}
wins!")
self.reset_board()
elif self.is_board_full():
messagebox.showinfo("Draw", "It's a draw!")
self.reset_board()
else:
self.current_player = 'O' if self.current_player == 'X' else 'X'
self.update_turn_label() # Update turn label
# If playing against the bot and it's bot's turn
if self.player_vs_bot.get() and self.current_player == 'O':
self.bot_play()
def bot_play(self):
best_score = -float('inf')
best_move = None
for i in range(3):
for j in range(3):
if self.board[i][j] == ' ':
self.board[i][j] = 'O'
score = self.minimax(self.board, False)
self.board[i][j] = ' '
if score > best_score:
best_score = score
best_move = (i, j)
if best_move is not None:
row, col = best_move
self.place_symbol(row, col)
def minimax(self, board, is_maximizing):
if self.check_winner() and is_maximizing:
return -1
elif self.check_winner() and not is_maximizing:
return 1
elif self.is_board_full():
return 0
if is_maximizing:
best_score = -float('inf')
for i in range(3):
for j in range(3):
if board[i][j] == ' ':
board[i][j] = 'O'
score = self.minimax(board, False)
board[i][j] = ' '
best_score = max(score, best_score)
return best_score
else:
best_score = float('inf')
for i in range(3):
for j in range(3):
if board[i][j] == ' ':
board[i][j] = 'X'
score = self.minimax(board, True)
board[i][j] = ' '
best_score = min(score, best_score)
return best_score
def check_winner(self):
# Check rows, columns, and diagonals for a winner
for i in range(3):
if self.board[i][0] == self.board[i][1] == self.board[i][2] != ' ':
return True
if self.board[0][i] == self.board[1][i] == self.board[2][i] != ' ':
return True
if self.board[0][0] == self.board[1][1] == self.board[2][2] != ' ':
return True
if self.board[0][2] == self.board[1][1] == self.board[2][0] != ' ':
return True
return False
def is_board_full(self):
# Check if the board is full
for row in self.board:
if ' ' in row:
return False
return True
def reset_board(self):
# Reset the board to its initial state
self.board = [[' ' for _ in range(3)] for _ in range(3)]
for i in range(3):
for j in range(3):
self.buttons[i][j].config(text='', state='normal') # Re-enable
buttons
self.current_player = 'X'
self.update_turn_label() # Update turn label
self.set_background_color() # Change background color
# If playing against the bot and bot is starting, let bot play
if self.player_vs_bot.get() and self.current_player == 'O':
self.bot_play()
def update_turn_label(self):
# Update the turn label to show current player's turn
self.turn_label.config(text=f"Player {self.current_player}'s Turn")
def set_background_color(self):
# Set random background and button colors
bg_colors = ['lightblue', 'lightgreen', 'lightpink', 'lightyellow']
button_color = random.choice(['White', 'Black', 'Gray', 'LightGray',
'Purple', 'Green', 'Darkgreen', 'Blue',
'Pink', 'Cyan', 'Red', 'Yellow', 'Brown',
'Orange', 'Gold'])
self.master.config(bg=random.choice(bg_colors))
for row in self.buttons:
for button in row:
button.config(bg=button_color)
def main():
root = tk.Tk()
game = TicTacToe(root)
root.mainloop()
main()