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;
}
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 ns_jim@yahoo.com or jim08788@yahoo.com ...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.