I want to create an AI move into my game, after the player does one. Is there any function I could use in order to let AI wait for few seconds before it makes a move? I already tried a canvas.after(), but it didn´t work properly (it also freezed my move).
[Tkinter] How to create a delay for AI without freezing the GUI
[Tkinter] How to create a delay for AI without freezing the GUI
|
May-03-2019, 05:03 PM
So I have read the Threads Guide, but got stucked on this point:
class Program: def __init__(self): self.width = 1000 self.height = 800 self.panel_width = 200 #self.root = Tk() self.canvas = tkinter.Canvas(width=self.width, height=self.height, bg="black") self.canvas.pack() self.canvas.bind("<ButtonPress>", self.click) self.figures_images = {"0": tkinter.PhotoImage(file="white_pawn.png"), ...} self.figures = {"0":[<class Pawn...>, (x,y), image_id],"1":[<class Pawn...>, (x,y), image_id],"2":[<class Pawn...>, (x,y), image_id],...} ... def create_layout(self): # not important for this problem def start_ai(self): ... move = Move_ai(self) # next methods are not important now class Pawn: def __init__(self, ...): ... # not important for this problem class Move_ai: def __init__(self, program): self.main = program thread = threading.Thread(target=self.move) thread.start() def move(self): time.sleep(3) # just to pretend PC is thinking ... # some code calculating which figure to move selected_id = ... # id of figure it decided to move with self.main.canvas.coords(self.main.figures_images[selected_id], tuple_of_coords) # ^ and this is that line raising an error to me, this one: To be honest, I don´t understand that solution described here very well, could you help me to solve this problem using and showing only that version of this solution, which my program really needs?
I've added headings to the various parts of the code in the link.
You have the error shown against the heading "Example of adding a thread but still getting a error" The solution is in the following code examples one with and one without decorators.
May-04-2019, 01:55 PM
Well I´m looking at the part "Example of adding a thread but still getting a error" but I have no idea how to suit it to my program. I have no buttons there and as I see, self.listbox.insert(tk.END, item) works with listbox I´m not using in my program.
May-04-2019, 02:00 PM
Look at "Example of a solution to the problem"
May-04-2019, 02:06 PM
Well, so I have changed my code so:
class Program: def __init__(self): self.width = 1000 self.height = 800 self.panel_width = 200 #self.root = Tk() self.canvas = tkinter.Canvas(width=self.width, height=self.height, bg="black") self.canvas.pack() self.canvas.bind("<ButtonPress>", self.click) self.figures_images = {"0": tkinter.PhotoImage(file="white_pawn.png"), ...} self.figures = {"0":[<class Pawn...>, (x,y), image_id],"1":[<class Pawn...>, (x,y), image_id],"2":[<class Pawn...>, (x,y), image_id],...} ... def create_layout(self): # not important for this problem def start_ai(self): ... move = Move_ai(self) # next methods are not important now class Pawn: def __init__(self, ...): ... # not important for this problem class Move_ai: def __init__(self, program): self.main = program thread_pool_executor = futures.ThreadPoolExecutor(max_workers=1) thread_pool_executor.submit(self.move) def move(self): time.sleep(3) # just to pretend PC is thinking ... # some code calculating which figure to move selected_id = ... # id of figure it decided to move with self.main.canvas.coords(self.main.figures_images[selected_id], tuple_of_coords) # ^ and this is that line raising an error to me, this one:And now it does not raise any error message, but it just freezes at point of canvas.coords (and no other moves are able to do). Did I forgot to implement something more from "Example of a solution to the problem"?
May-04-2019, 02:14 PM
You have to use the
canvas.after method for calling methods of the gui, it moves the calls back into the mainloops thread.The follwing is an code from that thread class MainFrame(tk.Frame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) .... .... def set_label_text(self, text=''): self.label['text'] = text def blocking_code(self): self.after(0, self.set_label_text, 'running') for number in range(5): self.after(0, self.listbox_insert, number) print(number) time.sleep(1) self.after(0, self.set_label_text, ' not running')In the method blocking_code self.after(0, self.set_label_text, 'running') is calling self.set_label_text back in the mainloops thread.
May-04-2019, 02:32 PM
If you just want to delay something the first argument to after is how long to wait in millisecs before calling the passed in callback.
import tkinter as tk import time class MainFrame(tk.Frame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.label = tk.Label(self, text='Player 1 turn') self.label.pack() self.button = tk.Button( self, text='Player 1 Move', command=self.on_button) self.button.pack(pady=15) self.pack() def on_button(self): print('Button clicked') self.label['text'] = 'player 2 thinking' self.button['state'] = 'disabled' self.after(3000, self.delayed_player_2) def delayed_player_2(self): self.label['text'] = 'player 2 moving' self.after(1000, self.player_2_finsihed) def player_2_finsihed(self): self.label['text'] = 'player 1 turn' self.button['state'] = 'normal' if __name__ == '__main__': app = tk.Tk() main_frame = MainFrame() app.mainloop() |
|
Possibly Related Threads… | |||||
Thread | Author | Replies | Views | Last Post | |
[Kivy] Asynchronous operation without window freezing | T800 | 0 | 645 |
Dec-06-2024, 05:40 AM Last Post: T800 |
|
[Tkinter] GUI keeps freezing | Fre3k | 2 | 4,706 |
May-23-2020, 05:41 PM Last Post: Fre3k |
|
[PyQt] How to open a program with python without freezing | LavaCreeperKing | 9 | 10,547 |
Aug-17-2019, 08:48 PM Last Post: LavaCreeperKing |
|
Gi module window freezing problem | loss | 0 | 2,680 |
May-05-2018, 04:42 PM Last Post: loss |
Users browsing this thread: 1 Guest(s)