Tower Hanoi - Why recursive draw only first and last steps?

please format code with </> button * homework policy * asking questions

int h=50;
int w=100;
int size=3;
int flag=0;
int[][] Array = { {1,2,3}, {0,0,0}, {0,0,0 } };
int[] Top={ 0, -1, 2, 2};
void setup() {
size(1200,500);
// Array[0][0]=1;
// Array[1][0]=2;
// Array[2][0]=3;
// Array[0][1]=0;
// Array[1][1]=0;
// Array[2][1]=0;
// Array[0][2]=0;
// Array[1][2]=0;
// Array[2][2]=0;

// draw_hanoi();
//hanoi(3,1,2,3);

}

void draw() {

if (flag==0)
{
draw_hanoi();
hanoi(3,1,2,3);
flag=1;
}

}

void draw_hanoi() {
fill(51);
rect(0,0,1200,500);
fill(200);
for (col=0;col<3;col++) {
for (ring=(size-1);ring>=0;ring–) {
if (Array[col][ring]!=0) {
rect(150+300*col+(size-ring-1)50,h(ring+1),(Array[col][ring])*w,h);
}
}
}
delay(100);
}

void hanoi(int n, int from_t,int to_t, int via_t)
{
if(n>0) {
hanoi(n-1,from_t,via_t,to_t);
Top[from_t]=Top[from_t]+1;
Array[to_t-1][Top[to_t]]=Array[from_t-1][Top[from_t]];
Top[to_t]=Top[to_t]-1;
Array[from_t-1][Top[from_t]]=0;
draw_hanoi();
// delay(2000);
hanoi(n-1,via_t,to_t,from_t);
}

Unfortunately,
draw() updates the screen only once at its end and not throughout. Bad.

So cannot see anything in the recursion.

There are ways to address this with a second thread
and a PImage

Also @jeremydouglass wrote something for that

Hello @dyehuda,

A similar issue regarding animation of another recursion was discussed here: Is my fractal optimized? Could it animate?.

For a strategy that you might be able to use as a model for your project, see this post within that discussion.

1 Like

I made this Towers of Hanoi a few years ago and ran into the same issue. My solution was to put it on a separate Thread.

import java.util.Stack;
import java.lang.Runnable;
boolean start = true;
final int DELAY = 500;
final int OFFSET = 150;
final int RING_CURVE = 90;
final int RING_HEIGHT = 30;
final int RING_LENGTH_STEP = 10;
final int RING_START_HEIGHT = 370;
final int RING_MAX_LENGTH = 250;
final int PEG_LEFT = 175;
final int PEG_MIDDLE = 475;
final int PEG_RIGHT = 800-25;
final int NUMBER_OF_DISK = 9;
Stack<Ring>ringsA = new Stack<Ring>();
Stack<Ring>ringsB = new Stack<Ring>();
Stack<Ring>ringsC = new Stack<Ring>();
Stack[] tower = {ringsA, ringsB, ringsC};
void setup() {
  size(1000, 500);
  for (int i = 0; i < NUMBER_OF_DISK; i++) {
    ringsA.push(new Ring(RING_MAX_LENGTH - i*20, color(random(255), random(255), random(255)), 20));
  }
   
   new Thread(new Runnable() {
      
      @Override
      public void run() {
        towersOfHanoi(n, from, aux, to);        
      }
    }
    ).start();
}

void drawBackground() {
  background(100);
  fill(200);
  for (int i = 0; i < 3; i++) {
    rect(OFFSET + i*300, 100, 50, 300, 10);
  }
  rect(0, 400, width, 50);
}

void towersOfHanoi(int n, int from, int aux, int to){
  if(n==1){
    move(from,to);
    delay(DELAY);
  }
  else{
     towersOfHanoi(n-1,from,to,aux);
     move(from, to);
     delay(DELAY);
     towersOfHanoi(n-1,aux,from,to);
  }
}
int n= NUMBER_OF_DISK;
int from = 0;
int aux = 1;
int to = 2;
void draw() {
  refresh();
  println("test");
}
void refresh() {
  drawBackground();
  int currentRingHeight = RING_START_HEIGHT;
  for (int i = 0; i < ringsA.size(); i++) {
    Ring r=ringsA.get(i);
    fill(r.getColor());
    rect(PEG_LEFT - (r.getSize()/2), currentRingHeight, r.getSize(), RING_HEIGHT, RING_CURVE);
    currentRingHeight -= RING_HEIGHT;
  }
  currentRingHeight = RING_START_HEIGHT;
   for (int i = 0; i < ringsB.size(); i++) {
    Ring r=ringsB.get(i);
    fill(r.getColor());
    rect(PEG_MIDDLE - (r.getSize()/2), currentRingHeight, r.getSize(), RING_HEIGHT, RING_CURVE);
    currentRingHeight -= RING_HEIGHT;
  }

  currentRingHeight = RING_START_HEIGHT;
   for (int i = 0; i < ringsC.size(); i++) {
    Ring r=ringsC.get(i);
    fill(r.getColor());
    rect(PEG_RIGHT - (r.getSize()/2), currentRingHeight, r.getSize(), RING_HEIGHT, RING_CURVE);
    currentRingHeight -= RING_HEIGHT;
  }
}
/* --=-- TOWER OF HANOI --=--
 GOAL:
 Move all of the rings from the leftmost peg to the rightmost peg.
 
 RULES:
 1. You can only move 1 ring at a time.
 2. Rings cannot be placed on rings that are smaller than they are(ex. the bottem ring could not be placed on top ring)
 */

void move(int orgin, int dest) {
  if (orgin != dest && orgin < 3 && dest < 3) {
    if (!tower[orgin].isEmpty()) {
      if (tower[dest].isEmpty()) {
        tower[dest].push(tower[orgin].pop());
      } else {
        if (((Ring)tower[orgin].peek()).getSize() < ((Ring) tower[dest].peek()).getSize()) {
          tower[dest].push(tower[orgin].pop());
        } else {
          System.err.println("RING TOO BIG");
          return;
        }
      }
    } else {
      System.err.println("PEG DOES NOT HAVE RINGS");
    }
  }
  //System.out.println("NUMBER ERROR");
}
class Ring {
  int size;
  color c;
  int position;

  Ring(int size, color c, int position) {
    this.size = size;
    this.c = c;
    this. position = position;
  }
  color getColor() {
    return c;
  }
  int getSize() {
    return size;
  }

  int getPosition() {
    return position;
  }

  void setPostition(int size) {
    this.size = size;
  }
}


2 Likes

Thank you very much for the information

1 Like