www.pudn.com > CÓïÑÔµÄС±àÒëÆ÷.zip > HANOI.C


/* 
 * 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  [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 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); 
}