1
/****************************************************************************
2
* Copyright (c) 1998-2005,2006 Free Software Foundation, Inc. *
4
* Permission is hereby granted, free of charge, to any person obtaining a *
5
* copy of this software and associated documentation files (the *
6
* "Software"), to deal in the Software without restriction, including *
7
* without limitation the rights to use, copy, modify, merge, publish, *
8
* distribute, distribute with modifications, sublicense, and/or sell *
9
* copies of the Software, and to permit persons to whom the Software is *
10
* furnished to do so, subject to the following conditions: *
12
* The above copyright notice and this permission notice shall be included *
13
* in all copies or substantial portions of the Software. *
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
16
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
17
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
18
* IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
19
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
20
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
21
* THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
23
* Except as contained in this notice, the name(s) of the above copyright *
24
* holders shall not be used in advertising or otherwise to promote the *
25
* sale, use or other dealings in this Software without prior written *
27
****************************************************************************/
2
29
* bs.c - original author: Bruce Holloway
3
30
* salvo option by: Chuck A DeGaul
7
34
* v2.0 featuring strict ANSI/POSIX conformance, November 1993.
8
35
* v2.1 with ncurses mouse support, September 1995
10
* $Id: bs.c,v 1.41 2005/05/28 21:38:24 tom Exp $
37
* $Id: bs.c,v 1.44 2006/05/20 15:38:52 tom Exp $
13
40
#include <test.priv.h>
150
177
static RETSIGTYPE uninitgame(int sig) GCC_NORETURN;
152
static RETSIGTYPE uninitgame(int sig GCC_UNUSED)
180
uninitgame(int sig GCC_UNUSED)
153
181
/* end the game, either normally or due to signal */
191
219
srand((unsigned) (time(0L) + getpid())); /* Kick the random number generator */
193
(void) signal(SIGINT, uninitgame);
194
(void) signal(SIGINT, uninitgame);
195
(void) signal(SIGIOT, uninitgame); /* for assert(3) */
196
if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
197
(void) signal(SIGQUIT, uninitgame);
221
CATCHALL(uninitgame);
199
223
if ((tmpname = getlogin()) != 0) {
200
224
(void) strcpy(name, tmpname);
950
973
#endif /* A_COLOR */
952
return ((hit ? (sunk ? S_SUNK : S_HIT) : S_MISS) ? TRUE : FALSE);
975
return hit ? (sunk ? S_SUNK : S_HIT) : S_MISS;
956
979
* This code implements a fairly irregular FSM, so please forgive the rampant
957
980
* unstructuredness below. The five labels are states which need to be held
958
981
* between computer turns.
983
* The FSM is not externally reset to RANDOM_FIRE if the player wins. Instead,
984
* the other states check for "impossible" conditions which signify a new
985
* game, then if found transition to RANDOM_FIRE.
1003
1030
if (navail == 0) /* no valid places for shots adjacent... */
1004
1031
goto refire; /* ...so we must random-fire */
1006
for (d = 0, n = rnd(navail) + 1; n; n--)
1033
n = rnd(navail) + 1;
1034
for (d = 0; used[d]; d++) ;
1035
/* used[d] is first that == 0 */
1038
/* used[d] is next that == 0 */
1041
assert(used[d] == FALSE);
1013
1044
x = ts.x + xincr[d * 2];
1014
1045
y = ts.y + yincr[d * 2];
1042
1073
case REVERSE_JUMP: /* nail down the ship's other end */
1074
d = (ts.dir + 4) % 8;
1044
1075
x = ts.x + ts.hits * xincr[d];
1045
1076
y = ts.y + ts.hits * yincr[d];
1046
1077
if (POSSIBLE(x, y) && (hit = cpufire(x, y))) {
1053
1084
next = RANDOM_FIRE;
1056
case SECOND_PASS: /* kill squares not caught on first pass */
1087
case SECOND_PASS: /* continue shooting after reversing */
1057
1088
x = ts.x + xincr[ts.dir];
1058
1089
y = ts.y + yincr[ts.dir];
1059
1090
if (POSSIBLE(x, y) && (hit = cpufire(x, y))) {
1070
/* check for continuation and/or winner */
1101
/* pause between shots in salvo */
1072
1103
(void) refresh();
1073
1104
(void) sleep(1);
1079
1107
(void) mvprintw(PROMPTLINE + 2, 0,
1080
1108
"New state %d, x=%d, y=%d, d=%d",