struct Peg
{
   private struct Disk
   {
       private int size;

       picture draw(pen p = pink+1mm)
       {
           picture pic;
           fill(pic, scale(5mm+size*7.5mm, 4mm)*box((-1/2,-1/2),(1/2,1/2)), p);
           label(pic, string(size));
           return pic;
       }
       void operator init(int size)
       {
           this.size = size;
       }
   }

   private Disk[] disks;
   private string name;

   string getname()
   {
       return name;
   }

   picture draw(pen p = blue+1mm)
   {
       picture pic;
       int n = disks.length;
       fill(pic, box((-2mm, -4mm),(2mm,40mm)), gray);
       fill(pic, box((-4cm, -10mm), (4cm, -4mm)), gray);
       label(pic, name, (0,-5mm), align=down);
       for (int k = 0; k < n; ++k)
           add(pic, disks[k].draw(), (0,k*5mm));
       return pic;
   }

   void operator init(int n, string name)
   {
       for (int k = n; k > 0; --k)
           disks.push(Disk(k));
       this.name = name;
   }

   static void transfer(Peg a, Peg b)
   {
       Disk disk = a.disks.pop();
       b.disks.push(disk);
   }
}
from Peg unravel transfer;


import animation;
//usepackage("animate");
//usepackage("movie15");
settings.tex = "pdflatex";

void solvehanoi(int n)
{
   animation ani;
   int step = 0;
   Peg A = Peg(n,"A"), B = Peg(0,"B"), C = Peg(0,"C");

   picture pic;
   add(pic, A.draw().fit(), 0, align=NW);
   add(pic, B.draw().fit(), 0, align=NE);
   add(pic, C.draw().fit(), 0, align=S);
   ani.add(pic);
   void solve(Peg src, Peg dest, Peg mid, int k)
   {
       if (k != 0) {
           solve(src, mid, dest, k-1);

           transfer(src, dest);
           ++step;
           write(format("%3d: ", step)
                   + src.getname() + " -> " + dest.getname());
           picture pic;
           add(pic, A.draw().fit(), 0, align=NW);
           add(pic, B.draw().fit(), 0, align=NE);
           add(pic, C.draw().fit(), 0, align=S);
           ani.add(pic);

           solve(mid, dest, src, k-1);
       }
   }
   solve(A, B, C, n);
   //label(ani.pdf(delay=500));
   ani.movie(delay=500);
}

solvehanoi(2);