-
Notifications
You must be signed in to change notification settings - Fork 1
/
TicTacToe.py
120 lines (103 loc) · 4.81 KB
/
TicTacToe.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import tkinter as tk
import tkinter.messagebox as messagebox
import random
import json
class TicTacToeGUI:
def __init__(self, agent = "ValueIteration"):
self.window = tk.Tk()
self.window.title("Tic Tac Toe")
self.current_player = "X"
self.board = (0,) * 9
self.buttons = [None] * 9
self.is_vs_computer = False # Flag to check if playing against the computer
self.computer_symbol = "O" # Symbol for the computer player
self.agent = agent
self.policy = {}
if self.agent == "ValueIteration":
path = "Policies/valueIteration.json"
elif self.agent == "PolicyIteration":
path = "Policies/policyIteration.json"
with open(path, 'r') as json_file:
# open json file as dictionary
self.policy = json.load(json_file)
# Calculate the window position to center it on the screen
screen_width = self.window.winfo_screenwidth()
screen_height = self.window.winfo_screenheight()
window_width = 320 # Adjust this as needed
window_height = 430 # Adjust this as needed
x = (screen_width - window_width) // 2
y = (screen_height - window_height) // 2
self.window.geometry(f"{window_width}x{window_height}+{x}+{y}")
player_choice = tk.StringVar()
player_choice.set("X")
player_label = tk.Label(self.window, text="Choose your symbol:")
player_label.grid(row=3, columnspan=3)
x_radio = tk.Radiobutton(self.window, text="X", variable=player_choice, value="X")
o_radio = tk.Radiobutton(self.window, text="O", variable=player_choice, value="O")
x_radio.grid(row=4, column=0)
o_radio.grid(row=4, column=1)
# Add a checkbox for playing against the computer
vs_computer_checkbox = tk.Checkbutton(self.window, text="Play vs Computer", command=self.toggle_vs_computer)
vs_computer_checkbox.grid(row=5, columnspan=3)
start_button = tk.Button(self.window, text="Start Game", command=lambda: self.start_game(player_choice.get()))
start_button.grid(row=6, columnspan=3)
def toggle_vs_computer(self):
self.is_vs_computer = not self.is_vs_computer
def start_game(self, player_choice):
self.computer_symbol = "O" if player_choice == "X" else "X" # Set computer symbol opposite to player
for i in range(9):
row, col = i // 3, i % 3
button = tk.Button(self.window, text="", width=10, height=5, command=lambda idx=i: self.make_move(idx))
button.grid(row=row, column=col)
self.buttons[i] = button
if self.computer_symbol == "X" and self.is_vs_computer:
# Computer starts the game if playing against the computer and computer is X
self.make_computer_move()
def make_move(self, idx):
if self.board[idx] == 0:
self.board = self.board[:idx] + (1 if self.current_player == "X" else 2,) + self.board[idx + 1:]
self.buttons[idx]['text'] = self.current_player
if self.check_win() or self.check_tie():
self.end_game()
else:
self.current_player = "O" if self.current_player == "X" else "X"
if self.is_vs_computer and self.current_player == self.computer_symbol:
# Computer's turn when playing against the computer
self.make_computer_move()
def make_computer_move(self):
# Get the current state of the board
state = self.board
# ivert X and O if computer is O
if self.computer_symbol == "O":
state = tuple(3-x if x!= 0 else 0 for x in state)
self.make_move(self.policy[str(state)])
def check_win(self):
win_combinations = [(0, 1, 2), (3, 4, 5), (6, 7, 8), (0, 3, 6), (1, 4, 7), (2, 5, 8), (0, 4, 8), (2, 4, 6)]
for combo in win_combinations:
a, b, c = combo
if (
self.board[a] == self.board[b] == self.board[c]
and self.board[a] != 0
):
messagebox.showinfo("Game Over", f"Player {self.current_player} wins!")
return True
return False
def check_tie(self):
if 0 not in self.board:
messagebox.showinfo("Game Over", "It's a tie!")
return True
return False
def end_game(self):
for button in self.buttons:
button.config(state=tk.DISABLED)
restart_button = tk.Button(self.window, text="Restart Game", command=self.restart_game)
restart_button.grid(row=7, columnspan=3)
def restart_game(self):
self.window.destroy()
self.__init__()
self.start_game("X")
def start(self):
self.window.mainloop()
if __name__ == "__main__":
game = TicTacToeGUI("PolicyIteration")
game.start()