1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #ifndef lint
9 static char sccsid[] = "@(#)dr_2.c 8.1 (Berkeley) 05/31/93";
10 #endif /* not lint */
11
12 #include "driver.h"
13
14 #define couldwin(f,t) (f->specs->crew2 > t->specs->crew2 * 1.5)
15
thinkofgrapples()16 thinkofgrapples()
17 {
18 register struct ship *sp, *sq;
19 char friendly;
20
21 foreachship(sp) {
22 if (sp->file->captain[0] || sp->file->dir == 0)
23 continue;
24 foreachship(sq) {
25 friendly = sp->nationality == capship(sq)->nationality;
26 if (!friendly) {
27 if (sp->file->struck || sp->file->captured != 0)
28 continue;
29 if (range(sp, sq) != 1)
30 continue;
31 if (grappled2(sp, sq))
32 if (toughmelee(sp, sq, 0, 0))
33 ungrap(sp, sq);
34 else
35 grap(sp, sq);
36 else if (couldwin(sp, sq)) {
37 grap(sp, sq);
38 sp->file->loadwith = L_GRAPE;
39 }
40 } else
41 ungrap(sp, sq);
42 }
43 }
44 }
45
checkup()46 checkup()
47 {
48 register struct ship *sp, *sq;
49 register char explode, sink;
50
51 foreachship(sp) {
52 if (sp->file->dir == 0)
53 continue;
54 explode = sp->file->explode;
55 sink = sp->file->sink;
56 if (explode != 1 && sink != 1)
57 continue;
58 if (die() < 5)
59 continue;
60 Write(sink == 1 ? W_SINK : W_EXPLODE, sp, 0, 2, 0, 0, 0);
61 Write(W_DIR, sp, 0, 0, 0, 0, 0);
62 if (snagged(sp))
63 foreachship(sq)
64 cleansnag(sp, sq, 1);
65 if (sink != 1) {
66 makesignal(sp, "exploding!", (struct ship *)0);
67 foreachship(sq) {
68 if (sp != sq && sq->file->dir && range(sp, sq) < 4)
69 table(RIGGING, L_EXPLODE, sp->specs->guns/13, sq, sp, 6);
70 }
71 } else
72 makesignal(sp, "sinking!", (struct ship *)0);
73 }
74 }
75
prizecheck()76 prizecheck()
77 {
78 register struct ship *sp;
79
80 foreachship(sp) {
81 if (sp->file->captured == 0)
82 continue;
83 if (sp->file->struck || sp->file->dir == 0)
84 continue;
85 if (sp->specs->crew1 + sp->specs->crew2 + sp->specs->crew3 > sp->file->pcrew * 6) {
86 Write(W_SIGNAL, sp, 1,
87 (int)"prize crew overthrown", 0, 0, 0);
88 Write(W_POINTS, sp->file->captured, 0, sp->file->captured->file->points - 2 * sp->specs->pts, 0, 0, 0);
89 Write(W_CAPTURED, sp, 0, -1, 0, 0, 0);
90 }
91 }
92 }
93
strend(str)94 strend(str)
95 char *str;
96 {
97 register char *p;
98
99 for (p = str; *p; p++)
100 ;
101 return p == str ? 0 : p[-1];
102 }
103
closeon(from,to,command,ta,ma,af)104 closeon(from, to, command, ta, ma, af)
105 register struct ship *from, *to;
106 char command[];
107 int ma, ta, af;
108 {
109 int high;
110 char temp[10];
111
112 temp[0] = command[0] = '\0';
113 high = -30000;
114 try(command, temp, ma, ta, af, ma, from->file->dir, from, to, &high, 0);
115 }
116
117 int dtab[] = {0,1,1,2,3,4,4,5}; /* diagonal distances in x==y */
118
score(movement,ship,to,onlytemp)119 score(movement, ship, to, onlytemp)
120 char movement[];
121 register struct ship *ship, *to;
122 char onlytemp;
123 {
124 char drift;
125 int row, col, dir, total, ran;
126 register struct File *fp = ship->file;
127
128 if ((dir = fp->dir) == 0)
129 return 0;
130 row = fp->row;
131 col = fp->col;
132 drift = fp->drift;
133 move(movement, ship, &fp->dir, &fp->row, &fp->col, &drift);
134 if (!*movement)
135 (void) strcpy(movement, "d");
136
137 ran = range(ship, to);
138 total = -50 * ran;
139 if (ran < 4 && gunsbear(ship, to))
140 total += 60;
141 if ((ran = portside(ship, to, 1) - fp->dir) == 4 || ran == -4)
142 total = -30000;
143
144 if (!onlytemp) {
145 fp->row = row;
146 fp->col = col;
147 fp->dir = dir;
148 }
149 return total;
150 }
151
move(p,ship,dir,row,col,drift)152 move(p, ship, dir, row, col, drift)
153 register char *p;
154 register struct ship *ship;
155 register char *dir;
156 register short *row, *col;
157 register char *drift;
158 {
159 int dist;
160 char moved = 0;
161
162 for (; *p; p++) {
163 switch (*p) {
164 case 'r':
165 if (++*dir == 9)
166 *dir = 1;
167 break;
168 case 'l':
169 if (--*dir == 0)
170 *dir = 8;
171 break;
172 case '1': case '2': case '3': case '4':
173 case '5': case '6': case '7':
174 moved++;
175 if (*dir % 2 == 0)
176 dist = dtab[*p - '0'];
177 else
178 dist = *p - '0';
179 *row -= dr[*dir] * dist;
180 *col -= dc[*dir] * dist;
181 break;
182 }
183 }
184 if (!moved) {
185 if (windspeed != 0 && ++*drift > 2) {
186 if (ship->specs->class >= 3 && !snagged(ship)
187 || (turn & 1) == 0) {
188 *row -= dr[winddir];
189 *col -= dc[winddir];
190 }
191 }
192 } else
193 *drift = 0;
194 }
195
try(command,temp,ma,ta,af,vma,dir,f,t,high,rakeme)196 try(command, temp, ma, ta, af, vma, dir, f, t, high, rakeme)
197 register struct ship *f, *t;
198 int ma, ta, af, *high, rakeme;
199 char command[], temp[];
200 {
201 register int new, n;
202 char st[4];
203 #define rakeyou (gunsbear(f, t) && !gunsbear(t, f))
204
205 if ((n = strend(temp)) < '1' || n > '9')
206 for (n = 1; vma - n >= 0; n++) {
207 (void) sprintf(st, "%d", n);
208 (void) strcat(temp, st);
209 new = score(temp, f, t, rakeme);
210 if (new > *high && (!rakeme || rakeyou)) {
211 *high = new;
212 (void) strcpy(command, temp);
213 }
214 try(command, temp, ma-n, ta, af, vma-n,
215 dir, f, t, high, rakeme);
216 rmend(temp);
217 }
218 if (ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r' || !strlen(temp)) {
219 (void) strcat(temp, "r");
220 new = score(temp, f, t, rakeme);
221 if (new > *high && (!rakeme || gunsbear(f, t) && !gunsbear(t, f))) {
222 *high = new;
223 (void) strcpy(command, temp);
224 }
225 try(command, temp, ma-1, ta-1, af, min(ma-1, maxmove(f, (dir == 8 ? 1 : dir+1), 0)), (dir == 8 ? 1 : dir+1),f,t,high,rakeme);
226 rmend(temp);
227 }
228 if ((ma > 0 && ta > 0 && (n = strend(temp)) != 'l' && n != 'r') || !strlen(temp)){
229 (void) strcat(temp, "l");
230 new = score(temp, f, t, rakeme);
231 if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))){
232 *high = new;
233 (void) strcpy(command, temp);
234 }
235 try(command, temp, ma-1, ta-1, af, (min(ma-1,maxmove(f, (dir-1 ? dir-1 : 8), 0))), (dir-1 ? dir -1 : 8), f, t, high, rakeme);
236 rmend(temp);
237 }
238 }
239
rmend(str)240 rmend(str)
241 char *str;
242 {
243 register char *p;
244
245 for (p = str; *p; p++)
246 ;
247 if (p != str)
248 *--p = 0;
249 }
250