#include #define POSX 10 #define POSY 5 #define DISC_CHAR '*' #define PEG_CHAR '#' #define TIME_OUT 300 typedef struct _peg_struct { int n_discs; /* Number of discs at present */ int bottomx, bottomy; /* bottom x, bottom y co-ord */ int *sizes; /* The disc sizes array */ }peg; void init_pegs(peg *p_my_pegs, int n_discs); void show_pegs(WINDOW *win, peg *p_my_pegs, int n_discs); void free_pegs(peg *p_my_pegs, int n_discs); void solve_hanoi(peg *p_my_pegs, int n, int src, int aux, int dst); void move_disc(peg *p_my_pegs, int n_discs, int src, int dst); void print_in_middle(int startx, int starty, int width, char *string, WINDOW *win); void check_usr_response(peg *p_my_pegs, int n_discs); int store_n_discs; char *welcome_string = "Enter the number of discs you want to be solved: "; int main(int argc, char *argv[]) { int n_discs; peg my_pegs[3]; initscr(); /* Start curses mode */ cbreak(); /* Line buffering disabled. Pass on every thing */ keypad(stdscr, TRUE); curs_set(FALSE); print_in_middle(0, LINES / 2, COLS, welcome_string, NULL); scanw("%d", &n_discs); timeout(TIME_OUT); noecho(); store_n_discs = n_discs; init_pegs(my_pegs, n_discs); show_pegs(stdscr, my_pegs, n_discs); solve_hanoi(my_pegs, n_discs, 0, 1, 2); free_pegs(my_pegs, n_discs); endwin(); /* End curses mode */ return 0; } void solve_hanoi(peg *p_my_pegs, int n_discs, int src, int aux, int dst) { if(n_discs == 0) return; solve_hanoi(p_my_pegs, n_discs - 1, src, dst, aux); move_disc(p_my_pegs, store_n_discs, src, dst); show_pegs(stdscr, p_my_pegs, store_n_discs); check_usr_response(p_my_pegs, store_n_discs); solve_hanoi(p_my_pegs, n_discs - 1, aux, src, dst); } void check_usr_response(peg *p_my_pegs, int n_discs) { int ch; ch = getch(); /* Waits for TIME_OUT milliseconds */ if(ch == ERR) return; else if(ch == KEY_F(1)) { free_pegs(p_my_pegs, n_discs); endwin(); exit(0); } } void move_disc(peg *p_my_pegs, int n_discs, int src, int dst) { int temp, index; --p_my_pegs[src].n_discs; index = 0; while(p_my_pegs[src].sizes[index] == 0 && index != n_discs) ++index; temp = p_my_pegs[src].sizes[index]; p_my_pegs[src].sizes[index] = 0; index = 0; while(p_my_pegs[dst].sizes[index] == 0 && index != n_discs) ++index; --index; p_my_pegs[dst].sizes[index] = temp; ++p_my_pegs[dst].n_discs; } void init_pegs(peg *p_my_pegs, int n_discs) { int size, temp, i; p_my_pegs[0].n_discs = n_discs; /* Allocate memory for size array * atmost the number of discs on a peg can be n_discs */ for(i = 0; i < n_discs; ++i) p_my_pegs[i].sizes = (int *)calloc(n_discs, sizeof(int)); size = 3; for(i = 0;i < n_discs; ++i, size += 2) p_my_pegs[0].sizes[i] = size; temp = (p_my_pegs[0].sizes[n_discs - 1] / 2); p_my_pegs[0].bottomx = POSX + 1 + temp; p_my_pegs[0].bottomy = POSY + 2 + n_discs; p_my_pegs[1].bottomx = p_my_pegs[0].bottomx + 2 + 2 * temp; p_my_pegs[1].bottomy = POSY + 2 + n_discs; p_my_pegs[2].bottomx = p_my_pegs[1].bottomx + 2 + 2 * temp; p_my_pegs[2].bottomy = POSY + 2 + n_discs; } void show_pegs(WINDOW *win, peg *p_my_pegs, int n_discs) { int i, j, k, x, y, size; wclear(win); attron(A_REVERSE); mvprintw(24, 0, "Press F1 to Exit"); attroff(A_REVERSE); for(i = 0;i < 3; ++i) mvwprintw( win, p_my_pegs[i].bottomy - n_discs - 1, p_my_pegs[i].bottomx, "%c", PEG_CHAR); y = p_my_pegs[0].bottomy - n_discs; for(i = 0; i < 3; ++i) /* For each peg */ { for(j = 0; j < n_discs; ++ j) /* For each row */ { if(p_my_pegs[i].sizes[j] != 0) { size = p_my_pegs[i].sizes[j]; x = p_my_pegs[i].bottomx - (size / 2); for(k = 0; k < size; ++k) mvwprintw(win, y, x + k, "%c", DISC_CHAR); } else mvwprintw(win, y, p_my_pegs[i].bottomx, "%c", PEG_CHAR); ++y; } y = p_my_pegs[0].bottomy - n_discs; } wrefresh(win); } void free_pegs(peg *p_my_pegs, int n_discs) { int i; for(i = 0;i < n_discs; ++i) free(p_my_pegs[i].sizes); } /* -------------------------------------------------------------* * startx = 0 means at present x * * starty = 0 means at present y * * win = NULL means take stdscr * * -------------------------------------------------------------*/ void print_in_middle(int startx, int starty, int width, char *string, WINDOW *win) { int length, x, y; float temp; if(win == NULL) win = stdscr; getyx(win, y, x); if(startx != 0) x = startx; if(starty != 0) y = starty; if(width == 0) width = 80; length = strlen(string); temp = (width - length)/ 2; x = startx + (int)temp; mvwprintw(win, y, x, "%s", string); refresh(); }