For a general description of the game, see http://en.wikipedia.org/wiki/Tower_of_Hanoi.
Requires JSAnimation and JSAnimation_frametools.
See http://faculty.washington.edu/rjl/classes/am583s2014/notes/animation.html.
In [ ]:
from pylab import *
In [ ]:
from JSAnimation import IPython_display
import JSAnimation_frametools as J
In [ ]:
def plot_disk(j,n,peg,position):
"""
plot disk number j out of n (j=1 is the smallest, j=n the largest)
also specify which peg (1,2, or 3) to plot it on, and its position.
position=1 means it is on the base, position=2 is on top of one other disk, etc.
"""
width = j/float(n) # actually the half-width of the jth disk
height = 1./float(n) # so n of them fit between 0 and 1 in y-direction
xpeg = 1 + 2.5*(peg-1) # location of this peg (they are at x = 1, 3.5, 7)
x = [xpeg-width, xpeg+width, xpeg+width, xpeg-width, xpeg-width]
y0 = (position-1)*height
y = [y0, y0, y0+height, y0+height, y0]
fill(x,y,'r') # fill in a rectangle with red, specified by the 5 (x,y) points
def plot_pegs(n):
plot([0,7],[0,0],'k',linewidth=3)
plot([1,1],[0,1.2],'k',linewidth=3)
plot([3.5,3.5],[0,1.2],'k',linewidth=3)
plot([6,6],[0,1.2],'k',linewidth=3)
axis([0,7,0,1.5])
Create an empty directory to store png files for each frame, and define the function to plot the configuration at each step:
In [ ]:
plotdir = '_plots' # to store png files for each figure
J.make_plotdir(plotdir, clobber=True) # ok to clobber if it already exists
def plot_all_disks(n,peg,frameno):
close('all') # close all figures
plot_pegs(n)
for i in [1,2,3]:
disks = peg[i]
for j,disk in enumerate(disks):
plot_disk(disk,n,i,len(disks)-j)
J.save_frame(frameno,plotdir,verbose=False)
next_frameno = frameno+1
return next_frameno
In [ ]:
n = 4
peg = {}
peg[1] = range(1,n+1)
peg[2] = []
peg[3] = []
frameno = plot_all_disks(n,peg,frameno=0)
def move_disks2(itop, ibottom, from_peg, to_peg, frameno):
if itop > ibottom:
raise InputError("Require itop <= ibottom, got itop = %i, ibottom = %i" %(itop,ibottom))
if itop==ibottom:
print "Move Disk %i from Peg %i to Peg %i" % (itop, from_peg, to_peg)
peg[from_peg] = peg[from_peg][1:] # drop first element of list
peg[to_peg] = [itop] + peg[to_peg] # add as first element of list
figure()
frameno = plot_all_disks(n,peg,frameno)
else:
other_peg = 6 - from_peg - to_peg
# recursive call:
frameno = move_disks2(itop, ibottom-1, from_peg, other_peg, frameno)
frameno = move_disks2(ibottom, ibottom, from_peg, to_peg, frameno)
frameno = move_disks2(itop, ibottom-1, other_peg, to_peg, frameno)
return frameno
frameno = move_disks2(1,n,1,3, frameno=1)
In [ ]:
anim = J.make_anim(plotdir, figsize=(8,4))
anim
In [ ]:
J.make_html(anim, file_name="Towers.html", title="Towers of Hanoi")
In [ ]:
from IPython.display import FileLink
FileLink('Towers.html')
<_plots/frame0000.png>