⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hanoi.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
字号:
/* *	Name: Towers of Hanoi. * *	Desc: *		This is a playable copy of towers of hanoi. *		Its sole purpose is to demonstrate my Amiga Curses package. *		This program should compile on any system that has Curses. *		'hanoi'		will give a manual game with 7 playing pieces. *		'hanoi n'	will give a manual game with n playing pieces. *		'hanoi n a' will give an auto solved game with n playing pieces. * *	Author: Simon J Raybould	(sie@fulcrum.bt.co.uk). * 	(This version has been slightly modified by the ncurses maintainers.) * *	Date: 05.Nov.90 * */#include <curses.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#define NPEGS			3	/* This is not configurable !! */#define MINTILES		3#define MAXTILES		9#define DEFAULTTILES	7#define TOPLINE			6#define BASELINE		16#define STATUSLINE		(LINES-3)#define LEFTPEG			19#define MIDPEG			39#define RIGHTPEG		59#define LENTOIND(x)		(((x)-1)/2)#define OTHER(a,b)		(3-((a)+(b)))struct Peg {	size_t Length[MAXTILES];	int Count;};struct Peg Pegs[NPEGS];int PegPos[] = { LEFTPEG, MIDPEG, RIGHTPEG };int TileColour[] = {	COLOR_GREEN,	/* Length 3 */	COLOR_MAGENTA,	/* Length 5 */	COLOR_RED,	/* Length 7 */	COLOR_BLUE,	/* Length 9 */	COLOR_CYAN,	/* Length 11 */	COLOR_YELLOW, 	/* Length 13 */	COLOR_GREEN,  	/* Length 15 */	COLOR_MAGENTA,	/* Length 17 */	COLOR_RED,	/* Length 19 */};int NMoves = 0;void InitTiles(int NTiles);void DisplayTiles(void);void MakeMove(int From, int To);void AutoMove(int From, int To, int Num);void Usage(void);int Solved(int NumTiles);int GetMove(int *From, int *To);int InvalidMove(int From, int To);intmain(int argc, char **argv){int NTiles, FromCol, ToCol;unsigned char AutoFlag = 0;	switch(argc) {	case 1:		NTiles = DEFAULTTILES;		break;	case 2:		NTiles = atoi(argv[1]);		if (NTiles > MAXTILES || NTiles < MINTILES) {			fprintf(stderr, "Range %d to %d\n", MINTILES, MAXTILES);			exit(1);		}		break;	case 3:		if (strcmp(argv[2], "a")) {			Usage();			exit(1);		}		NTiles = atoi(argv[1]);		if (NTiles > MAXTILES || NTiles < MINTILES) {			fprintf(stderr, "Range %d to %d\n", MINTILES, MAXTILES);			exit(1);		}		AutoFlag = TRUE;		break;	default:		Usage();		exit(1);	}#ifdef NCURSES_VERSION	trace(TRACE_MAXIMUM);#endif	initscr();	if (!has_colors()) {		endwin();		puts("terminal doesn't support color.");		exit(1);	}	start_color();	{	int i;	for (i = 0; i < 9; i++)		init_pair(i+1, COLOR_BLACK, TileColour[i]);	}	cbreak();	if (LINES < 24) {		endwin();		fprintf(stderr, "Min screen length 24 lines\n");		exit(1);	}	if(AutoFlag)		leaveok(stdscr, TRUE);	/* Attempt to remove cursor */	InitTiles(NTiles);	DisplayTiles();	if(AutoFlag) {		do {			noecho();			AutoMove(0, 2, NTiles);		} while(!Solved(NTiles));		sleep(2);	} else {		for(;;) {			if(GetMove(&FromCol, &ToCol))				break;			if(InvalidMove(FromCol, ToCol)) {				mvaddstr(STATUSLINE, 0, "Invalid Move !!");				refresh();				beep();				continue;			}			MakeMove(FromCol, ToCol);			if(Solved(NTiles)) {				mvprintw(STATUSLINE, 0, "Well Done !! You did it in %d moves", NMoves);				refresh();				sleep(5);				break;			}		}	}	curs_set(1);	endwin();	exit(0);}intInvalidMove(int From, int To){	if(From >= NPEGS)		return TRUE;	if(From < 0)		return TRUE;	if(To >= NPEGS)		return TRUE;	if(To < 0)		return TRUE;	if(From == To)		return TRUE;	if(!Pegs[From].Count)		return TRUE;	if(Pegs[To].Count &&			Pegs[From].Length[Pegs[From].Count-1] >			Pegs[To].Length[Pegs[To].Count-1])		return TRUE;	return FALSE;}voidInitTiles(int NTiles){int Size, SlotNo;		for(Size=NTiles*2+1, SlotNo=0; Size>=3; Size-=2)		Pegs[0].Length[SlotNo++] = Size;		Pegs[0].Count = NTiles;	Pegs[1].Count = 0;	Pegs[2].Count = 0;}voidDisplayTiles(){	int Line, Peg, SlotNo;	char TileBuf[BUFSIZ];	erase();	mvaddstr(1, 24, "T O W E R S   O F   H A N O I");	mvaddstr(3, 34, "SJR 1990");	mvprintw(19, 5, "Moves : %d", NMoves);	attrset(A_REVERSE);	mvaddstr(BASELINE, 8, "                                                               ");	for(Line=TOPLINE; Line<BASELINE; Line++) {		mvaddch(Line, LEFTPEG, ' ');		mvaddch(Line, MIDPEG, ' ');		mvaddch(Line, RIGHTPEG, ' ');	}	mvaddch(BASELINE, LEFTPEG, '1');	mvaddch(BASELINE, MIDPEG, '2');	mvaddch(BASELINE, RIGHTPEG, '3');	attrset(A_NORMAL);	/* Draw tiles */	for(Peg=0; Peg<NPEGS; Peg++) {		for(SlotNo=0; SlotNo<Pegs[Peg].Count; SlotNo++) {			memset(TileBuf, ' ', Pegs[Peg].Length[SlotNo]);			TileBuf[Pegs[Peg].Length[SlotNo]] = '\0';			attrset(COLOR_PAIR(LENTOIND(Pegs[Peg].Length[SlotNo])));			mvaddstr(BASELINE-(SlotNo+1),				(int)(PegPos[Peg] - Pegs[Peg].Length[SlotNo]/2),				TileBuf);		}	}	attrset(A_NORMAL);	refresh();}intGetMove(int *From, int *To){	mvaddstr(STATUSLINE, 0, "Next move ('q' to quit) from ");	clrtoeol();	refresh();	if((*From = getch()) == 'q')		return TRUE;	addch(*From);	*From -= ('0'+1);	addstr(" to ");	clrtoeol();	refresh();	if((*To = getch()) == 'q')		return TRUE;	addch(*To);	*To -= ('0'+1);	move(STATUSLINE, 0);	clrtoeol();	refresh();	return FALSE;}voidMakeMove(int From, int To){	Pegs[From].Count--;	Pegs[To].Length[Pegs[To].Count] = Pegs[From].Length[Pegs[From].Count];	Pegs[To].Count++;	NMoves++;	DisplayTiles();}voidAutoMove(int From, int To, int Num){	if(Num == 1) {		MakeMove(From, To);		return;	}	AutoMove(From, OTHER(From, To), Num-1);	MakeMove(From, To);	AutoMove(OTHER(From, To), To, Num-1);}intSolved(int NumTiles){int i;	for(i = 1; i < NPEGS; i++)		if (Pegs[i].Count == NumTiles)			return TRUE;	return FALSE;}voidUsage(){	fprintf(stderr, "Usage: hanoi [<No Of Tiles>] [a]\n");	fprintf(stderr, "The 'a' option causes the tower to be solved automatically\n");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -