Tic Tac Toe game in Python 3.X using tkinter GUI version 2Tic Tac Toe game in Python 3.X using tkinter UITic...
Is there a better way to make this?
Explain the objections to these measures against human trafficking
How can I deal with a significant flaw I found in my previous supervisor’s paper?
Tikzing a circled star
"On one hand" vs "on the one hand."
Why don't I see the difference between two different files in insert mode in vim?
Why is button three on trumpet almost never used alone?
What to do if authors don't respond to my serious concerns about their paper?
Why did Bush enact a completely different foreign policy to that which he espoused during the 2000 Presidential election campaign?
What is the purpose of easy combat scenarios that don't need resource expenditure?
What's a good word to describe a public place that looks like it wouldn't be rough?
Can we use the stored gravitational potential energy of a building to produce power?
How to generate a matrix with certain conditions
Am I a Rude Number?
Avoiding morning and evening handshakes
Why is working on the same position for more than 15 years not a red flag?
What is the etymology of the kanji 食?
Rear brake cable temporary fix possible?
Quenching swords in dragon blood; why?
Can a person refuse a presidential pardon?
Number of FLOP (Floating Point Operations) for exponentiation
How would an AI self awareness kill switch work?
Does the "particle exchange" operator have any validity?
How did the original light saber work?
Tic Tac Toe game in Python 3.X using tkinter GUI version 2
Tic Tac Toe game in Python 3.X using tkinter UITic Tac Toe game in PythonTic Tac Toe Game PythonTic Tic Tic Tac Tac Tac Toe Toe ToePython Tic Tac Toe GameBasic Python Tic-Tac-Toe GamePython Tic-Tac-Toe gameSimple Tic-Tac-Toe using tkinterPython Tic Tac Toe Gui and AIPython Tic Tac ToeTic Tac Toe game in Python 3.X using tkinter UI
$begingroup$
I am completely new to programming and to python and as my first self-learning project I am creating a simple Tic-Tac-Toe game. I have already posted a version of my code here on stack:
Tic Tac Toe game in Python 3.X using tkinter UI
However, after I've spent some time learning and came back to the code - I have found a whole bunch of problems with it and decided to try and fix it myself. In addition to that I've switched from procedural tkinter GUI approach to the object-oriented tkinter GUI approach. I'm still not sure if I'm doing things the right way. Thus, I seek your advice.
Note: choosing a setting in settings window does nothing for now. I am planning on implementing this feature in the future. I left it to get advice on creating radiobuttons and handling their control variables.
import random
import tkinter as tk
import tkinter.ttk as ttk
class AppMain:
def __init__(self, master):
self.master = master
self.frame = ttk.Frame(master, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.play = ttk.Button(self.frame, text='Play',
command=lambda: PlayMenu(do=0))
self.settings = ttk.Button(self.frame, text='Settings',
command=SettingsWindow)
self.qb = ttk.Button(self.frame, text="Quit", command=root.destroy)
self.main_window()
def main_window(self):
self.remove_widgets()
self.frame.pack(padx=25, pady=75)
self.play.pack(side='top', pady=(33, 0))
self.settings.pack(side='top', pady=5)
self.qb.pack(side='top', pady=(0, 32))
def remove_widgets(self):
for widget in self.master.winfo_children():
widget.pack_forget()
class SettingsWindow(AppMain):
def __init__(self):
self.frame = ttk.Frame(root, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.rb1 = ttk.Radiobutton(self.frame, text='Easy', variable=mode,
value=0)
self.rb2 = ttk.Radiobutton(self.frame, text='Impossible',
variable=mode, value=1)
self.rb3 = ttk.Radiobutton(self.frame, text='2 players',
variable=mode, value=2)
self.back = ttk.Button(self.frame, text='Back',
command=lambda: AppMain(master=root))
self.settings_window()
def settings_window(self):
r = AppMain(master=root)
r.remove_widgets()
self.frame.pack(padx=25, pady=75)
self.rb1.pack(side='top', pady=(10, 0))
self.rb2.pack(side='top', pady=(10, 0))
self.rb3.pack(side='top', padx=(0, 22), pady=(10, 0))
self.back.pack(side='top', pady=(16, 16))
class PlayMenu(AppMain):
def __init__(self, do):
self.do = do
self.label = ttk.Label(root, text='Choose your side',
font=('French Script MT', 20))
self.frame = ttk.Frame(root, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.player_x = ttk.Button(self.frame, text='X',
command=lambda: GameWindow(pl='X', pc='O'))
self.player_o = ttk.Button(self.frame, text='O',
command=lambda: GameWindow(pl='O', pc='X'))
self.back = ttk.Button(self.frame, text='Back',
command=lambda: AppMain(master=root))
if do == 'redeclare':
global statusLib
statusLib = [None for v in range(9)]
self.play_menu()
def play_menu(self):
r = AppMain(master=root)
r.remove_widgets()
self.label.pack(side='top', pady=(25, 0))
self.frame.pack(padx=25, pady=25)
self.player_x.grid(column=0, row=0, padx=(5, 0), pady=(5, 0))
self.player_o.grid(column=1, row=0, padx=(0, 5), pady=(5, 0))
self.back.grid(column=0, row=1, sticky='w, e', padx=(5, 5), pady=(0, 5),
columnspan=2)
class GameWindow(AppMain):
def __init__(self, pl, pc):
self.pl, self.pc, self.stop_game = pl, pc, False
self.frame = ttk.Frame(root, width=650, height=700)
self.frame.pack_propagate(False)
self.canvas = tk.Canvas(self.frame, width=600, height=600)
self.restart = ttk.Button(self.frame, text='Restart',
command=lambda: PlayMenu(do='redeclare'))
self.game_window()
def game_window(self):
r = AppMain(master=root)
r.remove_widgets()
self.frame.pack()
self.canvas.pack(side='top', pady=(25, 0))
self.restart.pack(side='bottom', pady=20)
self.draw_board()
self.canvas.bind('<Button-1>', self.square_selector)
if self.pl == 'O':
self.computer_move()
def draw_board(self):
self.canvas.create_line(0, 200, 600, 200)
self.canvas.create_line(0, 400, 600, 400)
self.canvas.create_line(200, 0, 200, 600)
self.canvas.create_line(400, 0, 400, 600)
def square_selector(self, event):
self.player_move(square=(event.x // 200 * 3 + event.y // 200))
def player_move(self, square):
if statusLib[square] is None:
self.make_move(sq=square, symbol=self.pl, turn='player')
if not self.stop_game:
self.computer_move()
def computer_move(self):
status, square = 0, None
while status is not None:
square = random.randint(0, 8)
status = statusLib[square]
self.make_move(sq=square, symbol=self.pc, turn='computer')
def make_move(self, sq, symbol, turn):
self.draw_move(symbol=symbol, sq=sq)
statusLib[sq] = symbol
self.end_game(this_move=turn, symbol=symbol)
def draw_move(self, symbol, sq):
pos = [100 + sq // 3 * 200, 100 + sq % 3 * 200]
self.canvas.create_text(pos, text=symbol, font=('French Script MT', 50),
anchor='center')
def end_game(self, this_move, symbol):
condition = self.check_end_game(symbol=symbol)
self.stop_game = condition[0]
text = ''
if condition[0]:
self.canvas.unbind('<Button-1>')
if this_move == 'player' and not condition[1]:
text = 'You win'
elif this_move == 'computer' and not condition[1]:
text = 'You lose'
elif condition[1]:
text = 'It's a tie'
self.finisher(fin=condition[2])
self.canvas.create_text(300, 300, text=text,
font=('French Script MT', 50),
fill='#EE2C2C')
@staticmethod
def check_end_game(symbol):
if statusLib[0] == statusLib[1] == statusLib[2] == symbol:
return [True, False, 1]
elif statusLib[3] == statusLib[4] == statusLib[5] == symbol:
return [True, False, 2]
elif statusLib[6] == statusLib[7] == statusLib[8] == symbol:
return [True, False, 3]
elif statusLib[0] == statusLib[3] == statusLib[6] == symbol:
return [True, False, 4]
elif statusLib[1] == statusLib[4] == statusLib[7] == symbol:
return [True, False, 5]
elif statusLib[2] == statusLib[5] == statusLib[8] == symbol:
return [True, False, 6]
elif statusLib[2] == statusLib[4] == statusLib[6] == symbol:
return [True, False, 7]
elif statusLib[0] == statusLib[4] == statusLib[8] == symbol:
return [True, False, 8]
elif all(k is not None for k in statusLib):
return [True, True, 0]
else:
return [False, False, 0]
def finisher(self, fin):
lib = [[100, 100, 100, 500], [300, 100, 300, 500], [500, 100, 500, 500],
[100, 100, 500, 100], [100, 300, 500, 300], [100, 500, 500, 500],
[500, 100, 100, 500], [100, 100, 500, 500]]
if fin != 0:
self.canvas.create_line(lib[fin - 1][0], lib[fin - 1][1],
lib[fin - 1][2], lib[fin - 1][3],
fill='#1874CD', width=5)
if __name__ == '__main__':
root = tk.Tk()
root.title('Tic Tac Toe')
root.minsize(width=300, height=300)
statusLib = [None for i in range(9)]
mode = tk.IntVar()
AppMain(master=root)
root.mainloop()
python beginner python-3.x tic-tac-toe tkinter
$endgroup$
add a comment |
$begingroup$
I am completely new to programming and to python and as my first self-learning project I am creating a simple Tic-Tac-Toe game. I have already posted a version of my code here on stack:
Tic Tac Toe game in Python 3.X using tkinter UI
However, after I've spent some time learning and came back to the code - I have found a whole bunch of problems with it and decided to try and fix it myself. In addition to that I've switched from procedural tkinter GUI approach to the object-oriented tkinter GUI approach. I'm still not sure if I'm doing things the right way. Thus, I seek your advice.
Note: choosing a setting in settings window does nothing for now. I am planning on implementing this feature in the future. I left it to get advice on creating radiobuttons and handling their control variables.
import random
import tkinter as tk
import tkinter.ttk as ttk
class AppMain:
def __init__(self, master):
self.master = master
self.frame = ttk.Frame(master, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.play = ttk.Button(self.frame, text='Play',
command=lambda: PlayMenu(do=0))
self.settings = ttk.Button(self.frame, text='Settings',
command=SettingsWindow)
self.qb = ttk.Button(self.frame, text="Quit", command=root.destroy)
self.main_window()
def main_window(self):
self.remove_widgets()
self.frame.pack(padx=25, pady=75)
self.play.pack(side='top', pady=(33, 0))
self.settings.pack(side='top', pady=5)
self.qb.pack(side='top', pady=(0, 32))
def remove_widgets(self):
for widget in self.master.winfo_children():
widget.pack_forget()
class SettingsWindow(AppMain):
def __init__(self):
self.frame = ttk.Frame(root, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.rb1 = ttk.Radiobutton(self.frame, text='Easy', variable=mode,
value=0)
self.rb2 = ttk.Radiobutton(self.frame, text='Impossible',
variable=mode, value=1)
self.rb3 = ttk.Radiobutton(self.frame, text='2 players',
variable=mode, value=2)
self.back = ttk.Button(self.frame, text='Back',
command=lambda: AppMain(master=root))
self.settings_window()
def settings_window(self):
r = AppMain(master=root)
r.remove_widgets()
self.frame.pack(padx=25, pady=75)
self.rb1.pack(side='top', pady=(10, 0))
self.rb2.pack(side='top', pady=(10, 0))
self.rb3.pack(side='top', padx=(0, 22), pady=(10, 0))
self.back.pack(side='top', pady=(16, 16))
class PlayMenu(AppMain):
def __init__(self, do):
self.do = do
self.label = ttk.Label(root, text='Choose your side',
font=('French Script MT', 20))
self.frame = ttk.Frame(root, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.player_x = ttk.Button(self.frame, text='X',
command=lambda: GameWindow(pl='X', pc='O'))
self.player_o = ttk.Button(self.frame, text='O',
command=lambda: GameWindow(pl='O', pc='X'))
self.back = ttk.Button(self.frame, text='Back',
command=lambda: AppMain(master=root))
if do == 'redeclare':
global statusLib
statusLib = [None for v in range(9)]
self.play_menu()
def play_menu(self):
r = AppMain(master=root)
r.remove_widgets()
self.label.pack(side='top', pady=(25, 0))
self.frame.pack(padx=25, pady=25)
self.player_x.grid(column=0, row=0, padx=(5, 0), pady=(5, 0))
self.player_o.grid(column=1, row=0, padx=(0, 5), pady=(5, 0))
self.back.grid(column=0, row=1, sticky='w, e', padx=(5, 5), pady=(0, 5),
columnspan=2)
class GameWindow(AppMain):
def __init__(self, pl, pc):
self.pl, self.pc, self.stop_game = pl, pc, False
self.frame = ttk.Frame(root, width=650, height=700)
self.frame.pack_propagate(False)
self.canvas = tk.Canvas(self.frame, width=600, height=600)
self.restart = ttk.Button(self.frame, text='Restart',
command=lambda: PlayMenu(do='redeclare'))
self.game_window()
def game_window(self):
r = AppMain(master=root)
r.remove_widgets()
self.frame.pack()
self.canvas.pack(side='top', pady=(25, 0))
self.restart.pack(side='bottom', pady=20)
self.draw_board()
self.canvas.bind('<Button-1>', self.square_selector)
if self.pl == 'O':
self.computer_move()
def draw_board(self):
self.canvas.create_line(0, 200, 600, 200)
self.canvas.create_line(0, 400, 600, 400)
self.canvas.create_line(200, 0, 200, 600)
self.canvas.create_line(400, 0, 400, 600)
def square_selector(self, event):
self.player_move(square=(event.x // 200 * 3 + event.y // 200))
def player_move(self, square):
if statusLib[square] is None:
self.make_move(sq=square, symbol=self.pl, turn='player')
if not self.stop_game:
self.computer_move()
def computer_move(self):
status, square = 0, None
while status is not None:
square = random.randint(0, 8)
status = statusLib[square]
self.make_move(sq=square, symbol=self.pc, turn='computer')
def make_move(self, sq, symbol, turn):
self.draw_move(symbol=symbol, sq=sq)
statusLib[sq] = symbol
self.end_game(this_move=turn, symbol=symbol)
def draw_move(self, symbol, sq):
pos = [100 + sq // 3 * 200, 100 + sq % 3 * 200]
self.canvas.create_text(pos, text=symbol, font=('French Script MT', 50),
anchor='center')
def end_game(self, this_move, symbol):
condition = self.check_end_game(symbol=symbol)
self.stop_game = condition[0]
text = ''
if condition[0]:
self.canvas.unbind('<Button-1>')
if this_move == 'player' and not condition[1]:
text = 'You win'
elif this_move == 'computer' and not condition[1]:
text = 'You lose'
elif condition[1]:
text = 'It's a tie'
self.finisher(fin=condition[2])
self.canvas.create_text(300, 300, text=text,
font=('French Script MT', 50),
fill='#EE2C2C')
@staticmethod
def check_end_game(symbol):
if statusLib[0] == statusLib[1] == statusLib[2] == symbol:
return [True, False, 1]
elif statusLib[3] == statusLib[4] == statusLib[5] == symbol:
return [True, False, 2]
elif statusLib[6] == statusLib[7] == statusLib[8] == symbol:
return [True, False, 3]
elif statusLib[0] == statusLib[3] == statusLib[6] == symbol:
return [True, False, 4]
elif statusLib[1] == statusLib[4] == statusLib[7] == symbol:
return [True, False, 5]
elif statusLib[2] == statusLib[5] == statusLib[8] == symbol:
return [True, False, 6]
elif statusLib[2] == statusLib[4] == statusLib[6] == symbol:
return [True, False, 7]
elif statusLib[0] == statusLib[4] == statusLib[8] == symbol:
return [True, False, 8]
elif all(k is not None for k in statusLib):
return [True, True, 0]
else:
return [False, False, 0]
def finisher(self, fin):
lib = [[100, 100, 100, 500], [300, 100, 300, 500], [500, 100, 500, 500],
[100, 100, 500, 100], [100, 300, 500, 300], [100, 500, 500, 500],
[500, 100, 100, 500], [100, 100, 500, 500]]
if fin != 0:
self.canvas.create_line(lib[fin - 1][0], lib[fin - 1][1],
lib[fin - 1][2], lib[fin - 1][3],
fill='#1874CD', width=5)
if __name__ == '__main__':
root = tk.Tk()
root.title('Tic Tac Toe')
root.minsize(width=300, height=300)
statusLib = [None for i in range(9)]
mode = tk.IntVar()
AppMain(master=root)
root.mainloop()
python beginner python-3.x tic-tac-toe tkinter
$endgroup$
add a comment |
$begingroup$
I am completely new to programming and to python and as my first self-learning project I am creating a simple Tic-Tac-Toe game. I have already posted a version of my code here on stack:
Tic Tac Toe game in Python 3.X using tkinter UI
However, after I've spent some time learning and came back to the code - I have found a whole bunch of problems with it and decided to try and fix it myself. In addition to that I've switched from procedural tkinter GUI approach to the object-oriented tkinter GUI approach. I'm still not sure if I'm doing things the right way. Thus, I seek your advice.
Note: choosing a setting in settings window does nothing for now. I am planning on implementing this feature in the future. I left it to get advice on creating radiobuttons and handling their control variables.
import random
import tkinter as tk
import tkinter.ttk as ttk
class AppMain:
def __init__(self, master):
self.master = master
self.frame = ttk.Frame(master, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.play = ttk.Button(self.frame, text='Play',
command=lambda: PlayMenu(do=0))
self.settings = ttk.Button(self.frame, text='Settings',
command=SettingsWindow)
self.qb = ttk.Button(self.frame, text="Quit", command=root.destroy)
self.main_window()
def main_window(self):
self.remove_widgets()
self.frame.pack(padx=25, pady=75)
self.play.pack(side='top', pady=(33, 0))
self.settings.pack(side='top', pady=5)
self.qb.pack(side='top', pady=(0, 32))
def remove_widgets(self):
for widget in self.master.winfo_children():
widget.pack_forget()
class SettingsWindow(AppMain):
def __init__(self):
self.frame = ttk.Frame(root, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.rb1 = ttk.Radiobutton(self.frame, text='Easy', variable=mode,
value=0)
self.rb2 = ttk.Radiobutton(self.frame, text='Impossible',
variable=mode, value=1)
self.rb3 = ttk.Radiobutton(self.frame, text='2 players',
variable=mode, value=2)
self.back = ttk.Button(self.frame, text='Back',
command=lambda: AppMain(master=root))
self.settings_window()
def settings_window(self):
r = AppMain(master=root)
r.remove_widgets()
self.frame.pack(padx=25, pady=75)
self.rb1.pack(side='top', pady=(10, 0))
self.rb2.pack(side='top', pady=(10, 0))
self.rb3.pack(side='top', padx=(0, 22), pady=(10, 0))
self.back.pack(side='top', pady=(16, 16))
class PlayMenu(AppMain):
def __init__(self, do):
self.do = do
self.label = ttk.Label(root, text='Choose your side',
font=('French Script MT', 20))
self.frame = ttk.Frame(root, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.player_x = ttk.Button(self.frame, text='X',
command=lambda: GameWindow(pl='X', pc='O'))
self.player_o = ttk.Button(self.frame, text='O',
command=lambda: GameWindow(pl='O', pc='X'))
self.back = ttk.Button(self.frame, text='Back',
command=lambda: AppMain(master=root))
if do == 'redeclare':
global statusLib
statusLib = [None for v in range(9)]
self.play_menu()
def play_menu(self):
r = AppMain(master=root)
r.remove_widgets()
self.label.pack(side='top', pady=(25, 0))
self.frame.pack(padx=25, pady=25)
self.player_x.grid(column=0, row=0, padx=(5, 0), pady=(5, 0))
self.player_o.grid(column=1, row=0, padx=(0, 5), pady=(5, 0))
self.back.grid(column=0, row=1, sticky='w, e', padx=(5, 5), pady=(0, 5),
columnspan=2)
class GameWindow(AppMain):
def __init__(self, pl, pc):
self.pl, self.pc, self.stop_game = pl, pc, False
self.frame = ttk.Frame(root, width=650, height=700)
self.frame.pack_propagate(False)
self.canvas = tk.Canvas(self.frame, width=600, height=600)
self.restart = ttk.Button(self.frame, text='Restart',
command=lambda: PlayMenu(do='redeclare'))
self.game_window()
def game_window(self):
r = AppMain(master=root)
r.remove_widgets()
self.frame.pack()
self.canvas.pack(side='top', pady=(25, 0))
self.restart.pack(side='bottom', pady=20)
self.draw_board()
self.canvas.bind('<Button-1>', self.square_selector)
if self.pl == 'O':
self.computer_move()
def draw_board(self):
self.canvas.create_line(0, 200, 600, 200)
self.canvas.create_line(0, 400, 600, 400)
self.canvas.create_line(200, 0, 200, 600)
self.canvas.create_line(400, 0, 400, 600)
def square_selector(self, event):
self.player_move(square=(event.x // 200 * 3 + event.y // 200))
def player_move(self, square):
if statusLib[square] is None:
self.make_move(sq=square, symbol=self.pl, turn='player')
if not self.stop_game:
self.computer_move()
def computer_move(self):
status, square = 0, None
while status is not None:
square = random.randint(0, 8)
status = statusLib[square]
self.make_move(sq=square, symbol=self.pc, turn='computer')
def make_move(self, sq, symbol, turn):
self.draw_move(symbol=symbol, sq=sq)
statusLib[sq] = symbol
self.end_game(this_move=turn, symbol=symbol)
def draw_move(self, symbol, sq):
pos = [100 + sq // 3 * 200, 100 + sq % 3 * 200]
self.canvas.create_text(pos, text=symbol, font=('French Script MT', 50),
anchor='center')
def end_game(self, this_move, symbol):
condition = self.check_end_game(symbol=symbol)
self.stop_game = condition[0]
text = ''
if condition[0]:
self.canvas.unbind('<Button-1>')
if this_move == 'player' and not condition[1]:
text = 'You win'
elif this_move == 'computer' and not condition[1]:
text = 'You lose'
elif condition[1]:
text = 'It's a tie'
self.finisher(fin=condition[2])
self.canvas.create_text(300, 300, text=text,
font=('French Script MT', 50),
fill='#EE2C2C')
@staticmethod
def check_end_game(symbol):
if statusLib[0] == statusLib[1] == statusLib[2] == symbol:
return [True, False, 1]
elif statusLib[3] == statusLib[4] == statusLib[5] == symbol:
return [True, False, 2]
elif statusLib[6] == statusLib[7] == statusLib[8] == symbol:
return [True, False, 3]
elif statusLib[0] == statusLib[3] == statusLib[6] == symbol:
return [True, False, 4]
elif statusLib[1] == statusLib[4] == statusLib[7] == symbol:
return [True, False, 5]
elif statusLib[2] == statusLib[5] == statusLib[8] == symbol:
return [True, False, 6]
elif statusLib[2] == statusLib[4] == statusLib[6] == symbol:
return [True, False, 7]
elif statusLib[0] == statusLib[4] == statusLib[8] == symbol:
return [True, False, 8]
elif all(k is not None for k in statusLib):
return [True, True, 0]
else:
return [False, False, 0]
def finisher(self, fin):
lib = [[100, 100, 100, 500], [300, 100, 300, 500], [500, 100, 500, 500],
[100, 100, 500, 100], [100, 300, 500, 300], [100, 500, 500, 500],
[500, 100, 100, 500], [100, 100, 500, 500]]
if fin != 0:
self.canvas.create_line(lib[fin - 1][0], lib[fin - 1][1],
lib[fin - 1][2], lib[fin - 1][3],
fill='#1874CD', width=5)
if __name__ == '__main__':
root = tk.Tk()
root.title('Tic Tac Toe')
root.minsize(width=300, height=300)
statusLib = [None for i in range(9)]
mode = tk.IntVar()
AppMain(master=root)
root.mainloop()
python beginner python-3.x tic-tac-toe tkinter
$endgroup$
I am completely new to programming and to python and as my first self-learning project I am creating a simple Tic-Tac-Toe game. I have already posted a version of my code here on stack:
Tic Tac Toe game in Python 3.X using tkinter UI
However, after I've spent some time learning and came back to the code - I have found a whole bunch of problems with it and decided to try and fix it myself. In addition to that I've switched from procedural tkinter GUI approach to the object-oriented tkinter GUI approach. I'm still not sure if I'm doing things the right way. Thus, I seek your advice.
Note: choosing a setting in settings window does nothing for now. I am planning on implementing this feature in the future. I left it to get advice on creating radiobuttons and handling their control variables.
import random
import tkinter as tk
import tkinter.ttk as ttk
class AppMain:
def __init__(self, master):
self.master = master
self.frame = ttk.Frame(master, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.play = ttk.Button(self.frame, text='Play',
command=lambda: PlayMenu(do=0))
self.settings = ttk.Button(self.frame, text='Settings',
command=SettingsWindow)
self.qb = ttk.Button(self.frame, text="Quit", command=root.destroy)
self.main_window()
def main_window(self):
self.remove_widgets()
self.frame.pack(padx=25, pady=75)
self.play.pack(side='top', pady=(33, 0))
self.settings.pack(side='top', pady=5)
self.qb.pack(side='top', pady=(0, 32))
def remove_widgets(self):
for widget in self.master.winfo_children():
widget.pack_forget()
class SettingsWindow(AppMain):
def __init__(self):
self.frame = ttk.Frame(root, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.rb1 = ttk.Radiobutton(self.frame, text='Easy', variable=mode,
value=0)
self.rb2 = ttk.Radiobutton(self.frame, text='Impossible',
variable=mode, value=1)
self.rb3 = ttk.Radiobutton(self.frame, text='2 players',
variable=mode, value=2)
self.back = ttk.Button(self.frame, text='Back',
command=lambda: AppMain(master=root))
self.settings_window()
def settings_window(self):
r = AppMain(master=root)
r.remove_widgets()
self.frame.pack(padx=25, pady=75)
self.rb1.pack(side='top', pady=(10, 0))
self.rb2.pack(side='top', pady=(10, 0))
self.rb3.pack(side='top', padx=(0, 22), pady=(10, 0))
self.back.pack(side='top', pady=(16, 16))
class PlayMenu(AppMain):
def __init__(self, do):
self.do = do
self.label = ttk.Label(root, text='Choose your side',
font=('French Script MT', 20))
self.frame = ttk.Frame(root, width=250, height=150, relief='groove')
self.frame.pack_propagate(False)
self.player_x = ttk.Button(self.frame, text='X',
command=lambda: GameWindow(pl='X', pc='O'))
self.player_o = ttk.Button(self.frame, text='O',
command=lambda: GameWindow(pl='O', pc='X'))
self.back = ttk.Button(self.frame, text='Back',
command=lambda: AppMain(master=root))
if do == 'redeclare':
global statusLib
statusLib = [None for v in range(9)]
self.play_menu()
def play_menu(self):
r = AppMain(master=root)
r.remove_widgets()
self.label.pack(side='top', pady=(25, 0))
self.frame.pack(padx=25, pady=25)
self.player_x.grid(column=0, row=0, padx=(5, 0), pady=(5, 0))
self.player_o.grid(column=1, row=0, padx=(0, 5), pady=(5, 0))
self.back.grid(column=0, row=1, sticky='w, e', padx=(5, 5), pady=(0, 5),
columnspan=2)
class GameWindow(AppMain):
def __init__(self, pl, pc):
self.pl, self.pc, self.stop_game = pl, pc, False
self.frame = ttk.Frame(root, width=650, height=700)
self.frame.pack_propagate(False)
self.canvas = tk.Canvas(self.frame, width=600, height=600)
self.restart = ttk.Button(self.frame, text='Restart',
command=lambda: PlayMenu(do='redeclare'))
self.game_window()
def game_window(self):
r = AppMain(master=root)
r.remove_widgets()
self.frame.pack()
self.canvas.pack(side='top', pady=(25, 0))
self.restart.pack(side='bottom', pady=20)
self.draw_board()
self.canvas.bind('<Button-1>', self.square_selector)
if self.pl == 'O':
self.computer_move()
def draw_board(self):
self.canvas.create_line(0, 200, 600, 200)
self.canvas.create_line(0, 400, 600, 400)
self.canvas.create_line(200, 0, 200, 600)
self.canvas.create_line(400, 0, 400, 600)
def square_selector(self, event):
self.player_move(square=(event.x // 200 * 3 + event.y // 200))
def player_move(self, square):
if statusLib[square] is None:
self.make_move(sq=square, symbol=self.pl, turn='player')
if not self.stop_game:
self.computer_move()
def computer_move(self):
status, square = 0, None
while status is not None:
square = random.randint(0, 8)
status = statusLib[square]
self.make_move(sq=square, symbol=self.pc, turn='computer')
def make_move(self, sq, symbol, turn):
self.draw_move(symbol=symbol, sq=sq)
statusLib[sq] = symbol
self.end_game(this_move=turn, symbol=symbol)
def draw_move(self, symbol, sq):
pos = [100 + sq // 3 * 200, 100 + sq % 3 * 200]
self.canvas.create_text(pos, text=symbol, font=('French Script MT', 50),
anchor='center')
def end_game(self, this_move, symbol):
condition = self.check_end_game(symbol=symbol)
self.stop_game = condition[0]
text = ''
if condition[0]:
self.canvas.unbind('<Button-1>')
if this_move == 'player' and not condition[1]:
text = 'You win'
elif this_move == 'computer' and not condition[1]:
text = 'You lose'
elif condition[1]:
text = 'It's a tie'
self.finisher(fin=condition[2])
self.canvas.create_text(300, 300, text=text,
font=('French Script MT', 50),
fill='#EE2C2C')
@staticmethod
def check_end_game(symbol):
if statusLib[0] == statusLib[1] == statusLib[2] == symbol:
return [True, False, 1]
elif statusLib[3] == statusLib[4] == statusLib[5] == symbol:
return [True, False, 2]
elif statusLib[6] == statusLib[7] == statusLib[8] == symbol:
return [True, False, 3]
elif statusLib[0] == statusLib[3] == statusLib[6] == symbol:
return [True, False, 4]
elif statusLib[1] == statusLib[4] == statusLib[7] == symbol:
return [True, False, 5]
elif statusLib[2] == statusLib[5] == statusLib[8] == symbol:
return [True, False, 6]
elif statusLib[2] == statusLib[4] == statusLib[6] == symbol:
return [True, False, 7]
elif statusLib[0] == statusLib[4] == statusLib[8] == symbol:
return [True, False, 8]
elif all(k is not None for k in statusLib):
return [True, True, 0]
else:
return [False, False, 0]
def finisher(self, fin):
lib = [[100, 100, 100, 500], [300, 100, 300, 500], [500, 100, 500, 500],
[100, 100, 500, 100], [100, 300, 500, 300], [100, 500, 500, 500],
[500, 100, 100, 500], [100, 100, 500, 500]]
if fin != 0:
self.canvas.create_line(lib[fin - 1][0], lib[fin - 1][1],
lib[fin - 1][2], lib[fin - 1][3],
fill='#1874CD', width=5)
if __name__ == '__main__':
root = tk.Tk()
root.title('Tic Tac Toe')
root.minsize(width=300, height=300)
statusLib = [None for i in range(9)]
mode = tk.IntVar()
AppMain(master=root)
root.mainloop()
python beginner python-3.x tic-tac-toe tkinter
python beginner python-3.x tic-tac-toe tkinter
edited 24 mins ago
Jamal♦
30.3k11119227
30.3k11119227
asked Feb 1 at 15:17
Aivaras KazakevičiusAivaras Kazakevičius
11115
11115
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212699%2ftic-tac-toe-game-in-python-3-x-using-tkinter-gui-version-2%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f212699%2ftic-tac-toe-game-in-python-3-x-using-tkinter-gui-version-2%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown