I have the code to show tower of hanoi graphically.
It is very hard coded,can anyone help me to remove hard coded sotuation.
#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;
}