home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frostbyte's 1980s DOS Shareware Collection
/
floppyshareware.zip
/
floppyshareware
/
GLEN
/
MC20.ZIP
/
HANOI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-20
|
4KB
|
178 lines
/*
* Towers of Hanoi
*
* This program solves the "Towers of Hanoi" problem, which is to move a stack
* of different sized rings from one of three towers to another. Only one ring
* may be moved at a time, and a ring may not be placed on top of a smaller
* ring.
*
* Original Author Unknown
*/
#include \mc\stdio.h /* Standard I/O definitions */
#include \mc\video.h /* Video I/O definitions */
#define POST 0xB3
#define POST_BASE 0xC1
#define BASE 0xC4
#define RING 0xDC
#define SCREEN_WIDTH 80
#define SCREEN_HEIGHT 25
#define RING_WIDTH ((((SCREEN_WIDTH-2)/3)&0xFE)-1)
#define LEFT_POST (RING_WIDTH/2+1)
#define CENTER_POST (LEFT_POST+RING_WIDTH)
#define RIGHT_POST (LEFT_POST+2*RING_WIDTH)
#define MOVING_ROW 2
#define BASE_ROW 15
#define POST_HEIGHT 11
char top[3] = { BASE_ROW-1, BASE_ROW-1, BASE_ROW-1 };
unsigned pause;
/*
* Main program, draw the posts & begin moving rings
*/
main(argc, argv)
int argc;
char *argv[];
{
int nrings, i;
if(argc < 2 || argc > 3)
abort("\nUse: hanoi <rings> [delay]\n");
nrings = atoi(argv[1]); /* Number of rings */
pause = argc > 2 ? atoi(argv[2]) : 2500; /* Delay count */
vopen();
/* Draw the posts */
for(i = MOVING_ROW+2; i < BASE_ROW; ++i) {
putxy(LEFT_POST, i, POST);
putxy(CENTER_POST, i, POST);
putxy(RIGHT_POST, i, POST); }
/* Draw the base */
vgotoxy(0, BASE_ROW);
for(i = 1; i < SCREEN_WIDTH; ++i)
vputc(BASE);
/* Draw the post-base connections */
putxy(LEFT_POST, BASE_ROW, POST_BASE);
putxy(CENTER_POST, BASE_ROW, POST_BASE);
putxy(RIGHT_POST, BASE_ROW, POST_BASE);
/* Draw the title */
vgotoxy(30, BASE_ROW+2);
V_ATTR = REVERSE;
vputs(" TOWERS OF HANOI ");
V_ATTR = NORMAL;
/* Draw the initial ring positions */
for(i = nrings; i > 0; --i)
draw(i, LEFT_POST, top[0]--, RING);
/* Perform the movements */
hanoi(nrings, 0, 2, 1);
vgotoxy(0, 20);
}
/*
* Performs towers of hanoi movements by recursing from the current
* position to the bottom of the ring stack, moving a single ring,
* and walking back up again, re-arranging the movements with each
* recursion.
*/
hanoi(n, a, b, c)
char n, a, b, c;
{
if(n) {
hanoi(n-1, a, c, b);
movering(n, a, b);
hanoi(n-1, c, b, a); }
}
/*
* Place a character on the screen at a specified X/Y address
*/
putxy(x, y, c)
char c;
int x,y;
{
vgotoxy(x,y);
vputc(c);
}
/*
* Draw a ring at a position on the screen
*/
draw(ring, centre, y, c)
char ring, centre, y, c;
{
char i;
vgotoxy(centre-ring, y);
for(i=0; i<ring; ++i)
vputc(c);
vgotoxy(centre+1, y);
for(i=0; i<ring; ++i)
vputc(c);
}
/*
* Move a ring between two posts by repeatedly drawing and erasing it
*/
movering(ring, from, to)
char ring, from, to;
{
char fromc, toc;
char fromy, toy;
fromc = LEFT_POST + from * RING_WIDTH;
toc = LEFT_POST + to * RING_WIDTH;
fromy = ++top[from];
toy = top[to]--;
while(fromy != MOVING_ROW) {
draw(ring, fromc, fromy, ' ');
draw(ring, fromc, --fromy, RING);
wait(); }
if(fromc < toc)
while(fromc != toc) {
putxy(fromc-ring, fromy, ' ');
putxy(fromc, fromy, RING);
putxy(fromc+1, fromy, ' ');
putxy(fromc+ring+1, fromy, RING);
++fromc;
wait(); }
else if (fromc > toc)
while(fromc != toc) {
putxy(fromc+ring, fromy, ' ');
putxy(fromc, fromy, RING);
putxy(fromc-1, fromy, ' ');
putxy(fromc-ring-1, fromy, RING);
--fromc;
wait(); }
while(fromy != toy) {
draw(ring, fromc, fromy, ' ');
draw(ring, fromc, ++fromy, RING);
wait(); }
}
/*
* Wait a pre-defined delay period
*/
wait()
{
int i;
for(i=0; i < pause; ++i);
}