fixed clear lastline when quitting
[unix-history] / usr / src / games / sail / dr_3.c
CommitLineData
b860dc81 1#ifndef lint
2fb1fc86 2static char *sccsid = "@(#)dr_3.c 2.2 83/11/01";
b860dc81 3#endif
b860dc81 4
b3a57661 5#include "driver.h"
b860dc81
CL
6
7moveall() /* move all comp ships */
8{
b3a57661
EW
9 register struct ship *sp, *sq; /* r11, r10 */
10 register int n; /* r9 */
11 struct ship *closest;
12 register int k, l, m, ma; /* r8, r7, r6, */
6c17b19a
EW
13 int ta;
14 char af;
b3a57661
EW
15 int row[NSHIP], col[NSHIP], dir[NSHIP], r1, r2, c1, c2, d1, d2;
16 char clast[NSHIP][sizeof SHIP(0)->file->last];
b860dc81 17
b3a57661
EW
18 /*
19 * first try to create moves for OUR ships
20 */
21 foreachship(sp) {
6c17b19a 22 if (sp->file->captain[0] || sp->file->dir == 0)
b3a57661
EW
23 continue;
24 if (!sp->file->struck && windspeed && !snagged(sp)
25 && sp->specs->crew3) {
6c17b19a 26 ta = maxturns(sp, &af);
b3a57661
EW
27 ma = maxmove(sp, sp->file->dir, 0);
28 closest = closestenemy(sp, 0, 0);
29 if (closest == 0)
30 *sp->file->last = '\0';
b860dc81 31 else
b3a57661
EW
32 closeon(sp, closest, sp->file->last,
33 ta, ma, af);
34 } else
35 *sp->file->last = '\0';
759267e0
EW
36 /*
37 makesignal(sp, "move (%d): %s", 0, turn, sp->file->last);
38 */
b860dc81 39 }
b3a57661
EW
40 /*
41 * Then execute the moves for ALL ships (dead ones too),
42 * saving old positions in row[], col[], dir[],
43 * and the moves in clase[][].
44 * The new positions are written out.
45 */
46 n = 0;
47 foreachship(sp) {
48 if (snagged(sp))
b860dc81 49 clast[n][0] = '\0';
b3a57661
EW
50 else
51 (void) strcpy(clast[n], sp->file->last);
52 row[n] = sp->file->row;
53 col[n] = sp->file->col;
54 dir[n] = sp->file->dir;
55 moveship(sp, clast[n]);
56 n++;
b860dc81 57 }
b3a57661
EW
58 /*
59 * Now resolve collisions.
60 * This is the tough part.
61 */
62 for (k = 0; stillmoving(clast, k); k++) {
63 /*
64 * Step once.
65 * And propagate the nulls at the end of clast[].
66 */
67 n = 0;
68 foreachship(sp) {
b860dc81 69 if (dir[n])
b3a57661 70 step(clast[n][k], sp, row+n, col+n, dir+n);
b860dc81
CL
71 if (!clast[n][k])
72 clast[n][k+1] = '\0';
b3a57661 73 n++;
b860dc81 74 }
b3a57661
EW
75 /*
76 * The real stuff.
77 */
78 n = 0;
79 foreachship(sp) {
80 if ((d1 = sp->file->dir) == 0 || isolated(sp))
759267e0 81 goto cont1;
b3a57661
EW
82 r1 = sp->file->row;
83 c1 = sp->file->col;
84 sp->file->dir = dir[n];
85 sp->file->row = row[n];
86 sp->file->col = col[n];
87 l = 0;
88 foreachship(sq) {
759267e0
EW
89 if (sp == sq)
90 goto cont2;
91 if ((d2 = sq->file->dir) == 0)
92 goto cont2;
b3a57661
EW
93 r2 = sq->file->row;
94 c2 = sq->file->col;
95 sq->file->dir = dir[l];
96 sq->file->row = row[l];
97 sq->file->col = col[l];
759267e0 98 if (snagged2(sp, sq)
b3a57661
EW
99 && push(sp, sq) && range(sp, sq) > 1) {
100 Write(W_SHIPROW, sq, 0,
101 sp->file->row - 1, 0, 0, 0);
102 if (sp->file->dir == 1
2fb1fc86 103 || sp->file->dir == 5)
b3a57661
EW
104 Write(W_SHIPCOL, sq, 0,
105 sp->file->col - 1,
106 0, 0, 0);
107 else
108 Write(W_SHIPCOL, sq, 0,
109 sp->file->col, 0, 0, 0);
110 Write(W_SHIPDIR, sq, 0,
111 sp->file->dir, 0, 0, 0);
112 }
113 if (!range(sp, sq) && !fouled2(sp, sq)
114 && push(sp, sq)) {
115 makesignal(sp,
116 "collision with %s (%c%c)", sq);
117 if (die() < 4) {
118 makesignal(sp,
119 "fouled with %s (%c%c)",
120 sq);
121 for (m = 0; m < NSHIP && sp->file->fouls[m].turnfoul; m++)
122 ;
123 if (m < NSHIP)
124 Write(W_FOUL, sp, 0,
125 m, turn, l, 0);
126 for (m = 0; m < NSHIP && sq->file->fouls[m].turnfoul; m++)
127 ;
128 if (m < NSHIP)
129 Write(W_FOUL, sq, 0,
130 m, turn, n, 0);
b860dc81 131 }
b3a57661
EW
132 clast[n][k+1] = '\0';
133 sp->file->row = r2;
134 sp->file->col = c2;
135 sp->file->dir = d2;
136 moveship(sp, clast[n]);
137 Write(W_SHIPROW, sq, 0,
138 sp->file->row-1, 0, 0, 0);
139 if (sp->file->dir == 1
140 || sp->file->dir == 5)
141 Write(W_SHIPCOL, sq, 0,
142 sp->file->col-1, 0, 0, 0);
143 else
144 Write(W_SHIPCOL, sq, 0,
145 sp->file->col, 0, 0, 0);
146 Write(W_SHIPDIR, sq, 0,
147 sp->file->dir, 0, 0, 0);
148 Write(W_DRIFT, sq, 0, 0, 0, 0, 0);
149 Write(W_DRIFT, sp, 0, 0, 0, 0, 0);
759267e0 150 goto cont2;
b860dc81 151 }
759267e0
EW
152 sq->file->row = r2;
153 sq->file->col = c2;
154 sq->file->dir = d2;
155 cont2:
b3a57661 156 l++;
b860dc81 157 }
b3a57661
EW
158 sp->file->row = r1;
159 sp->file->col = c1;
160 sp->file->dir = d1;
759267e0 161 cont1:
b3a57661 162 n++;
b860dc81
CL
163 }
164 }
b3a57661
EW
165 /*
166 * Clear old moves.
167 */
168 foreachship(sp)
169 sp->file->last[0] = 0;
b860dc81
CL
170}
171
172stillmoving(last, k)
b3a57661 173char last[][sizeof SHIP(0)->file->last]; /* how's that for portability */
b860dc81
CL
174register int k;
175{
b3a57661
EW
176 register struct ship *sp;
177 register char (*p)[sizeof *last]; /* and this? */
b860dc81 178
b3a57661
EW
179 p = last;
180 foreachship(sp) {
181 if ((*p)[k])
182 return 1;
183 p++;
184 }
185 return 0;
b860dc81
CL
186}
187
188isolated(ship)
b3a57661 189register struct ship *ship;
b860dc81 190{
b3a57661 191 register struct ship *sp;
b860dc81 192
b3a57661
EW
193 foreachship(sp) {
194 if (ship != sp && range(ship, sp) <= 10)
195 return 0;
196 }
197 return 1;
b860dc81
CL
198}
199
200push(from, to)
b3a57661 201register struct ship *from, *to;
b860dc81 202{
b860dc81
CL
203 register int bs, sb;
204
b3a57661
EW
205 sb = to->specs->class;
206 bs = from->specs->class;
207 if (sb > bs)
208 return 1;
b860dc81 209 if (sb < bs)
b3a57661
EW
210 return 0;
211 return from < to;
b860dc81
CL
212}
213
b3a57661
EW
214step(com, ship, row, col, dir)
215register struct ship *ship;
216register int *row, *col, *dir;
b860dc81
CL
217char com;
218{
b860dc81
CL
219 register int dist;
220
b3a57661
EW
221 switch (com) {
222 case 'r':
223 if (++*dir == 9)
224 *dir = 1;
225 break;
226 case 'l':
227 if (--*dir == 0)
228 *dir = 8;
229 break;
230 case '0': case '1': case '2': case '3':
231 case '4': case '5': case '6': case '7':
232 if (*dir % 2 == 0)
233 dist = dtab[com - '0'];
234 else
235 dist = com - '0';
236 *row -= dr[*dir] * dist;
237 *col -= dc[*dir] * dist;
238 break;
239 case 'b':
240 break;
241 case 'd':
242 if (ship->specs->class >= 3 && !snagged(ship)
243 || turn % 2 == 0) {
244 *row -= dr[winddir];
245 *col -= dc[winddir];
246 }
247 break;
b860dc81
CL
248 }
249}
250
b3a57661
EW
251sendbp(from, to, sections, isdefense)
252register struct ship *from, *to;
253int sections;
254char isdefense;
b860dc81
CL
255{
256 int n;
b3a57661 257 register struct BP *bp;
b860dc81 258
b3a57661
EW
259 bp = isdefense ? from->file->DBP : from->file->OBP;
260 for (n = 0; n < 3 && bp[n].turnsent; n++)
261 ;
262 if (n < 3 && sections) {
263 Write(isdefense ? W_DBP : W_OBP, from, 0,
264 turn, to-SHIP(0), sections, 0);
265 if (isdefense)
266 makesignal(from, "repelling boarders",
267 (struct ship *)0);
b860dc81 268 else
b3a57661 269 makesignal(from, "boarding the %s (%c%c)", to);
b860dc81
CL
270 }
271}
272
b3a57661
EW
273toughmelee(ship, to, isdefense, count)
274register struct ship *ship, *to;
275int isdefense, count;
b860dc81 276{
b3a57661
EW
277 register struct BP *bp;
278 register obp = 0;
279 int n, OBP = 0, DBP = 0, dbp = 0;
b860dc81 280 int qual;
b860dc81 281
b3a57661
EW
282 qual = ship->specs->qual;
283 bp = isdefense ? ship->file->DBP : ship->file->OBP;
284 for (n = 0; n < NBP; n++, bp++) {
285 if (bp->turnsent && (to == bp->toship || isdefense)) {
286 obp += bp->mensent / 100
287 ? ship->specs->crew1 * qual : 0;
288 obp += (bp->mensent % 100)/10
289 ? ship->specs->crew2 * qual : 0;
290 obp += bp->mensent % 10
291 ? ship->specs->crew3 * qual : 0;
b860dc81
CL
292 }
293 }
b3a57661
EW
294 if (count || isdefense)
295 return obp;
296 OBP = toughmelee(to, ship, 0, count + 1);
297 dbp = toughmelee(ship, to, 1, count + 1);
298 DBP = toughmelee(to, ship, 1, count + 1);
b860dc81 299 if (OBP > obp + 10 || OBP + DBP >= obp + dbp + 10)
b3a57661 300 return 1;
b860dc81 301 else
b3a57661 302 return 0;
b860dc81
CL
303}
304
305reload()
306{
b3a57661 307 register struct ship *sp;
b860dc81 308
b3a57661
EW
309 foreachship(sp) {
310 sp->file->loadwith = 0;
311 }
b860dc81
CL
312}
313
314checksails()
315{
b3a57661
EW
316 register struct ship *sp;
317 register int rig, full;
318 struct ship *close;
b860dc81 319
b3a57661
EW
320 foreachship(sp) {
321 if (sp->file->captain[0] != 0)
322 continue;
323 rig = sp->specs->rig1;
324 if (windspeed == 6 || windspeed == 5 && sp->specs->class > 4)
b860dc81 325 rig = 0;
b3a57661
EW
326 if (rig && sp->specs->crew3) {
327 close = closestenemy(sp, 0, 0);
328 if (close != 0) {
329 if (range(sp, close) > 9)
330 full = 1;
331 else
b860dc81 332 full = 0;
b3a57661 333 } else
b860dc81 334 full = 0;
b3a57661
EW
335 } else
336 full = 0;
337 if ((sp->file->FS != 0) != full)
338 Write(W_FS, sp, 0, full, 0, 0, 0);
b860dc81
CL
339 }
340}