Update hanoi.py - bug fix, speed adjustment.
This commit is contained in:
parent
08ccb4c68a
commit
f974ac14df
61
hanoi.py
61
hanoi.py
@ -13,6 +13,7 @@ GAP = 2
|
|||||||
CANVAS_W = 500
|
CANVAS_W = 500
|
||||||
CANVAS_H = 400
|
CANVAS_H = 400
|
||||||
gbl_speed = 0.001 # in seconds
|
gbl_speed = 0.001 # in seconds
|
||||||
|
gbl_step = 2
|
||||||
gbl_pegs = []
|
gbl_pegs = []
|
||||||
gbl_pegstate = [[], [], []]
|
gbl_pegstate = [[], [], []]
|
||||||
gbl_disks = []
|
gbl_disks = []
|
||||||
@ -24,13 +25,15 @@ gbl_ready = True
|
|||||||
def setup_gui():
|
def setup_gui():
|
||||||
global gbl_canvas
|
global gbl_canvas
|
||||||
|
|
||||||
def get_ent(event):
|
def ent_return(event):
|
||||||
|
event.widget.tk_focusNext().focus()
|
||||||
|
|
||||||
|
def get_ent_focus(event):
|
||||||
global gbl_num_disks
|
global gbl_num_disks
|
||||||
|
|
||||||
try:
|
try:
|
||||||
new_num = int(ent_disks.get())
|
new_num = int(ent_disks.get())
|
||||||
gbl_num_disks = new_num
|
gbl_num_disks = new_num
|
||||||
event.widget.tk_focusNext().focus()
|
|
||||||
draw_init_setting()
|
draw_init_setting()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
ent_disks.delete(0, tk.END)
|
ent_disks.delete(0, tk.END)
|
||||||
@ -43,40 +46,44 @@ def setup_gui():
|
|||||||
tk.Label(tk_row, text="No. of Disks: ").pack(side=tk.LEFT)
|
tk.Label(tk_row, text="No. of Disks: ").pack(side=tk.LEFT)
|
||||||
ent_disks = tk.Entry(tk_row, width=5)
|
ent_disks = tk.Entry(tk_row, width=5)
|
||||||
ent_disks.insert(0, str(gbl_num_disks))
|
ent_disks.insert(0, str(gbl_num_disks))
|
||||||
ent_disks.bind('<Return>', get_ent)
|
ent_disks.bind('<Return>', ent_return)
|
||||||
ent_disks.bind('<FocusOut>', get_ent)
|
ent_disks.bind('<FocusOut>', get_ent_focus)
|
||||||
ent_disks.pack(side=tk.LEFT, padx=5)
|
ent_disks.pack(side=tk.LEFT, padx=5)
|
||||||
btn_start = tk.Button(tk_row, text="Start", width=6)
|
btn_start = tk.Button(tk_row, text="Start", width=6, command=run_hanoi)
|
||||||
btn_start.bind('<ButtonRelease-1>', run_hanoi)
|
# btn_start.bind('<ButtonRelease-1>', run_hanoi)
|
||||||
btn_start.pack(side=tk.LEFT, padx=5)
|
btn_start.pack(side=tk.LEFT, padx=5)
|
||||||
btn_reset = tk.Button(tk_row, text="Reset", width=6)
|
btn_reset = tk.Button(tk_row, text="Reset", width=6, command=reset_hanoi)
|
||||||
btn_reset.bind('<ButtonRelease-1>', reset_hanoi)
|
# btn_reset.bind('<ButtonRelease-1>', reset_hanoi)
|
||||||
btn_reset.pack(side=tk.LEFT, padx=5)
|
btn_reset.pack(side=tk.LEFT, padx=5)
|
||||||
tk.Label(tk_row, text="Speed: ").pack(side=tk.LEFT)
|
tk.Label(tk_row, text="Speed: ").pack(side=tk.LEFT)
|
||||||
tk_var = tk.StringVar(gbl_tkroot)
|
tk_var = tk.StringVar(gbl_tkroot)
|
||||||
tk_var.set('normal')
|
tk_var.set('normal')
|
||||||
tk_opt_menu = tk.OptionMenu(tk_row, tk_var,
|
tk_opt_menu = tk.OptionMenu(tk_row, tk_var,
|
||||||
*{'slow', 'normal', 'fastest'})
|
*{'slow', 'normal', 'fastest'})
|
||||||
tk_opt_menu.config(width = 6)
|
tk_opt_menu.config(width=6, takefocus=True)
|
||||||
tk_opt_menu.pack(side=tk.LEFT)
|
tk_opt_menu.pack(side=tk.LEFT)
|
||||||
tk_row.pack(side=tk.TOP, pady=5)
|
tk_row.pack(side=tk.TOP, pady=5)
|
||||||
|
|
||||||
# animation canvas
|
# animation canvas
|
||||||
gbl_canvas = tk.Canvas(gbl_tkroot, width=CANVAS_W, height=CANVAS_H)
|
gbl_canvas = tk.Canvas(gbl_tkroot, width=CANVAS_W, height=CANVAS_H)
|
||||||
gbl_canvas.pack()
|
gbl_canvas.pack()
|
||||||
|
btn_start.focus_set()
|
||||||
|
|
||||||
def change_speed(*args):
|
def change_speed(*args):
|
||||||
global gbl_speed
|
global gbl_speed, gbl_step
|
||||||
speed_opt = {'slow': 0.002, 'normal': 0.001, 'fastest': 0}
|
speed_opt = {'slow': 0.001, 'normal': 0.001, 'fastest': 0}
|
||||||
|
step_opt = {'slow': 1, 'normal': 2, 'fastest': 1}
|
||||||
gbl_speed = speed_opt.get(tk_var.get())
|
gbl_speed = speed_opt.get(tk_var.get())
|
||||||
|
gbl_step = step_opt.get(tk_var.get())
|
||||||
# print(gbl_speed)
|
# print(gbl_speed)
|
||||||
|
|
||||||
tk_var.trace('w', change_speed)
|
tk_var.trace('w', change_speed)
|
||||||
|
|
||||||
|
|
||||||
def run_hanoi(event):
|
def run_hanoi():
|
||||||
global gbl_ready
|
global gbl_ready
|
||||||
|
|
||||||
|
# t0 = time.time()
|
||||||
if gbl_ready:
|
if gbl_ready:
|
||||||
gbl_ready = False
|
gbl_ready = False
|
||||||
try:
|
try:
|
||||||
@ -85,9 +92,11 @@ def run_hanoi(event):
|
|||||||
print(f'forced reset: {repr(err)}')
|
print(f'forced reset: {repr(err)}')
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
# t1 = time.time()
|
||||||
|
# print(t1-t0)
|
||||||
|
|
||||||
|
|
||||||
def reset_hanoi(event):
|
def reset_hanoi():
|
||||||
draw_init_setting()
|
draw_init_setting()
|
||||||
|
|
||||||
|
|
||||||
@ -133,6 +142,7 @@ def draw_init_setting():
|
|||||||
|
|
||||||
gbl_ready = True
|
gbl_ready = True
|
||||||
|
|
||||||
|
|
||||||
def move_disk(i, a, b):
|
def move_disk(i, a, b):
|
||||||
global gbl_pegstate, gbl_canvas
|
global gbl_pegstate, gbl_canvas
|
||||||
disk_num = gbl_pegstate[a].pop()
|
disk_num = gbl_pegstate[a].pop()
|
||||||
@ -147,7 +157,7 @@ def move_disk(i, a, b):
|
|||||||
x1, y1, x2, y2 = gbl_canvas.bbox(disk)
|
x1, y1, x2, y2 = gbl_canvas.bbox(disk)
|
||||||
if y2 < py1:
|
if y2 < py1:
|
||||||
break
|
break
|
||||||
gbl_canvas.move(disk, 0, -1)
|
gbl_canvas.move(disk, 0, -gbl_step)
|
||||||
gbl_tkroot.update_idletasks()
|
gbl_tkroot.update_idletasks()
|
||||||
gbl_tkroot.update()
|
gbl_tkroot.update()
|
||||||
time.sleep(gbl_speed)
|
time.sleep(gbl_speed)
|
||||||
@ -155,18 +165,24 @@ def move_disk(i, a, b):
|
|||||||
# Move to peg b
|
# Move to peg b
|
||||||
px1, py1, px2, py2 = gbl_canvas.bbox(gbl_pegs[b])
|
px1, py1, px2, py2 = gbl_canvas.bbox(gbl_pegs[b])
|
||||||
new_center = (px1 + px2) // 2
|
new_center = (px1 + px2) // 2
|
||||||
while True:
|
|
||||||
x1, y1, x2, y2 = gbl_canvas.bbox(disk)
|
x1, y1, x2, y2 = gbl_canvas.bbox(disk)
|
||||||
center = (x1 + x2) // 2
|
center = (x1 + x2) // 2
|
||||||
if center == new_center:
|
|
||||||
break
|
while center < new_center:
|
||||||
if center > new_center:
|
gbl_canvas.move(disk, gbl_step, 0)
|
||||||
gbl_canvas.move(disk, -1, 0)
|
|
||||||
else:
|
|
||||||
gbl_canvas.move(disk, 1, 0)
|
|
||||||
gbl_tkroot.update_idletasks()
|
gbl_tkroot.update_idletasks()
|
||||||
gbl_tkroot.update()
|
gbl_tkroot.update()
|
||||||
time.sleep(0.7*gbl_speed) # faster
|
time.sleep(0.7*gbl_speed) # faster
|
||||||
|
x1, y1, x2, y2 = gbl_canvas.bbox(disk)
|
||||||
|
center = (x1 + x2) // 2
|
||||||
|
|
||||||
|
while center > new_center:
|
||||||
|
gbl_canvas.move(disk, -gbl_step, 0)
|
||||||
|
gbl_tkroot.update_idletasks()
|
||||||
|
gbl_tkroot.update()
|
||||||
|
time.sleep(0.7*gbl_speed) # faster
|
||||||
|
x1, y1, x2, y2 = gbl_canvas.bbox(disk)
|
||||||
|
center = (x1 + x2) // 2
|
||||||
|
|
||||||
# Drop down
|
# Drop down
|
||||||
disk_h = y2 - y1
|
disk_h = y2 - y1
|
||||||
@ -175,7 +191,7 @@ def move_disk(i, a, b):
|
|||||||
x1, y1, x2, y2 = gbl_canvas.bbox(disk)
|
x1, y1, x2, y2 = gbl_canvas.bbox(disk)
|
||||||
if y2 >= new_bottom:
|
if y2 >= new_bottom:
|
||||||
break
|
break
|
||||||
gbl_canvas.move(disk, 0, 1)
|
gbl_canvas.move(disk, 0, gbl_step)
|
||||||
gbl_tkroot.update_idletasks()
|
gbl_tkroot.update_idletasks()
|
||||||
gbl_tkroot.update()
|
gbl_tkroot.update()
|
||||||
time.sleep(gbl_speed)
|
time.sleep(gbl_speed)
|
||||||
@ -188,7 +204,6 @@ def hanoi(n, a, b, c):
|
|||||||
Hanoi algorithm: move n pieces from a to c, using b as buffer.
|
Hanoi algorithm: move n pieces from a to c, using b as buffer.
|
||||||
For each move, call animate() to show the move
|
For each move, call animate() to show the move
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if n < 0:
|
if n < 0:
|
||||||
return
|
return
|
||||||
hanoi(n-1, a, c, b)
|
hanoi(n-1, a, c, b)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user