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

📄 battle.c

📁 一个C格式的脚本处理函数库源代码,可让你的C程序具有执行C格式的脚本文件
💻 C
字号:
/*  * battle.c - original author: Bruce Holloway *		mods by: Chuck A DeGaul */#include <unistd.h>#include <stdlib.h>#include <ctype.h>#include <time.h>#include <signal.h>#ifdef SLANG# include <slcurses.h>#else# include <curses.h>#endif#define	OTHER	1-turnchar numbers[] = "   0  1  2  3  4  5  6  7  8  9";char carrier[] = "Aircraft Carrier";char battle[] = "Battleship";char sub[] = "Submarine";char destroy[] = "Destroyer";char ptboat[] = "PT Boat";char name[40];char dftname[] = "Stranger";struct _ships {    char *name;    char symbol;    char length;    char start;		/* Coordinates - 0,0=0; 10,10=100. */    char dir;		/* Direction - 0 = right; 1 = down. */    char hits;		/* How many times has this ship been hit? (-1==sunk) */};struct _ships plyship[] = {    { carrier,'A',5,0,0,0 },    { battle,'B',4,0,0,0 },    { destroy,'D',3,0,0,0 },    { sub,'S',3,0,0,0 },    { ptboat,'P',2,0,0,0 },};struct _ships cpuship[] = {    { carrier,'A',5,0,0,0 },    { battle,'B',4,0,0,0 },    { destroy,'D',3,0,0,0 },    { sub,'S',3,0,0,0 },    { ptboat,'P',2,0,0,0 },};char hits[2][100], board[2][100];	/* "Hits" board, and main board. */int srchstep;int cpuhits;int cstart, cdir;int plywon=0, cpuwon=0;			/* How many games has each won? */int turn;				/* 0=player, 1=computer */int huntoffs;				/* Offset on search strategy */int salvo, blitz, ask, seemiss;		/* options */void intro(void);void initgame(void);int rnd(int);void plyplace(struct _ships *);int getdir(void);void placeship(struct _ships *, int, int);int checkplace(struct _ships *, int, int);void error(char *);void prompt(void);char getcoord(void);void cpuplace(struct _ships *);int awinna(void);int plyturn(void);int hitship(int);int cputurn(void);int playagain(void);void uninitgame();int sgetc(char *);int do_options(int, char *[]);int scount(int);intmain(int argc, char **argv){    do_options(argc, argv);    intro();    do {		initgame();		while(awinna() == -1) {		    if (!blitz) {				if (!salvo) {		    	    if (turn) 		    	    	cputurn(); 		    	    else plyturn();				} else {				     register int i;				     i = scount(turn);				     while (i--) {					 	if (turn) 					 	    if (cputurn()) 							 	if (awinna() != -1) 							     	i = 0;					 	else 					 	    if(plyturn()) 							 	if (awinna() != -1) 							     	i = 0;				 	}			    }		    } else {		    	while((turn) ? cputurn() : plyturn());		    }		    turn = OTHER;		}    } while(playagain());    uninitgame();    exit(0);}#define	PR	addstrvoidintro(){char *tmpname;    srand(time(0L));			/* Kick the random number generator */    signal(SIGINT,uninitgame);    if(signal(SIGQUIT,SIG_IGN) != SIG_IGN) signal(SIGQUIT,uninitgame);#if 1	/* for some bizzare reason, getlogin or cuserid cause havoc with the terminal */	if ((tmpname = getlogin()) != NULL) {		strcpy(name, tmpname);	} else#endif	strcpy(name,dftname);    name[0] = toupper(name[0]);    initscr();    savetty();    nonl();     cbreak();     noecho();    clear();    mvaddstr(4,29,"Welcome to Battleship!");    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");    mvaddstr(20,27,"Hit any key to continue..."); refresh();    getch();}voidinitgame(){int i;    clear();    mvaddstr(0,35,"BATTLESHIP");    mvaddstr(4,12,"Main Board");    mvaddstr(6,0,numbers);    move(7,0);    for(i=0; i<10; ++i){		printw("%c  .  .  .  .  .  .  .  .  .  .  %c\n",i+'A',i+'A');	}    mvaddstr(17,0,numbers);    mvaddstr(4,55,"Hit/Miss Board");    mvaddstr(6,45,numbers);    for(i=0; i<10; ++i){		mvprintw(7+i,45,"%c  .  .  .  .  .  .  .  .  .  .  %c",i+'A',i+'A');	}    mvaddstr(17,45,numbers);    for(turn=0; turn<2; ++turn)	for(i=0; i<100; ++i){	    hits[turn][i] = board[turn][i] = 0;    }    for(turn=0; turn<2; ++turn){	for(i=0; i<5; ++i)	    if (!turn) 	    	plyplace(&plyship[i]);	    else 	    	cpuplace(&cpuship[i]);	}    turn = rnd(2);    cstart = cdir = -1;    cpuhits = 0;    srchstep = 3;    huntoffs = rnd(srchstep);}intrnd(int n){    return(((rand() & 0x7FFF) % n));}voidplyplace(ss)struct _ships *ss;{int c, d;    do {		prompt();		printw("Place your %s (ex.%c%d) ? ",ss->name,rnd(10)+'A',rnd(10));		c = getcoord();		d = getdir();	} while(!checkplace(ss,c,d));    placeship(ss,c,d);}int getdir(){    prompt();     addstr("What direction (0=right, 1=down) ? ");    return(sgetc("01")-'0');}voidplaceship(ss,c,d)struct _ships *ss;int c, d;{int x, y, l, i;    for(l=0; l<ss->length; ++l){		i = c + l * ((d) ? 10 : 1);		board[turn][i] = ss->symbol;		x = (i % 10) * 3 + 3;		y = (i / 10) + 7;		if(!turn) mvaddch(y,x,ss->symbol);	}    ss->start = c;    ss->dir = d;    ss->hits = 0;}intcheckplace(ss,c,d)struct _ships *ss;int c, d;{int x, y, l;    x = c%10; y = c/10;    if(((x+ss->length) > 10 && !d) || ((y+ss->length) > 10 && d==1)){	if(!turn)	    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){	x = c + l * ((d) ? 10 : 1);	if(board[turn][x]){	    if(!turn)		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(0);	    }	}    return(1);}voiderror(s)char *s;{    prompt();     beep();    printw("%s -- hit any key to continue --",s);    refresh();    getch();}voidprompt(){    move(22,0);     clrtoeol();}chargetcoord(){int ch, x, y;redo:    y = sgetc("ABCDEFGHIJ");    do {		ch = getch();		if (ch == 0x7F || ch == 8) {	    	addstr("\b \b"); 	    	refresh();	    	goto redo;	    }	} while(ch < '0' || ch > '9');    addch(x = ch);     refresh();    return((y-'A')*10+x-'0');}voidcpuplace(ss)struct _ships *ss;{int c, d;    do{		c = rnd(100); 		d = rnd(2);	} while(!checkplace(ss,c,d));    placeship(ss,c,d);}intawinna(){int i, j;struct _ships *ss;    for (i = 0; i < 2; ++i) {		ss = (i) ? cpuship : plyship;		for(j=0; j<5; ++j, ++ss)		    if(ss->length != ss->hits)				break;		if(j == 5) return(OTHER);	}    return(-1);}intplyturn(){int c, res;char *m;    prompt();    addstr("Where do you want to shoot? ");    c = getcoord();    if(!(res = hits[turn][c])){	hits[turn][c] = res = (board[OTHER][c]) ? 'H' : 'M';	mvaddch(7+c/10,48+3*(c%10),(res=='H') ? 'H' : 'o');	if(0 != (c = hitship(c))){	    prompt();	    switch(rnd(3)){		case 0:		    m = "You sank my %s!";		    break;		case 1:		    m = "I have this sinking feeling about my %s....";		    break;		case 2:		    m = "Have some mercy for my %s!";		    break;		}	    move(23,0); 	    clrtoeol(); 	    beep();	    printw(m,cpuship[c-1].name); refresh();	    return(awinna() == -1);	    }	}    prompt();    move(23,0); clrtoeol();    printw("You %s.",(res=='M')?"missed":"scored a hit"); refresh();    return(res == 'H');}inthitship(c)int c;{struct _ships *ss;int sym, i, j;    ss = (turn) ? plyship : cpuship;    if (!(sym = board[OTHER][c])) return(0);    for (i = 0; i < 5; ++i, ++ss)	if (ss->symbol == sym) {	    j = ss->hits; 	    ++j; 	    ss->hits = j;	    if (j == ss->length) 	    	return(i+1);	    return(0);	 }   return 0;}int cputurn(){int c, res, x, y, i, d;redo:    if (cstart == -1){		if (cpuhits){		    for(i=0, c=rnd(100); i<100; ++i, c = (c+1) % 100)			if(hits[turn][c] == 'H')			    break;		    if(i != 100){				cstart = c;				cdir = -1;				goto fndir;			}	    }		do {		    i = 0;		    do{				while(hits[turn][c=rnd(100)]);				x = c % 10; y = c / 10;				if(++i == 1000) break;			} while(((x+huntoffs) % srchstep) != (y % srchstep));		    if(i == 1000) --srchstep;	    } while(i == 1000);	}    else if(cdir == -1){fndir:	for(i=0, d=rnd(4); i++ < 4; d = (d+1) % 4){		    x = cstart%10; y = cstart/10;		    switch(d){				case 0: ++x; break;				case 1: ++y; break;				case 2: --x; break;				case 3: --y; break;			}		    if(x<0 || x>9 || y<0 || y>9) continue;		    if(hits[turn][c=y*10+x]) continue;		    cdir = -2;		    break;	    }		if(i == 4){		    cstart = -1;		    goto redo;	    }	}    else{		x = cstart%10; y = cstart/10;		switch(cdir){		    case 0: ++x; break;		    case 1: ++y; break;		    case 2: --x; break;		    case 3: --y; break;	    }		if(x<0 || x>9 || y<0 || y>9 || hits[turn][y*10+x]){		    cdir = (cdir+2) % 4;		    for(;;){				switch(cdir){				    case 0: ++x; break;				    case 1: ++y; break;				    case 2: --x; break;				    case 3: --y; break;			    }				if(x<0 || x>9 || y<0 || y>9){ cstart = -1; 				goto redo; 			}			if(!hits[turn][y*10+x]) break;		}    }	c = y*10 + x;	}    if (!ask) {        res = (board[OTHER][c]) ? 'H' : 'M';        move(21,0); clrtoeol();        printw("I shoot at %c%d. I %s!",c/10+'A',c%10,(res=='H')?"hit":"miss");    } else {        for(;;){	    prompt();	    printw("I shoot at %c%d. Do I (H)it or (M)iss? ",c/10+'A',c%10);	    res = sgetc("HM");	    if((res=='H' && !board[OTHER][c]) || (res=='M' && board[OTHER][c])){	        error("You lie!");	        continue;	        }	    break;	    }        addch(res);    }    hits[turn][c] = res;    if(res == 'H') {	++cpuhits;	if(cstart == -1) cdir = -1;	cstart = c;	if(cdir == -2) cdir = d;	mvaddch(7+(c/10),3+3*(c%10),'*');	if (blitz && !ask) {	    refresh();	    sleep(1);	}    }    else { 	if (seemiss) {	    mvaddch(7+(c/10),3+3*(c%10),' ');	} else {	    if(cdir == -2) cdir = -1;	}    }    if(0 != (c=hitship(c))){	cstart = -1;	cpuhits -= plyship[c-1].length;	x = plyship[c-1].start;	d = plyship[c-1].dir;	y = plyship[c-1].length;	for(i=0; i<y; ++i){	    hits[turn][x] = '*';	    x += (d) ? 10 : 1;	    }	}    if (salvo && !ask) {	refresh();	sleep(1);    }    if(awinna() != -1) return(0);    return(res == 'H');}intplayagain(){int i, x, y, dx, dy, j;    for(i=0; i<5; ++i){	x = cpuship[i].start; y = x/10+7; x = (x % 10) * 3 + 48;	dx = (cpuship[i].dir) ? 0 : 3;	dy = (cpuship[i].dir) ? 1 : 0;	for(j=0; j < cpuship[i].length; ++j){	    mvaddch(y,x,cpuship[i].symbol);	    x += dx; y += dy;	    }	}    if(awinna()) ++cpuwon; else ++plywon;    i = 18 + strlen(name);    if(plywon >= 10) ++i;    if(cpuwon >= 10) ++i;    mvprintw(2,(80-i)/2,"%s: %d     Computer: %d",name,plywon,cpuwon);    prompt();    printw((awinna()) ? "Want to be humiliated again, %s? "		  : "Going to give me a chance for revenge, %s? ",name);    return(sgetc("YN") == 'Y');}voiduninitgame(int sig){    refresh();    endwin();    exit(0);}intsgetc(s)char *s;{char *s1;int ch;    refresh();    for (;;) {		ch = toupper(getch());		for (s1 = s; *s1 && ch != *s1; ++s1);		if (*s1) {	    	addch(ch); 	    	refresh();	    	return(ch);	    }	}}/*  * I should use getopts() from libc.a, but I'm leary that other UNIX * systems might not have it, although I'd love to use it. */ intdo_options(c,op)int c;char *op[];{register int i;    if (c > 1) {		for (i=1; i<c; i++) {		    switch(op[i][0]) {		    default:		    case '?':			fprintf(stderr, "Usage: battle [ -s | -b ] [ -a ] [ -m ]\n");			fprintf(stderr, "\tWhere the options are:\n");			fprintf(stderr, "\t-s : play a salvo game (mutex with -b)\n");			fprintf(stderr, "\t-b : play a blitz game (mutex with -s)\n");			fprintf(stderr, "\t-a : computer asks you for hit/miss\n");			fprintf(stderr, "\t-m : computer misses are displayed\n");			exit(1);			break;		    case '-':			switch(op[i][1]) {			case 'b':			    blitz = 1;			    if (salvo == 1) {				fprintf(stderr,				    "Bad Arg: -b and -s are mutually exclusive\n");				exit(1);			    }			    break;			case 's':			    salvo = 1;			    if (blitz == 1) {				fprintf(stderr,				    "Bad Arg: -s and -b are mutually exclusive\n");				exit(1);			    }			    break;			case 'a':			    ask = 1;			    break;			case 'm':			    seemiss = 1;			    break;			default:			    fprintf(stderr,				"Bad Arg: type \"%s ?\" for usage message\n", op[0]);			    exit(1);			}   		    }		}		fprintf(stdout, "Playing optional game (");		if (salvo) 		    fprintf(stdout, "salvo, noblitz, ");		else if (blitz)			    fprintf(stdout, "blitz, nosalvo, ");			else 			    fprintf(stdout, "noblitz, nosalvo, ");		if (ask) 		    fprintf(stdout, "ask, ");		else 		    fprintf(stdout, "noask, ");		if (seemiss) 		    fprintf(stdout, "seemiss)\n");		else 		    fprintf(stdout, "noseemiss)\n");	}	    else	fprintf(stdout,	    "Playing standard game (no blitz, no slavo, no ask, no seemiss)\n");    sleep(2);    return(0);}intscount(who)int who;{int i, shots;struct _ships *sp;    if (who) {	/* count cpu shots */	sp = cpuship;    } else {	/* count player shots */	sp = plyship;    }    for (i=0, shots = 0; i<5; i++, sp++) {	/* extra test for machines with unsigned chars! */	if (sp->hits == (char) -1 || sp->hits >= sp->length) {	    continue;	/* dead ship */	} else {	    shots++;	}    }    return(shots);}

⌨️ 快捷键说明

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