"""Demo to show how to solve the Tower of Hanoi""" # Credits: # https://github.com/gjbex/training-material/blob/master/Misc/Notebooks/hanoi.ipynb # Creative Commons Zero v1.0 Universal licence from vedo import Plotter, Cylinder, Box from copy import deepcopy class Hanoi: def __init__(self, nr_disks): self._nr_disks = nr_disks self._towers = [list(range(nr_disks, 0, -1)), list(), list()] @property def nr_disks(self): return self._nr_disks @property def nr_moves(self): return 2**self.nr_disks - 1 @property def towers(self): return deepcopy(self._towers) def tower(self, n): return self._towers[n].copy() def move_disk(self, from_tower, to_tower): disk = self._towers[from_tower].pop() self._towers[to_tower].append(disk) return disk, from_tower, to_tower def move_disks(self, n, from_tower, to_tower): if n == 1: yield self.move_disk(from_tower, to_tower) else: helper = 3 - from_tower - to_tower yield from self.move_disks(n - 1, from_tower, helper) yield self.move_disk(from_tower, to_tower) yield from self.move_disks(n - 1, helper, to_tower) def moves(self): yield from self.move_disks(self.nr_disks, 0, 1) nr_disks = 5 hanoi = Hanoi(nr_disks) tower_states = list([hanoi.towers]) for _ in hanoi.moves(): tower_states.append(hanoi.towers) disks = { hanoi.nr_disks - i : Cylinder(r=0.2*(hanoi.nr_disks-i+1), c=i) for i in range(hanoi.nr_disks) } plt = Plotter(interactive=False, size=(800, 600), bg='wheat', bg2='lb') plt += list(disks.values()) plt += Box(pos=(3,0,-0.5), size=(12,4,0.1)) cam = dict( pos=(14.60, -20.56, 7.680), focal_point=(3.067, 0.5583, 1.910), viewup=(-0.1043, 0.2088, 0.9724), ) plt.show(camera=cam) for t in range(len(tower_states)): state = tower_states[t] for tower_nr in range(3): for i, disk in enumerate(state[tower_nr]): disks[disk].pos([3 * tower_nr, 0, i+0.5]) plt.render() plt.interactive().close()