hanoi3d.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. """Demo to show how to solve the Tower of Hanoi"""
  2. # Credits:
  3. # https://github.com/gjbex/training-material/blob/master/Misc/Notebooks/hanoi.ipynb
  4. # Creative Commons Zero v1.0 Universal licence
  5. from vedo import Plotter, Cylinder, Box
  6. from copy import deepcopy
  7. class Hanoi:
  8. def __init__(self, nr_disks):
  9. self._nr_disks = nr_disks
  10. self._towers = [list(range(nr_disks, 0, -1)), list(), list()]
  11. @property
  12. def nr_disks(self):
  13. return self._nr_disks
  14. @property
  15. def nr_moves(self):
  16. return 2**self.nr_disks - 1
  17. @property
  18. def towers(self):
  19. return deepcopy(self._towers)
  20. def tower(self, n):
  21. return self._towers[n].copy()
  22. def move_disk(self, from_tower, to_tower):
  23. disk = self._towers[from_tower].pop()
  24. self._towers[to_tower].append(disk)
  25. return disk, from_tower, to_tower
  26. def move_disks(self, n, from_tower, to_tower):
  27. if n == 1:
  28. yield self.move_disk(from_tower, to_tower)
  29. else:
  30. helper = 3 - from_tower - to_tower
  31. yield from self.move_disks(n - 1, from_tower, helper)
  32. yield self.move_disk(from_tower, to_tower)
  33. yield from self.move_disks(n - 1, helper, to_tower)
  34. def moves(self):
  35. yield from self.move_disks(self.nr_disks, 0, 1)
  36. nr_disks = 5
  37. hanoi = Hanoi(nr_disks)
  38. tower_states = list([hanoi.towers])
  39. for _ in hanoi.moves():
  40. tower_states.append(hanoi.towers)
  41. disks = { hanoi.nr_disks - i : Cylinder(r=0.2*(hanoi.nr_disks-i+1), c=i)
  42. for i in range(hanoi.nr_disks) }
  43. plt = Plotter(interactive=False, size=(800, 600), bg='wheat', bg2='lb')
  44. plt += list(disks.values())
  45. plt += Box(pos=(3,0,-0.5), size=(12,4,0.1))
  46. cam = dict(
  47. pos=(14.60, -20.56, 7.680),
  48. focal_point=(3.067, 0.5583, 1.910),
  49. viewup=(-0.1043, 0.2088, 0.9724),
  50. )
  51. plt.show(camera=cam)
  52. for t in range(len(tower_states)):
  53. state = tower_states[t]
  54. for tower_nr in range(3):
  55. for i, disk in enumerate(state[tower_nr]):
  56. disks[disk].pos([3 * tower_nr, 0, i+0.5])
  57. plt.render()
  58. plt.interactive().close()