84 lines
3.2 KiB
Python
84 lines
3.2 KiB
Python
import tkinter as tk
|
|
from tkinter import Frame, Button, Label, StringVar, messagebox
|
|
from app.widgets.abc import ThreadedTab
|
|
|
|
class TicTacToeTab(ThreadedTab):
|
|
|
|
def __init__(self, root: Frame | tk.Tk, **kwargs):
|
|
self.current_player = StringVar(value="X") # Start with player X
|
|
self.board = [[None for _ in range(3)] for _ in range(3)] # 3x3 board
|
|
super().__init__(root, **kwargs)
|
|
|
|
def build(self):
|
|
# Create the main frame for the Tic Tac Toe interface
|
|
self.game_frame = Frame(self)
|
|
self.game_frame.pack(fill="both", expand=True)
|
|
|
|
# Create the label to display the current player
|
|
self.player_label = Label(self.game_frame, textvariable=self.current_player, font=("Arial", 16))
|
|
self.player_label.pack(padx=5, pady=5)
|
|
|
|
# Create the grid for the Tic Tac Toe board
|
|
self.board_frame = Frame(self.game_frame)
|
|
self.board_frame.pack(expand=True)
|
|
|
|
for row in range(3):
|
|
for col in range(3):
|
|
button = Button(
|
|
self.board_frame,
|
|
text="",
|
|
font=("Arial", 24),
|
|
width=5,
|
|
height=2,
|
|
command=lambda r=row, c=col: self.make_move(r, c)
|
|
)
|
|
button.grid(row=row, column=col, padx=5, pady=5)
|
|
self.board[row][col] = button
|
|
|
|
def make_move(self, row, col):
|
|
button = self.board[row][col]
|
|
# Check if the cell is already occupied
|
|
if button["text"] == "":
|
|
button["text"] = self.current_player.get()
|
|
if self.check_winner():
|
|
messagebox.showinfo("Game Over", f"Player {self.current_player.get()} wins!")
|
|
self.reset_board()
|
|
elif self.is_draw():
|
|
messagebox.showinfo("Game Over", "It's a draw!")
|
|
self.reset_board()
|
|
else:
|
|
self.switch_player()
|
|
else:
|
|
messagebox.showwarning("Invalid Move", "This cell is already taken!")
|
|
|
|
def switch_player(self):
|
|
self.current_player.set("O" if self.current_player.get() == "X" else "X")
|
|
|
|
def check_winner(self):
|
|
# Check rows, columns, and diagonals
|
|
for i in range(3):
|
|
if self.board[i][0]["text"] == self.board[i][1]["text"] == self.board[i][2]["text"] != "":
|
|
return True
|
|
if self.board[0][i]["text"] == self.board[1][i]["text"] == self.board[2][i]["text"] != "":
|
|
return True
|
|
if self.board[0][0]["text"] == self.board[1][1]["text"] == self.board[2][2]["text"] != "":
|
|
return True
|
|
if self.board[0][2]["text"] == self.board[1][1]["text"] == self.board[2][0]["text"] != "":
|
|
return True
|
|
return False
|
|
|
|
def is_draw(self):
|
|
# Check if all cells are filled
|
|
return all(self.board[row][col]["text"] != "" for row in range(3) for col in range(3))
|
|
|
|
def reset_board(self):
|
|
# Clear the board
|
|
for row in range(3):
|
|
for col in range(3):
|
|
self.board[row][col]["text"] = ""
|
|
self.current_player.set("X")
|
|
|
|
def task(self):
|
|
# Placeholder for threaded behavior if needed
|
|
pass
|