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

📄 bs.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * bs.c - original author: Bruce Holloway *		salvo option by: Chuck A DeGaul * with improved user interface, autoconfiguration and code cleanup *		by Eric S. Raymond <esr@snark.thyrsus.com> * v1.2 with color support and minor portability fixes, November 1990 * v2.0 featuring strict ANSI/POSIX conformance, November 1993. * v2.1 with ncurses mouse support, September 1995 *//* #define _POSIX_SOURCE -- incompatible with solaris termios.h */#include <signal.h>#include <ctype.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <assert.h>#include <time.h>#if HAVE_TERMIOS_H#include <sys/termios.h>	/* required before solaris curses.h */#endif#include <curses.h>#ifndef SIGIOT#define SIGIOT SIGABRT#endif#ifndef A_UNDERLINE	/* BSD curses */#define	beep()	write(1,"\007",1);#define	cbreak	crmode#define	saveterm savetty#define	resetterm resetty#define	nocbreak nocrmode#define strchr	index#endif /* !A_UNDERLINE */static int getcoord(int);/* * Constants for tuning the random-fire algorithm. It prefers moves that * diagonal-stripe the board with a stripe separation of srchstep. If * no such preferred moves are found, srchstep is decremented. */#define BEGINSTEP	3	/* initial value of srchstep *//* miscellaneous constants */#define SHIPTYPES	5#define	OTHER		(1-turn)#define PLAYER		0#define COMPUTER	1#define MARK_HIT	'H'#define MARK_MISS	'o'#define CTRLC		'\003'	/* used as terminate command */#define FF		'\014'	/* used as redraw command *//* coordinate handling */#define BWIDTH		10#define BDEPTH		10/* display symbols */#define SHOWHIT		'*'#define SHOWSPLASH	' '#define IS_SHIP(c)	isupper(c)/* how to position us on player board */#define PYBASE	3#define PXBASE	3#define PY(y)	(PYBASE + (y))#define PX(x)	(PXBASE + (x)*3)#define pgoto(y, x)	(void)move(PY(y), PX(x))/* how to position us on cpu board */#define CYBASE	3#define CXBASE	48#define CY(y)	(CYBASE + (y))#define CX(x)	(CXBASE + (x)*3)#define CYINV(y)	((y) - CYBASE)#define CXINV(x)	(((x) - CXBASE) / 3)#define cgoto(y, x)	(void)move(CY(y), CX(x))#define ONBOARD(x, y)	(x >= 0 && x < BWIDTH && y >= 0 && y < BDEPTH)/* other board locations */#define COLWIDTH	80#define PROMPTLINE	21			/* prompt line */#define SYBASE		CYBASE + BDEPTH + 3	/* move key diagram */#define SXBASE		63#define MYBASE		SYBASE - 1		/* diagram caption */#define MXBASE		64#define HYBASE		SYBASE - 1		/* help area */#define HXBASE		0/* this will need to be changed if BWIDTH changes */static char numbers[] = "   0  1  2  3  4  5  6  7  8  9";static char carrier[] = "Aircraft Carrier";static char battle[] = "Battleship";static char sub[] = "Submarine";static char destroy[] = "Destroyer";static char ptboat[] = "PT Boat";static char name[40];static char dftname[] = "stranger";/* direction constants */#define E	0#define SE	1#define S	2#define SW	3#define W	4#define NW	5#define N	6#define NE	7static int xincr[8] = {1,  1,  0, -1, -1, -1,  0,  1};static int yincr[8] = {0,  1,  1,  1,  0, -1, -1, -1};/* current ship position and direction */static int curx = (BWIDTH / 2);static int cury = (BDEPTH / 2);typedef struct{    char *name;		/* name of the ship type */    unsigned hits;	/* how many times has this ship been hit? */    char symbol;	/* symbol for game purposes */    char length;	/* length of ship */    char x, y;		/* coordinates of ship start point */    unsigned char dir;	/* direction of `bow' */    bool placed;	/* has it been placed on the board? */}ship_t;static bool checkplace(int b, ship_t *ss, int vis);ship_t plyship[SHIPTYPES] ={    { carrier,	0, 'A', 5},    { battle,	0, 'B', 4},    { destroy,	0, 'D', 3},    { sub,	0, 'S', 3},    { ptboat,	0, 'P', 2},};ship_t cpuship[SHIPTYPES] ={    { carrier,	0, 'A', 5},    { battle,	0, 'B', 4},    { destroy,	0, 'D', 3},    { sub,	0, 'S', 3},    { ptboat,	0, 'P', 2},};/* "Hits" board, and main board. */static char hits[2][BWIDTH][BDEPTH], board[2][BWIDTH][BDEPTH];static int turn;			/* 0=player, 1=computer */static int plywon=0, cpuwon=0;		/* How many games has each won? */static int salvo, blitz, closepack;#define	PR	(void)addstrstatic void uninitgame(int sig)/* end the game, either normally or due to signal */{    clear();    (void)refresh();    (void)resetterm();    (void)echo();    (void)endwin();    exit(sig);}static void announceopts(void)/* announce which game options are enabled */{    if (salvo || blitz || closepack)    {	(void) printw("Playing optional game (");	if (salvo)	    (void) printw("salvo, ");	else	    (void) printw("nosalvo, ");	if (blitz)	    (void) printw("blitz ");	else	    (void) printw("noblitz, ");	if (closepack)	    (void) printw("closepack)");	else	    (void) printw("noclosepack)");    }    else	(void) printw(	"Playing standard game (noblitz, nosalvo, noclosepack)");}static void intro(void){    extern char *getlogin(void);    char *tmpname;    srand((unsigned)(time(0L)+getpid()));	/* Kick the random number generator */    (void) signal(SIGINT,uninitgame);    (void) signal(SIGINT,uninitgame);    (void) signal(SIGIOT,uninitgame);		/* for assert(3) */    if(signal(SIGQUIT,SIG_IGN) != SIG_IGN)	(void)signal(SIGQUIT,uninitgame);    if((tmpname = getlogin()) != 0)    {	(void)strcpy(name,tmpname);	name[0] = toupper(name[0]);    }    else	(void)strcpy(name,dftname);    (void)initscr();#ifdef KEY_MIN    keypad(stdscr, TRUE);#endif /* KEY_MIN */    (void)saveterm();    (void)nonl();    (void)cbreak();    (void)noecho();#ifdef PENGUIN    (void)clear();    (void)mvaddstr(4,29,"Welcome to Battleship!");    (void)move(8,0);    PR("                                                  \\\n");    PR("                           \\                     \\ \\\n");    PR("                          \\ \\                   \\ \\ \\_____________\n");    PR("                         \\ \\ \\_____________      \\ \\/            |\n");    PR("                          \\ \\/             \\      \\/             |\n");    PR("                           \\/               \\_____/              |__\n");    PR("           ________________/                                       |\n");    PR("           \\  S.S. Penguin                                         |\n");    PR("            \\                                                     /\n");    PR("             \\___________________________________________________/\n");    (void) mvaddstr(22,27,"Hit any key to continue..."); (void)refresh();    (void) getch();#endif /* PENGUIN */#ifdef A_COLOR    start_color();    init_pair(COLOR_BLACK, COLOR_BLACK, COLOR_BLACK);    init_pair(COLOR_GREEN, COLOR_GREEN, COLOR_BLACK);    init_pair(COLOR_RED, COLOR_RED, COLOR_BLACK);    init_pair(COLOR_CYAN, COLOR_CYAN, COLOR_BLACK);    init_pair(COLOR_WHITE, COLOR_WHITE, COLOR_BLACK);    init_pair(COLOR_MAGENTA, COLOR_MAGENTA, COLOR_BLACK);    init_pair(COLOR_BLUE, COLOR_BLUE, COLOR_BLACK);    init_pair(COLOR_YELLOW, COLOR_YELLOW, COLOR_BLACK);#endif /* A_COLOR */#ifdef NCURSES_MOUSE_VERSION    (void) mousemask(BUTTON1_CLICKED, (mmask_t *)NULL);#endif /* NCURSES_MOUSE_VERSION*/}		    /* VARARGS1 */static void prompt(int n, char *f, char *s)/* print a message at the prompt line */{    (void) move(PROMPTLINE + n, 0);    (void) clrtoeol();    (void) printw(f, s);    (void) refresh();}static void error(char *s){    (void) move(PROMPTLINE + 2, 0);    (void) clrtoeol();    if (s)    {	(void) addstr(s);	(void) beep();    }}static void placeship(int b, ship_t *ss, int vis){    int l;    for(l = 0; l < ss->length; ++l)    {	int newx = ss->x + l * xincr[ss->dir];	int newy = ss->y + l * yincr[ss->dir];	board[b][newx][newy] = ss->symbol;	if (vis)	{	    pgoto(newy, newx);	    (void) addch((chtype)ss->symbol);	}    }    ss->hits = 0;}static int rnd(int n){    return(((rand() & 0x7FFF) % n));}static void randomplace(int b, ship_t *ss)/* generate a valid random ship placement into px,py */{    register int bwidth = BWIDTH - ss->length;    register int bdepth = BDEPTH - ss->length;    do {	ss->y = rnd(bdepth);	ss->x = rnd(bwidth);	ss->dir = rnd(2) ? E : S;    } while	(!checkplace(b, ss, FALSE));}static void initgame(void){    int i, j, unplaced;    ship_t *ss;    (void) clear();    (void) mvaddstr(0,35,"BATTLESHIPS");    (void) move(PROMPTLINE + 2, 0);    announceopts();    memset(board, 0, sizeof(char) * BWIDTH * BDEPTH * 2);    memset(hits,  0, sizeof(char) * BWIDTH * BDEPTH * 2);    for (i = 0; i < SHIPTYPES; i++)    {	ss = cpuship + i;	ss->x = ss->y = ss->dir = ss->hits = ss->placed = 0;	ss = plyship + i;	ss->x = ss->y = ss->dir = ss->hits = ss->placed = 0;    }    /* draw empty boards */    (void) mvaddstr(PYBASE - 2, PXBASE + 5, "Main Board");    (void) mvaddstr(PYBASE - 1, PXBASE - 3,numbers);    for(i=0; i < BDEPTH; ++i)    {	(void) mvaddch(PYBASE + i, PXBASE - 3, (chtype)(i + 'A'));#ifdef A_COLOR	if (has_colors())	    attron(COLOR_PAIR(COLOR_BLUE));#endif /* A_COLOR */	(void) addch(' ');	for (j = 0; j < BWIDTH; j++)	    (void) addstr(" . ");#ifdef A_COLOR	attrset(0);#endif /* A_COLOR */	(void) addch(' ');	(void) addch((chtype)(i + 'A'));    }    (void) mvaddstr(PYBASE + BDEPTH, PXBASE - 3,numbers);    (void) mvaddstr(CYBASE - 2, CXBASE + 7,"Hit/Miss Board");    (void) mvaddstr(CYBASE - 1, CXBASE - 3, numbers);    for(i=0; i < BDEPTH; ++i)    {	(void) mvaddch(CYBASE + i, CXBASE - 3, (chtype)(i + 'A'));#ifdef A_COLOR	if (has_colors())	    attron(COLOR_PAIR(COLOR_BLUE));#endif /* A_COLOR */	(void) addch(' ');	for (j = 0; j < BWIDTH; j++)	    (void) addstr(" . ");#ifdef A_COLOR	attrset(0);#endif /* A_COLOR */	(void) addch(' ');	(void) addch((chtype)(i + 'A'));    }    (void) mvaddstr(CYBASE + BDEPTH,CXBASE - 3,numbers);    (void) mvprintw(HYBASE,  HXBASE,		    "To position your ships: move the cursor to a spot, then");    (void) mvprintw(HYBASE+1,HXBASE,		    "type the first letter of a ship type to select it, then");    (void) mvprintw(HYBASE+2,HXBASE,		    "type a direction ([hjkl] or [4862]), indicating how the");    (void) mvprintw(HYBASE+3,HXBASE,		    "ship should be pointed. You may also type a ship letter");    (void) mvprintw(HYBASE+4,HXBASE,		    "followed by `r' to position it randomly, or type `R' to");    (void) mvprintw(HYBASE+5,HXBASE,		    "place all remaining ships randomly.");    (void) mvaddstr(MYBASE,   MXBASE, "Aiming keys:");    (void) mvaddstr(SYBASE,   SXBASE, "y k u    7 8 9");    (void) mvaddstr(SYBASE+1, SXBASE, " \\|/      \\|/ ");    (void) mvaddstr(SYBASE+2, SXBASE, "h-+-l    4-+-6");    (void) mvaddstr(SYBASE+3, SXBASE, " /|\\      /|\\ ");    (void) mvaddstr(SYBASE+4, SXBASE, "b j n    1 2 3");    /* have the computer place ships */    for(ss = cpuship; ss < cpuship + SHIPTYPES; ss++)    {	randomplace(COMPUTER, ss);	placeship(COMPUTER, ss, FALSE);    }    ss = (ship_t *)NULL;    do {	char c, docked[SHIPTYPES + 2], *cp = docked;	/* figure which ships still wait to be placed */	*cp++ = 'R';	for (i = 0; i < SHIPTYPES; i++)	    if (!plyship[i].placed)		*cp++ = plyship[i].symbol;	*cp = '\0';	/* get a command letter */	prompt(1, "Type one of [%s] to pick a ship.", docked+1);	do {	    c = getcoord(PLAYER);	} while	    (!strchr(docked, c));	if (c == 'R')	    (void) ungetch('R');	else	{	    /* map that into the corresponding symbol */	    for (ss = plyship; ss < plyship + SHIPTYPES; ss++)		if (ss->symbol == c)		    break;	    prompt(1, "Type one of [hjklrR] to place your %s.", ss->name);	    pgoto(cury, curx);	}	do {	    c = getch();	} while	    (!strchr("hjklrR", c) || c == FF);	if (c == FF)	{	    (void)clearok(stdscr, TRUE);	    (void)refresh();	}	else if (c == 'r')	{	    prompt(1, "Random-placing your %s", ss->name);	    randomplace(PLAYER, ss);	    placeship(PLAYER, ss, TRUE);	    error((char *)NULL);	    ss->placed = TRUE;	}	    	else if (c == 'R')	{	    prompt(1, "Placing the rest of your fleet at random...", "");	    for (ss = plyship; ss < plyship + SHIPTYPES; ss++)		if (!ss->placed)		{		    randomplace(PLAYER, ss);		    placeship(PLAYER, ss, TRUE);		    ss->placed = TRUE;		}	    error((char *)NULL);	}	    	else if (strchr("hjkl8462", c))	{	    ss->x = curx;	    ss->y = cury;	    switch(c)	    {	    case 'k': case '8': ss->dir = N; break;	    case 'j': case '2': ss->dir = S; break;	    case 'h': case '4': ss->dir = W; break;	    case 'l': case '6': ss->dir = E; break;	    }	    	    if (checkplace(PLAYER, ss, TRUE))	    {		placeship(PLAYER, ss, TRUE);		error((char *)NULL);		ss->placed = TRUE;	    }	}	for (unplaced = i = 0; i < SHIPTYPES; i++)	    unplaced += !plyship[i].placed;    } while	(unplaced);    turn = rnd(2);    (void) mvprintw(HYBASE,  HXBASE,		    "To fire, move the cursor to your chosen aiming point   ");    (void) mvprintw(HYBASE+1,  HXBASE,		    "and strike any key other than a motion key.            ");    (void) mvprintw(HYBASE+2,  HXBASE,		    "                                                       ");    (void) mvprintw(HYBASE+3,  HXBASE,		    "                                                       ");    (void) mvprintw(HYBASE+4,  HXBASE,		    "                                                       ");    (void) mvprintw(HYBASE+5,  HXBASE,		    "                                                       ");    (void) prompt(0, "Press any key to start...", "");    (void) getch();}static int getcoord(int atcpu){    int ny, nx, c;    if (atcpu)	cgoto(cury,curx);    else	pgoto(cury, curx);    (void)refresh();    for (;;)    {	if (atcpu)	{	    (void) mvprintw(CYBASE + BDEPTH+1, CXBASE+11, "(%d, %c)", curx, 'A'+cury);	    cgoto(cury, curx);	}	else	{	    (void) mvprintw(PYBASE + BDEPTH+1, PXBASE+11, "(%d, %c)", curx, 'A'+cury);	    pgoto(cury, curx);	}	switch(c = getch())	{	case 'k': case '8':#ifdef KEY_MIN	case KEY_UP:#endif /* KEY_MIN */	    ny = cury+BDEPTH-1; nx = curx;	    break;	case 'j': case '2':#ifdef KEY_MIN	case KEY_DOWN:#endif /* KEY_MIN */	    ny = cury+1;        nx = curx;	    break;	case 'h': case '4':#ifdef KEY_MIN	case KEY_LEFT:#endif /* KEY_MIN */	    ny = cury;          nx = curx+BWIDTH-1;	    break;	case 'l': case '6':#ifdef KEY_MIN	case KEY_RIGHT:#endif /* KEY_MIN */	    ny = cury;          nx = curx+1;	    break;	case 'y': case '7':#ifdef KEY_MIN	case KEY_A1:#endif /* KEY_MIN */	    ny = cury+BDEPTH-1; nx = curx+BWIDTH-1;	    break;	case 'b': case '1':#ifdef KEY_MIN	case KEY_C1:#endif /* KEY_MIN */	    ny = cury+1;        nx = curx+BWIDTH-1;	    break;	case 'u': case '9':#ifdef KEY_MIN	case KEY_A3:#endif /* KEY_MIN */	    ny = cury+BDEPTH-1; nx = curx+1;	    break;	case 'n': case '3':#ifdef KEY_MIN	case KEY_C3:#endif /* KEY_MIN */	    ny = cury+1;        nx = curx+1;	    break;	case FF:	    nx = curx; ny = cury;	    (void)clearok(stdscr, TRUE);	    (void)refresh();	    break;#ifdef NCURSES_MOUSE_VERSION	case KEY_MOUSE:	    {		MEVENT	myevent;		getmouse(&myevent);		if (atcpu			&& myevent.y >= CY(0) && myevent.y <= CY(BDEPTH)			&& myevent.x >= CX(0) && myevent.x <= CX(BDEPTH))		{		    curx = CXINV(myevent.x);		    cury = CYINV(myevent.y);		    return(' ');		}		else		{		    beep();		    continue;		}	    }	    /* no fall through */#endif /* NCURSES_MOUSE_VERSION */	default:	    if (atcpu)		(void) mvaddstr(CYBASE + BDEPTH + 1, CXBASE + 11, "      ");	    else		(void) mvaddstr(PYBASE + BDEPTH + 1, PXBASE + 11, "      ");	    return(c);	}

⌨️ 快捷键说明

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