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













0












$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()









share|improve this question











$endgroup$

















    0












    $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()









    share|improve this question











    $endgroup$















      0












      0








      0





      $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()









      share|improve this question











      $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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 24 mins ago









      Jamal

      30.3k11119227




      30.3k11119227










      asked Feb 1 at 15:17









      Aivaras KazakevičiusAivaras Kazakevičius

      11115




      11115






















          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
          });


          }
          });














          draft saved

          draft discarded


















          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
















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          is 'sed' thread safeWhat should someone know about using Python scripts in the shell?Nexenta bash script uses...

          How do i solve the “ No module named 'mlxtend' ” issue on Jupyter?

          Pilgersdorf Inhaltsverzeichnis Geografie | Geschichte | Bevölkerungsentwicklung | Politik | Kultur...