Tower Of Hanoi ( Graphical Illustration )

harshchandra 2 Tallied Votes 2K Views Share

The famous Tower Of Hanoi with graphics and animations.

#include <graphics.H>
#include <stdio.H>
#include <conio.H>
#include <dos.h>

#define YSize 20

int n,DELAY;
int IsManual=0,flag=1;

int DiskIsIn[5];
int PosInPeg[5];
int DiskCount[3];

void SetMode()
{	int gdriver = VGA, gmode=VGAMED;
	initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
}

void Box(int x1,int y1,int x2,int y2,int doit=1){
		int c2=WHITE,c1=DARKGRAY;
		if(doit){
			if(flag==0) flag=1;
			else flag=0;
			switch(flag){
				case 0:{ c1=WHITE; c2=DARKGRAY; break; }
				case 1:{ c2=WHITE; c1=DARKGRAY; break; }
			}
		}
		bar(x1,y1,x2,y2);
		setcolor(c1);
		line(x1,y1,x2,y1);
		line(x1,y1,x1,y2);
		setcolor(c2);
		line(x1,y2,x2,y2);
		line(x2,y1+1,x2,y2);
}

void DrawHanoi(int n){
	int i,x,y,size;
	for(i=0;i<n;i++){
		x=5+(DiskIsIn[i]*215)+((4-i)*20);
		y=150+PosInPeg[i]*30;
		size=40+i*40;
		setfillstyle(SOLID_FILL,10+i);
		Box(x,y,x+size,y+YSize);
	}
}

void MoveDisk(int Disk,int from, int to){
	int x,y,size=Disk*40,tx,ty;

	x=5+(DiskIsIn[Disk-1]*215)+((5-Disk)*20);
	y=150+PosInPeg[Disk-1]*30;
	do{
		setfillstyle(SOLID_FILL,BLACK);
		bar(x,y,x+size,y+YSize);
		y-=30;
		setfillstyle(SOLID_FILL,9+Disk);
		Box(x,y,x+size,y+YSize);
		if(IsManual) getch();
		else delay(DELAY);
	}while(y>60);

	tx=5+(to*215)+((5-Disk)*20);
	do{
		setfillstyle(SOLID_FILL,BLACK);
		bar(x,y,x+size,y+YSize);
		if(tx<x) x-=43; else x+=43;
		setfillstyle(SOLID_FILL,9+Disk);
		Box(x,y,x+size,y+YSize);
		if(IsManual) getch();
		else delay(DELAY);
	}while(x!=tx);

	PosInPeg[Disk-1]=n-1-DiskCount[to];
	DiskCount[to]++;
	DiskCount[from]--;
	DiskIsIn[Disk-1]=to;

	ty=150+PosInPeg[Disk-1]*30;
	do{
		setfillstyle(SOLID_FILL,BLACK);
		bar(x,y,x+size,y+YSize);
		y+=30;
		setfillstyle(SOLID_FILL,9+Disk);
		Box(x,y,x+size,y+YSize);
		if(IsManual) getch();
		else delay(DELAY);
	}while(y<ty);
}

void Towers(int n,int from,int to,int aux){
	if(n==1){
		MoveDisk(1,from,to);
		return;
	}
	if(kbhit()) return;
	Towers(n-1,from,aux,to);
	if(kbhit()) return;
	MoveDisk(n,from,to);
	Towers(n-1,aux,to,from);
}

int main(){
	int i;

	do{	printf("\nEnter no. of disks (1-5): ");
		scanf("%d",&n);
	}while((n<1)&&(n>5));
	DELAY=(6-n)*100;

	SetMode();
	settextstyle(TRIPLEX_FONT,HORIZ_DIR,1);
	setbkcolor(LIGHTGRAY);
	cleardevice();
	setfillstyle(SOLID_FILL,LIGHTGRAY);
	Box(150,13,490,33,0);
	Box(160,324,480,346,0);
	setcolor(WHITE);
	outtextxy(180,10,"T o w e r s   o f    H a n o i");
	outtextxy(205,321,"Press any key to S T O P");
	setcolor(DARKGRAY);
	outtextxy(181,11,"T o w e r s   o f    H a n o i");
	outtextxy(206,322,"Press any key to S T O P");

	DiskCount[0]=n;
	DiskCount[1]=0;
	DiskCount[2]=0;
	for(i=0;i<n;i++){	PosInPeg[i]=i; DiskIsIn[i]=0; }

	DrawHanoi(n);
	Towers(n,0,2,1);
	getch();
	closegraph();
	return 0;
}

Dani AI

Generated

This thread shows a nice, classic BGI-based Towers of Hanoi animation by and a useful GTK/Cairo port from that demonstrates a modern, flicker-free approach (pixmap/double buffering). Reports like 's "not working" are almost always environmental or tiny logic issues rather than problems with the Hanoi algorithm itself.

Troubleshooting checklist and quick fixes:

  • The code uses Borland/Turbo C DOS APIs (graphics.h, conio.h, dos.h) and expects BGI drivers under c:\tc\bgi. Modern compilers do not provide those. Run the original in DOSBox/Turbo C, or use a BGI-compatible wrapper (WinBGIm) or port to a modern library (GTK/SDL/Qt). 's GTK port is a ready example of the latter.
  • Input validation bug: the loop that reads the number of disks uses the wrong logical test, which can allow values outside 1..5. That can produce negative delay or other odd behavior—validate and clamp n to the intended range.
  • Ensure library/include/linker paths are correct if you try a WinBGIm or MinGW build. Missing drivers or wrong include paths are the common compile/link failures.
  • Flicker and animation: draw to an offscreen buffer (pixmap) and blit to the window; avoid repeatedly clearing the whole screen. Use event-driven timers instead of blocking delay/getch for smoother UX.

Porting tips and improvements: compute disk sizes from the window dimensions so the animation scales; replace magic numbers with named constants; validate array bounds for disk/peg indices. For or anyone wanting bar/pie charts, choose a GUI or plotting library (GTK/Cairo, Qt, SDL, or a language like Python with Matplotlib) rather than trying to extend old BGI code.

jim387 0 Unverified User

do you know how to code a bar or a pie graph??the outputof it would base on the user input...if ever you have pls help me and send me in my email add or ...thnks a lot and more power...advance happy holidays....

TkTkorrovi 69 Junior Poster

Thank you, good algorithm! The same using GTK, which shows that it's not very difficult to port simple graphics to another graphics library, i don't know though whether i guessed the colors right.

#include <gtk/gtk.h>
#include <stdlib.h>

int diskisin [5], posinpeg [5],
  diskcount [3], width = 655,
  height = 430, delay = 100000,
  ysize = 20, kbhit, n;
double cl [] [3] = {{1, 1, 1},
  {.5, .5, .5}, {0, 0, 1},
  {0, 1, 0}, {0, 1, 1},
  {1, 0, 0}, {1, 0, 1}};
GdkPixmap *pixmap;
GtkWidget *da;
cairo_t *cr;

void drawscreen ()
{
  if (kbhit) return;
  gtk_widget_queue_draw_area
  (da, 0, 0, width, height);
  for (g_usleep (delay);
    g_main_context_iteration
    (0, 0); );
}

void rectangle (int x, int y,
  int width, int height,
  int cn)
{
  cairo_set_source_rgb (cr,
  cl [cn] [0], cl [cn] [1],
    cl [cn] [2]);
  cairo_rectangle (cr, x, y,
    width, height);
  cairo_fill (cr);
}

void dostep (int *x, int *y,
  int xd, int yd, int size,
  int disk)
{
  rectangle (*x, *y, size,
    ysize, 0);
  rectangle (*x += xd,
    *y += yd, size, ysize,
    disk + 1);
  drawscreen ();
}

void movedisk (int disk,
  int from, int to)
{
  int size = disk * 40, tx, ty,
    x, y;

  x = 5 + diskisin [disk - 1] *
    215 + (5 - disk) * 20;
  y = 150 +
    posinpeg [disk - 1] * 30;
  while (y > 60)
    dostep (&x, &y, 0, -30,
      size, disk);
  tx = 5 + to * 215 +
    (5 - disk) * 20;
  while (x != tx)
    dostep (&x, &y, tx < x ?
      -43 : 43, 0, size, disk);
  posinpeg [disk - 1] = n - 1 -
    diskcount [to]++;
  diskcount [from]--;
  diskisin [disk - 1] = to;
  ty = 150 +
    posinpeg [disk - 1] * 30;
  while (y < ty)
    dostep (&x, &y, 0, 30,
      size, disk);
}

void towers (int n, int from,
  int to, int aux)
{
  if (n == 1) {
    movedisk (1, from, to);
    return;
  }
  if (kbhit) return;
  towers (n - 1, from, aux,
    to);
  if (kbhit) return;
  movedisk (n, from, to);
  towers (n - 1, aux, to,
    from);
}

gint expose_event ()
{
  gdk_draw_drawable
    (da->window,
    da->style->white_gc,
    pixmap, 0, 0, 0, 0, width,
    height);
  return 0;
}
 
gint shut ()
{
  kbhit = 1;
  return 0;
}

int main (int argc,
  char **argv)
{
  int i;
  char buf [FILENAME_MAX];
  GtkWidget *window;
  PangoFontDescription *font;
  PangoLayout *text;

  gtk_init (&argc, &argv);
  window = gtk_window_new
    (GTK_WINDOW_TOPLEVEL);
  gtk_widget_set_size_request
    (window, width, height);
  gtk_window_set_resizable
    (GTK_WINDOW (window), 0);
  gtk_window_set_title
    (GTK_WINDOW (window),
    "Towers of Hanoi");
  da = gtk_drawing_area_new ();
  gtk_container_add
    (GTK_CONTAINER (window),
    da);
  gtk_widget_set_events
    (window,
    GDK_KEY_PRESS_MASK);
  g_signal_connect (window,
    "delete_event",
    G_CALLBACK (shut), 0);
  g_signal_connect
    (G_OBJECT (window),
    "key_press_event",
    G_CALLBACK (shut), 0);
  g_signal_connect
    (G_OBJECT (da),
    "expose_event",
    G_CALLBACK (expose_event),
    0);
  /* before pixmap, gc etc */
  gtk_widget_show_all (window);
  text =
gtk_widget_create_pango_layout
    (da, "T o w e r s   o f"
    "    H a n o i");
  font =
pango_font_description_from_string
    ("monospace bold");
pango_font_description_set_absolute_size
    (font, 16 * PANGO_SCALE);
pango_layout_set_font_description
    (text, font);
  pixmap = gdk_pixmap_new
    (window->window, width,
    height, -1);
  cr = gdk_cairo_create
    (pixmap);

  printf ("Enter no. of "
    "disks (1-5): ");
  fgets (buf, FILENAME_MAX,
    stdin);
  n = strtol (buf, 0, 10);
  if (n < 1 || n > 5) return 1;
  for (g_usleep (delay);
    g_main_context_iteration
      (0, 0); );
  cairo_set_antialias (cr,
    CAIRO_ANTIALIAS_DEFAULT);
  rectangle (0, 0, width,
    height, 0);
  rectangle (150, 13,
    490 - 150, 33 - 13, 1);
  rectangle (160, 324,
    480 - 160, 346 - 324, 1);
  cairo_set_source_rgb (cr,
    cl [0] [0], cl [0] [1],
    cl [0] [2]);
  cairo_move_to (cr, 170, 14);
  pango_cairo_show_layout (cr,
    text);
  pango_layout_set_text (text,
    "Press any key to S T O P",
    -1);
  cairo_move_to (cr, 197, 325);
  pango_cairo_show_layout (cr,
    text);
  diskcount [0] = n;
  for (i = 0; i < n; i++)
    posinpeg [i] = i;
  for (i = 0; i < n; i++)
    rectangle (5 +
      diskisin [i] * 215 +
      (4 - i) * 20, 150 +
      i * 30, 40 + i * 40,
      ysize, i + 2);
  drawscreen ();
  towers (n, 0, 2, 1);
  while (!kbhit)
    for (g_usleep (delay);
      g_main_context_iteration
      (0, 0); );
  pango_font_description_free
    (font);
  cairo_destroy (cr);
  g_object_unref (pixmap);
  g_object_unref (text);
  return 0;
}
rheyang16 0 Newbie Poster

hi...im working on my final project now...can u help me to solve the problem or even an idea...the data structured used was GRAPH...and the problem is making less on cost the passenger of the airport...

i dont know how it goes coz this is my first try..and i dont really hav a background study on graphs...

plzzzzzzzzzz.......help me..............

akhil1989 0 Newbie Poster

Hey these codes r not working...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.