/* * Hanoi. */ #include FILE *vt_fd; int top[3] = { 22, 22, 22 }; main(argc, argv) char *argv[]; { register n; if (argc == 0) { argc = 2; argv[0] = "hanoi"; argv[1] = "5"; } if (argc < 2) { fprintf(stderr, "Arg. count!\n"); exit(1); } n = atoi(argv[1]); if (n<0 || n>13) { fprintf(stderr, "Bad number of rings!\n"); exit(1); } if ((vt_fd = fopen("ti:", "wn")) == NULL) error("Can't open terminal"); setup(n); hanoi(n, 0, 2, 1); } hanoi(n, a, b, c) { if (n == 0) return; hanoi(n-1, a, c, b); movering(n, a, b); hanoi(n-1, c, b, a); } setup(n) { register i; erase(); for (i=11; i<23; ++i) { cput(15, i, '|'); cput(40, i, '|'); cput(65, i, '|'); } dca(5, 23); for (i=5; i<76; ++i) putc('-', vt_fd); for (i=n; i>0; --i) draw(i, 15, top[0]--, 'x'); } cput(x, y, c) { dca(x, y); putc(c, vt_fd); } draw(ring, centre, y, ch) { register i; dca(centre-ring, y); for (i=0; i toc) while (fromc != toc) { cput(fromc+ring, fromy, ' '); cput(fromc, fromy, 'x'); cput(fromc-1, fromy, ' '); cput(fromc-ring-1, fromy, 'x'); --fromc; } while (fromy != toy) { draw(ring, fromc, fromy, ' '); draw(ring, fromc, ++fromy, 'x'); } } /* * C u r s o r c o n t r o l f u n c t i o n s * * On VMS, cursor must be linked with kbgetc and kbputb. * */ #define ESC 0233 static char dcastring[] { ESC, 'Y', '?', '?' }; #define DCAROW 2 #define DCACOL 3 dca(x, y) int x; /* X -- Column on the screen */ int y; /* Y -- Row on the screen */ /* * Move the cursor to the indicated position. [0,0] is the top left-hand * corner of the screen */ { dcastring[DCACOL] = 32 + x; dcastring[DCAROW] = 32 + y; ttyput(dcastring, sizeof dcastring); } static char clrscr[] { ESC, 'H', ESC, 'J', 0 }; erase() /* * Clear the screen */ { ttyput(clrscr, sizeof clrscr); } ttyput(buffer, buflen) char *buffer; /* What to output */ int buflen; /* Number of bytes to output */ /* * Output to the terminal. RSX mode. */ { fput(buffer, buflen, vt_fd); fflush(vt_fd); }