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

📄 bs.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
📖 第 1 页 / 共 2 页
字号:
	curx = nx % BWIDTH;	cury = ny % BDEPTH;    }}static int collidecheck(int b, int y, int x)/* is this location on the selected zboard adjacent to a ship? */{    int	collide;    /* anything on the square */    if ((collide = IS_SHIP(board[b][x][y])) != 0)	return(collide);    /* anything on the neighbors */    if (!closepack)    {	int i;	for (i = 0; i < 8; i++)	{	    int xend, yend;	    yend = y + yincr[i];	    xend = x + xincr[i];	    if (ONBOARD(xend, yend))		collide += IS_SHIP(board[b][xend][yend]);	}    }    return(collide);}static bool checkplace(int b, ship_t *ss, int vis){    int l, xend, yend;    /* first, check for board edges */    xend = ss->x + ss->length * xincr[ss->dir];    yend = ss->y + ss->length * yincr[ss->dir];    if (!ONBOARD(xend, yend))    {	if (vis)	    switch(rnd(3))	    {	    case 0:		error("Ship is hanging from the edge of the world");		break;	    case 1:		error("Try fitting it on the board");		break;	    case 2:		error("Figure I won't find it if you put it there?");		break;	    }	return(0);    }    for(l = 0; l < ss->length; ++l)    {	if(collidecheck(b, ss->y+l*yincr[ss->dir], ss->x+l*xincr[ss->dir]))	{	    if (vis)		switch(rnd(3))		{		    case 0:			error("There's already a ship there");			break;		    case 1:			error("Collision alert!  Aaaaaagh!");			break;		    case 2:			error("Er, Admiral, what about the other ship?");			break;		    }	    return(FALSE);	    }	}    return(TRUE);}static int awinna(void){    int i, j;    ship_t *ss;    for(i=0; i<2; ++i)    {	ss = (i) ? cpuship : plyship;	for(j=0; j < SHIPTYPES; ++j, ++ss)	    if(ss->length > ss->hits)		break;	if (j == SHIPTYPES)	    return(OTHER);    }    return(-1);}static ship_t *hitship(int x, int y)/* register a hit on the targeted ship */{    ship_t *sb, *ss;    char sym;    int oldx, oldy;    getyx(stdscr, oldy, oldx);    sb = (turn) ? plyship : cpuship;    if(!(sym = board[OTHER][x][y]))	return((ship_t *)NULL);    for(ss = sb; ss < sb + SHIPTYPES; ++ss)	if(ss->symbol == sym)	{	    if (++ss->hits < ss->length)	/* still afloat? */		return((ship_t *)NULL);	    else				/* sunk! */	    {		int i, j;		if (!closepack)		    for (j = -1; j <= 1; j++)		    {			int bx = ss->x + j * xincr[(ss->dir + 2) % 8];			int by = ss->y + j * yincr[(ss->dir + 2) % 8];			for (i = -1; i <= ss->length; ++i)			{			    int x1, y1;			    			    x1 = bx + i * xincr[ss->dir];			    y1 = by + i * yincr[ss->dir];			    if (ONBOARD(x1, y1))			    {				hits[turn][x1][y1] = MARK_MISS;				if (turn % 2 == PLAYER)				{				    cgoto(y1, x1);#ifdef A_COLOR				    if (has_colors())					attron(COLOR_PAIR(COLOR_GREEN));#endif /* A_COLOR */				    (void)addch(MARK_MISS);#ifdef A_COLOR				    attrset(0);#endif /* A_COLOR */				}			    }			}		    }		for (i = 0; i < ss->length; ++i)		{		    int x1 = ss->x + i * xincr[ss->dir];		    int y1 = ss->y + i * yincr[ss->dir];		    hits[turn][x1][y1] = ss->symbol;		    if (turn % 2 == PLAYER)		    {			cgoto(y1, x1);			(void) addch((chtype)(ss->symbol));		    }		}		(void) move(oldy, oldx);		return(ss);	    }	}    (void) move(oldy, oldx);    return((ship_t *)NULL);}static int plyturn(void){    ship_t *ss;    bool hit;    char *m = NULL;    prompt(1, "Where do you want to shoot? ", "");    for (;;)    {	(void) getcoord(COMPUTER);	if (hits[PLAYER][curx][cury])	{	    prompt(1, "You shelled this spot already! Try again.", "");	    beep();	}	else	    break;    }    hit = IS_SHIP(board[COMPUTER][curx][cury]);    hits[PLAYER][curx][cury] = hit ? MARK_HIT : MARK_MISS;    cgoto(cury, curx);#ifdef A_COLOR    if (has_colors())	if (hit)	    attron(COLOR_PAIR(COLOR_RED));	else	    attron(COLOR_PAIR(COLOR_GREEN));#endif /* A_COLOR */    (void) addch((chtype)hits[PLAYER][curx][cury]);#ifdef A_COLOR    attrset(0);#endif /* A_COLOR */    prompt(1, "You %s.", hit ? "scored a hit" : "missed");    if(hit && (ss = hitship(curx, cury)))    {	switch(rnd(5))	{	case 0:	    m = " You sank my %s!";	    break;	case 1:	    m = " I have this sinking feeling about my %s....";	    break;	case 2:	    m = " My %s has gone to Davy Jones's locker!";	    break;	case 3:	    m = " Glub, glub -- my %s is headed for the bottom!";	    break;	case 4:	    m = " You'll pick up survivors from my my %s, I hope...!";	    break;	}	(void)printw(m, ss->name);	(void)beep();	return(awinna() == -1);    }    return(hit);}static int sgetc(char *s){    char *s1;    int ch;    (void)refresh();    for(;;)    {	ch = getch();	if (islower(ch))	    ch = toupper(ch);	if (ch == CTRLC)	    uninitgame(0);	for (s1=s; *s1 && ch != *s1; ++s1)	    continue;	if (*s1)	{	    (void) addch((chtype)ch);	    (void)refresh();	    return(ch);	    }	}}static void randomfire(int *px, int *py)/* random-fire routine -- implements simple diagonal-striping strategy */{    static int turncount = 0;    static int srchstep = BEGINSTEP;    static int huntoffs;		/* Offset on search strategy */    int ypossible[BWIDTH * BDEPTH], xpossible[BWIDTH * BDEPTH], nposs;    int ypreferred[BWIDTH * BDEPTH], xpreferred[BWIDTH * BDEPTH], npref;    int x, y, i;    if (turncount++ == 0)	huntoffs = rnd(srchstep);    /* first, list all possible moves */    nposs = npref = 0;    for (x = 0; x < BWIDTH; x++)	for (y = 0; y < BDEPTH; y++)	    if (!hits[COMPUTER][x][y])	    {		xpossible[nposs] = x;		ypossible[nposs] = y;		nposs++;		if (((x+huntoffs) % srchstep) != (y % srchstep))		{		    xpreferred[npref] = x;		    ypreferred[npref] = y;		    npref++;		}	    }    if (npref)    {	i = rnd(npref);	*px = xpreferred[i];	*py = ypreferred[i];    }    else if (nposs)    {	i = rnd(nposs);	*px = xpossible[i];	*py = ypossible[i];	if (srchstep > 1)	    --srchstep;    }    else    {	error("No moves possible?? Help!");	exit(1);	/*NOTREACHED*/    }}#define S_MISS	0#define S_HIT	1#define S_SUNK	-1static bool cpufire(int x, int y)/* fire away at given location */{    bool hit, sunk;    ship_t *ss = NULL;    hits[COMPUTER][x][y] = (hit = (board[PLAYER][x][y])) ? MARK_HIT : MARK_MISS;    (void) mvprintw(PROMPTLINE, 0,	"I shoot at %c%d. I %s!", y + 'A', x, hit ? "hit" : "miss");    if ((sunk = (hit && (ss = hitship(x, y)))))	(void) printw(" I've sunk your %s", ss->name);    (void)clrtoeol();    pgoto(y, x);#ifdef A_COLOR    if (has_colors())	if (hit)	    attron(COLOR_PAIR(COLOR_RED));	else	    attron(COLOR_PAIR(COLOR_GREEN));#endif /* A_COLOR */    (void)addch((chtype)(hit ? SHOWHIT : SHOWSPLASH));#ifdef A_COLOR    attrset(0);#endif /* A_COLOR */    return(hit ? (sunk ? S_SUNK : S_HIT) : S_MISS);}/* * This code implements a fairly irregular FSM, so please forgive the rampant * unstructuredness below. The five labels are states which need to be held * between computer turns. */static bool cputurn(void){#define POSSIBLE(x, y)	(ONBOARD(x, y) && !hits[COMPUTER][x][y])#define RANDOM_FIRE	0#define RANDOM_HIT	1#define HUNT_DIRECT	2#define FIRST_PASS	3#define REVERSE_JUMP	4#define SECOND_PASS	5    static int next = RANDOM_FIRE;    static bool used[4];    static ship_t ts;    int navail, x, y, d, n, hit = S_MISS;    switch(next)    {    case RANDOM_FIRE:	/* last shot was random and missed */    refire:	randomfire(&x, &y);	if (!(hit = cpufire(x, y)))	    next = RANDOM_FIRE;	else	{	    ts.x = x; ts.y = y;	    ts.hits = 1;	    next = (hit == S_SUNK) ? RANDOM_FIRE : RANDOM_HIT;	}	break;    case RANDOM_HIT:	/* last shot was random and hit */	used[E/2] = used[S/2] = used[W/2] = used[N/2] = FALSE;	/* FALLTHROUGH */    case HUNT_DIRECT:	/* last shot hit, we're looking for ship's long axis */	for (d = navail = 0; d < 4; d++)	{	    x = ts.x + xincr[d*2]; y = ts.y + yincr[d*2];	    if (!used[d] && POSSIBLE(x, y))		navail++;	    else		used[d] = TRUE;	}	if (navail == 0)	/* no valid places for shots adjacent... */	    goto refire;	/* ...so we must random-fire */	else	{	    for (d = 0, n = rnd(navail) + 1; n; n--)		while (used[d])		    d++;	    assert(d <= 4);	    used[d] = FALSE;	    x = ts.x + xincr[d*2];	    y = ts.y + yincr[d*2];	    assert(POSSIBLE(x, y));	    if (!(hit = cpufire(x, y)))		next = HUNT_DIRECT;	    else	    {		ts.x = x; ts.y = y; ts.dir = d*2; ts.hits++;		next = (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS;	    }	}	break;    case FIRST_PASS:	/* we have a start and a direction now */	x = ts.x + xincr[ts.dir];	y = ts.y + yincr[ts.dir];	if (POSSIBLE(x, y) && (hit = cpufire(x, y)))	{	    ts.x = x; ts.y = y; ts.hits++;	    next = (hit == S_SUNK) ? RANDOM_FIRE : FIRST_PASS;	}	else	    next = REVERSE_JUMP;	break;    case REVERSE_JUMP:	/* nail down the ship's other end */	d = ts.dir + 4;	x = ts.x + ts.hits * xincr[d];	y = ts.y + ts.hits * yincr[d];	if (POSSIBLE(x, y) && (hit = cpufire(x, y)))	{	    ts.x = x; ts.y = y; ts.dir = d; ts.hits++;	    next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS;	}	else	    next = RANDOM_FIRE;	break;    case SECOND_PASS:	/* kill squares not caught on first pass */	x = ts.x + xincr[ts.dir];	y = ts.y + yincr[ts.dir];	if (POSSIBLE(x, y) && (hit = cpufire(x, y)))	{	    ts.x = x; ts.y = y; ts.hits++;	    next = (hit == S_SUNK) ? RANDOM_FIRE: SECOND_PASS;	    break;	}	else	    next = RANDOM_FIRE;	break;    }    /* check for continuation and/or winner */    if (salvo)    {	(void)refresh();	(void)sleep(1);    }    if (awinna() != -1)	return(FALSE);#ifdef DEBUG    (void) mvprintw(PROMPTLINE + 2, 0,		    "New state %d, x=%d, y=%d, d=%d",		    next, x, y, d);#endif /* DEBUG */    return(hit);}staticint playagain(void){    int j;    ship_t *ss;    for (ss = cpuship; ss < cpuship + SHIPTYPES; ss++)	for(j = 0; j < ss->length; j++)	{	    cgoto(ss->y + j * yincr[ss->dir], ss->x + j * xincr[ss->dir]);	    (void)addch((chtype)ss->symbol);	}    if(awinna())	++cpuwon;    else	++plywon;    j = 18 + strlen(name);    if(plywon >= 10)	++j;    if(cpuwon >= 10)	++j;    (void) mvprintw(1,(COLWIDTH-j)/2,		    "%s: %d     Computer: %d",name,plywon,cpuwon);    prompt(2, (awinna()) ? "Want to be humiliated again, %s [yn]? "	   : "Going to give me a chance for revenge, %s [yn]? ",name);    return(sgetc("YN") == 'Y');}static void do_options(int c, char *op[]){    register int i;    if (c > 1)    {	for (i=1; i<c; i++)	{	    switch(op[i][0])	    {	    default:	    case '?':		(void) fprintf(stderr, "Usage: battle [-s | -b] [-c]\n");		(void) fprintf(stderr, "\tWhere the options are:\n");		(void) fprintf(stderr, "\t-s : play a salvo game\n");		(void) fprintf(stderr, "\t-b : play a blitz game\n");		(void) fprintf(stderr, "\t-c : ships may be adjacent\n");		exit(1);		break;	    case '-':		switch(op[i][1])		{		case 'b':		    blitz = 1;		    if (salvo == 1)		    {			(void) fprintf(stderr,				"Bad Arg: -b and -s are mutually exclusive\n");			exit(1);		    }		    break;		case 's':		    salvo = 1;		    if (blitz == 1)		    {			(void) fprintf(stderr,				"Bad Arg: -s and -b are mutually exclusive\n");			exit(1);		    }		    break;		case 'c':		    closepack = 1;		    break;		default:		    (void) fprintf(stderr,			    "Bad arg: type \"%s ?\" for usage message\n", op[0]);		    exit(1);		}	    }	}    }}static int scount(int who){    register int i, shots;    register ship_t *sp;    if (who)	sp = cpuship;	/* count cpu shots */    else	sp = plyship;	/* count player shots */    for (i=0, shots = 0; i < SHIPTYPES; i++, sp++)    {	if (sp->hits >= sp->length)	    continue;		/* dead ship */	else	    shots++;    }    return(shots);}int main(int argc, char *argv[]){    do_options(argc, argv);    intro();    do {	initgame();	while(awinna() == -1)	{	    if (!blitz)	    {		if (!salvo)		{	    	    if(turn)			(void) cputurn();		    else			(void) plyturn();		}		else		{		    register int i;		    i = scount(turn);		    while (i--)		    {			if (turn)			{			    if (cputurn() && awinna() != -1)				i = 0;			}			else			{			    if (plyturn() && awinna() != -1)				i = 0;			}		    }		} 	    }	    else	    	while(turn ? cputurn() : plyturn())		    continue;	    turn = OTHER;	}    } while	(playagain());    uninitgame(0);    /*NOTREACHED*/   return 1;}/* bs.c ends here */

⌨️ 快捷键说明

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