Example #1
0
static bool
collidecheck(int b, int y, int x)
/* is this location on the selected zboard adjacent to a ship? */
{
    bool collide;

    /* anything on the square */
    if ((collide = IS_SHIP(board[b][x][y])) != FALSE)
	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)
		&& IS_SHIP(board[b][xend][yend])) {
		collide = TRUE;
		break;
	    }
	}
    }
    return (collide);
}
Example #2
0
/* is this location on the selected zboard adjacent to a ship? */
static int
collidecheck(int b, int y, int x)
{
    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);
}
Example #3
0
File: bs.c Project: a565109863/src
static bool
checkplace(int b, ship_t *ss, int vis)
{
    int l, xend, yend;

    /* first, check for board edges */
    xend = ss->x + (ss->length - 1) * xincr[ss->dir];
    yend = ss->y + (ss->length - 1) * 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(FALSE);
    }

    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);
}
Example #4
0
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]) == 0)
	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
				    (void) attrset(0);
#endif /* A_COLOR */
				} else {
				    pgoto(y1, x1);
				    (void) addch(SHOWSPLASH);
				}
			    }
			}
		    }

		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));
		    } else {
			pgoto(y1, x1);
#ifdef A_COLOR
			if (has_colors())
			    attron(COLOR_PAIR(COLOR_RED));
#endif /* A_COLOR */
			(void) addch(SHOWHIT);
#ifdef A_COLOR
			(void) attrset(0);
#endif /* A_COLOR */
		    }
		}

		(void) move(oldy, oldx);
		return (ss);
	    }
	}
    (void) move(oldy, oldx);
    return ((ship_t *) NULL);
}
Example #5
0
/* a hit on the targeted ship */
static ship_t *
hitship(int x, int y)
{
    ship_t *sb, *ss;
    char sym;
    int oldx, oldy;

    getyx(stdscr, oldy, oldx);
    sb = (turn) ? plyship : cpuship;
    if(!(sym = board[OTHER][x][y]))
	return(NULL);
    for(ss = sb; ss < sb + SHIPTYPES; ++ss)
	if(ss->symbol == sym)
	{
	    if (++ss->hits < ss->length) {	/* still afloat? */
			return(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 cx, cy;

			    	cx = bx + i * xincr[ss->dir];
			    	cy = by + i * yincr[ss->dir];
			    	if (ONBOARD(cx, cy)) {
						hits[turn][cx][cy] = MARK_MISS;
						if (turn % 2 == PLAYER) {
				    		cgoto(cy, cx);
#ifdef A_COLOR
				    		if (has_colors())
								attron(COLOR_PAIR(COLOR_GREEN));
#endif /* A_COLOR */

				    		addch(MARK_MISS);
#ifdef A_COLOR
				    		attrset(0);
#endif /* A_COLOR */
						}
			    	}
				}
	    	}
		}

		for (i = 0; i < ss->length; ++i)
		{
		    int dx = ss->x + i * xincr[ss->dir];
		    int dy = ss->y + i * yincr[ss->dir];

		    hits[turn][dx][dy] = ss->symbol;
		    if (turn % 2 == PLAYER)
		    {
			cgoto(dy, dx);
			addch(ss->symbol);
		    }
		}

		move(oldy, oldx);
		return(ss);
	    }
	}
    move(oldy, oldx);
    return(NULL);
}
Example #6
0
File: bs.c Project: a565109863/src
/*
 * 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 int
cputurn(void)
{
    static bool used[4];
    static ship_t ts;
    int navail, x, y, d, n, hit = S_MISS;
    bool closenoshot = FALSE;

    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[W/2] = (!(cpushipcanfit(ts.x,ts.y,cpushortest,E)));
	used[S/2] = used[N/2] = (!(cpushipcanfit(ts.x,ts.y,cpushortest,S)));
	/* 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--,d++)
		while (used[d])
		    d++;
	    d--;

	    x = ts.x + xincr[d*2];
	    y = ts.y + yincr[d*2];

	    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))
	{
	    if ((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;
	}
	else
	    next = REVERSE_JUMP;
	/* FALL THROUGH */

    case REVERSE_JUMP:	/* nail down the ship's other end */
	ts.dir = (ts.dir + 4) % 8;
	ts.x += (ts.hits-1) * xincr[ts.dir];
	ts.y += (ts.hits-1) * yincr[ts.dir];
	/* FALL THROUGH */

    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))
	{
	    if ((hit = cpufire(x, y)))
	    {
		    ts.x = x; ts.y = y; ts.hits++;
		    next = (hit == S_SUNK) ? RANDOM_FIRE : SECOND_PASS;
	    }
	    else
	    {
	    /* The only way to get here is if closepack is on; otherwise,
	     * we _have_ sunk the ship.  I set hit to S_SUNK just to get
	     * the additional closepack logic at the end of the switch.
	     */
/*assert closepack*/
if (!closepack)  error("Assertion failed: not closepack 1");
		    hit = S_SUNK;
		    next = RANDOM_FIRE;
	    }
	}
	else
	{
/*assert closepack*/
if (!closepack)  error("Assertion failed: not closepack 2");
	    hit = S_SUNK;
	    closenoshot = TRUE;  /* Didn't shoot yet! */
	    next = RANDOM_FIRE;
	}
	break;
    }   /* switch(next) */

    if (hit == S_SUNK)
    {
	   /* Update cpulongest and cpushortest.  We could increase srchstep
	    * if it's smaller than cpushortest but that makes strategic sense
	    * only if we've been doing continuous diagonal stripes, and that's
	    * less interesting to watch.
	    */
	    ship_t *sp = plyship;

	    cpushortest = cpulongest;
	    cpulongest  = 0;
	    for (d=0 ; d < SHIPTYPES; d++, sp++)
	    {
		   if (sp->hits < sp->length)
		   {
		cpushortest = (cpushortest < sp->length) ? cpushortest : sp->length;
		cpulongest  = (cpulongest  > sp->length) ? cpulongest  : sp->length;
		   }
	    }
	    /* Now, if we're in closepack mode, we may have knocked off part of
	     * another ship, in which case we shouldn't do RANDOM_FIRE.  A
		* more robust implementation would probably do this check regardless
		* of whether closepack was set or not.
		* Note that MARK_HIT is set only for ships that aren't sunk;
		* hitship() changes the marker to the ship's character when the
		* ship is sunk.
	     */
	    if (closepack)
	    {
		  ts.hits = 0;
		  for (x = 0; x < BWIDTH; x++)
			for (y = 0; y < BDEPTH; y++)
			{
				if (hits[COMPUTER][x][y] == MARK_HIT)
				{
				/* So we found part of another ship.  It may have more
				 * than one hit on it.  Check to see if it does.  If no
				 * hit does, take the last MARK_HIT and be RANDOM_HIT.
				 */
	ts.x = x; ts.y = y; ts.hits = 1;
	for (d = 0; d < 8; d += 2)
	{
	    while ((ONBOARD(ts.x, ts.y)) && 
			(hits[COMPUTER][(int)ts.x][(int)ts.y] == MARK_HIT))
	    {
		    ts.x += xincr[d]; ts.y += yincr[d]; ts.hits++;
	    }
	    if ((--ts.hits > 1) && (ONBOARD(ts.x, ts.y)) &&
		    (hits[COMPUTER][(int)ts.x][(int)ts.y] == 0))
	    {
		    ts.dir = d;
		    ts.x -= xincr[d]; ts.y -= yincr[d];
		    d = 100;                  /* use as a flag */
		    x = BWIDTH; y = BDEPTH;   /* end the loop */
	    } else {
	         ts.x = x; ts.y = y; ts.hits = 1;
	    }
	
	}
				}
				if (ts.hits)
				{
					next = (d >= 100) ? FIRST_PASS : RANDOM_HIT;
				} else
					next = RANDOM_FIRE;
				}
	    }
	    if (closenoshot)
	    {
		   return(cputurn());
	    }
    }

    /* check for continuation and/or winner */
    if (salvo)
    {
	(void)refresh();
	(void)sleep(1);
    }

    return(hit);
}