(linenum→info "unix/slp.c:2238")

bsd-games/2.17/sail/dr_2.c

    1: /*      $NetBSD: dr_2.c,v 1.19 2003/08/07 09:37:41 agc Exp $ */
    2: 
    3: /*
    4:  * Copyright (c) 1983, 1993
    5:  *      The Regents of the University of California.  All rights reserved.
    6:  *
    7:  * Redistribution and use in source and binary forms, with or without
    8:  * modification, are permitted provided that the following conditions
    9:  * are met:
   10:  * 1. Redistributions of source code must retain the above copyright
   11:  *    notice, this list of conditions and the following disclaimer.
   12:  * 2. Redistributions in binary form must reproduce the above copyright
   13:  *    notice, this list of conditions and the following disclaimer in the
   14:  *    documentation and/or other materials provided with the distribution.
   15:  * 3. Neither the name of the University nor the names of its contributors
   16:  *    may be used to endorse or promote products derived from this software
   17:  *    without specific prior written permission.
   18:  *
   19:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29:  * SUCH DAMAGE.
   30:  */
   31: 
   32: #include <sys/cdefs.h>
   33: #ifndef lint
   34: #if 0
   35: static char sccsid[] = "@(#)dr_2.c      8.1 (Berkeley) 5/31/93";
   36: #else
   37: __RCSID("$NetBSD: dr_2.c,v 1.19 2003/08/07 09:37:41 agc Exp $");
   38: #endif
   39: #endif /* not lint */
   40: 
   41: #include <stdio.h>
   42: #include <stdlib.h>
   43: #include <string.h>
   44: #include "extern.h"
   45: #include "driver.h"
   46: 
   47: #define couldwin(f,t) (f->specs->crew2 > t->specs->crew2 * 1.5)
   48: 
   49: static int      str_end(const char *);
   50: static int      score(struct ship *, struct ship *, char *, int);
   51: static void     move_ship(struct ship *, const char *, unsigned char *, short *, short *, char *);
   52: static void     try(struct ship *, struct ship *, char *, char *, int, int, int, int, int, int *, int);
   53: static void     rmend(char *);
   54: 
   55: const int dtab[] = {0,1,1,2,3,4,4,5};   /* diagonal distances in x==y */
   56: 
   57: void
   58: thinkofgrapples(void)
   59: {
   60:         struct ship *sp, *sq;
   61:         char friendly;
   62: 
   63:         foreachship(sp) {
   64:                 if (sp->file->captain[0] || sp->file->dir == 0)
   65:                         continue;
   66:                 foreachship(sq) {
   67:                         friendly = sp->nationality == capship(sq)->nationality;
   68:                         if (!friendly) {
   69:                                 if (sp->file->struck || sp->file->captured != 0)
   70:                                         continue;
   71:                                 if (range(sp, sq) != 1)
   72:                                         continue;
   73:                                 if (grappled2(sp, sq))
   74:                                         if (is_toughmelee(sp, sq, 0, 0))
   75:                                                 ungrap(sp, sq);
   76:                                         else
   77:                                                 grap(sp, sq);
   78:                                 else if (couldwin(sp, sq)) {
   79:                                         grap(sp, sq);
   80:                                         sp->file->loadwith = L_GRAPE;
   81:                                 }
   82:                         } else
   83:                                 ungrap(sp, sq);
   84:                 }
   85:         }
   86: }
   87: 
   88: void
   89: checkup(void)
   90: {
   91:         struct ship *sp, *sq;
   92:         char explode, sink;
   93: 
   94:         foreachship(sp) {
   95:                 if (sp->file->dir == 0)
   96:                         continue;
   97:                 explode = sp->file->explode;
   98:                 sink = sp->file->sink;
   99:                 if (explode != 1 && sink != 1)
  100:                         continue;
  101:                 if (dieroll() < 5)
  102:                         continue;
  103:                 Write(sink == 1 ? W_SINK : W_EXPLODE, sp, 2, 0, 0, 0);
  104:                 Write(W_DIR, sp, 0, 0, 0, 0);
  105:                 if (snagged(sp))
  106:                         foreachship(sq)
  107:                                 cleansnag(sp, sq, 1);
  108:                 if (sink != 1) {
  109:                         makemsg(sp, "exploding!");
  110:                         foreachship(sq) {
  111:                                 if (sp != sq && sq->file->dir && range(sp, sq) < 4)
  112:                                         table(sp, sq, RIGGING, L_EXPLODE, sp->specs->guns/13, 6);
  113:                         }
  114:                 } else
  115:                         makemsg(sp, "sinking!");
  116:         }
  117: }
  118: 
  119: void
  120: prizecheck(void)
  121: {
  122:         struct ship *sp;
  123: 
  124:         foreachship(sp) {
  125:                 if (sp->file->captured == 0)
  126:                         continue;
  127:                 if (sp->file->struck || sp->file->dir == 0)
  128:                         continue;
  129:                 if (sp->specs->crew1 + sp->specs->crew2 + sp->specs->crew3 > sp->file->pcrew * 6) {
  130:                         Writestr(W_SIGNAL, sp, "prize crew overthrown");
  131:                         Write(W_POINTS, sp->file->captured, sp->file->captured->file->points - 2 * sp->specs->pts, 0, 0, 0);
  132:                         Write(W_CAPTURED, sp, -1, 0, 0, 0);
  133:                 }
  134:         }
  135: }
  136: 
  137: static int
  138: str_end(const char *str)
  139: {
  140:         const char *p;
  141: 
  142:         for (p = str; *p; p++)
  143:                 ;
  144:         return p == str ? 0 : p[-1];
  145: }
  146: 
  147: void
  148: closeon(struct ship *from, struct ship *to, char *command, int ta, int ma, int af)
  149: {
  150:         int high;
  151:         char temp[10];
  152: 
  153:         temp[0] = command[0] = '\0';
  154:         high = -30000;
  155:         try(from, to, command, temp, ma, ta, af, ma, from->file->dir, &high, 0);
  156: }
  157: 
  158: static int
  159: score(struct ship *ship, struct ship *to, char *movement, int onlytemp)
  160: {
  161:         char drift;
  162:         int row, col, dir, total, ran;
  163:         struct File *fp = ship->file;
  164: 
  165:         if ((dir = fp->dir) == 0)
  166:                 return 0;
  167:         row = fp->row;
  168:         col = fp->col;
  169:         drift = fp->drift;
  170:         move_ship(ship, movement, &fp->dir, &fp->row, &fp->col, &drift);
  171:         if (!*movement)
  172:                 strcpy(movement, "d");
  173: 
  174:         ran = range(ship, to);
  175:         total = -50 * ran;
  176:         if (ran < 4 && gunsbear(ship, to))
  177:                 total += 60;
  178:         if ((ran = portside(ship, to, 1) - fp->dir) == 4 || ran == -4)
  179:                 total = -30000;
  180: 
  181:         if (!onlytemp) {
  182:                 fp->row = row;
  183:                 fp->col = col;
  184:                 fp->dir = dir;
  185:         }
  186:         return total;
  187: }
  188: 
  189: static void
  190: move_ship(struct ship *ship, const char *p, unsigned char *dir, short *row, short *col, char *drift)
  191: {
  192:         int dist;
  193:         char moved = 0;
  194: 
  195:         for (; *p; p++) {
  196:                 switch (*p) {
  197:                 case 'r':
  198:                         if (++*dir == 9)
  199:                                 *dir = 1;
  200:                         break;
  201:                 case 'l':
  202:                         if (--*dir == 0)
  203:                                 *dir = 8;
  204:                         break;
  205:                 case '1': case '2': case '3': case '4':
  206:                 case '5': case '6': case '7':
  207:                         moved++;
  208:                         if (*dir % 2 == 0)
  209:                                 dist = dtab[*p - '0'];
  210:                         else
  211:                                 dist = *p - '0';
  212:                         *row -= dr[*dir] * dist;
  213:                         *col -= dc[*dir] * dist;
  214:                         break;
  215:                 }
  216:         }
  217:         if (!moved) {
  218:                 if (windspeed != 0 && ++*drift > 2) {
  219:                         if ((ship->specs->class >= 3 && !snagged(ship))
  220:                             || (turn & 1) == 0) {
  221:                                 *row -= dr[winddir];
  222:                                 *col -= dc[winddir];
  223:                         }
  224:                 }
  225:         } else
  226:                 *drift = 0;
  227: }
  228: 
  229: static void
  230: try(struct ship *f, struct ship *t, char *command, char *temp, int ma, int ta, int af, int vma, int dir, int *high, int rakeme)
  231: {
  232:         int new, n;
  233:         char st[4];
  234: #define rakeyou (gunsbear(f, t) && !gunsbear(t, f))
  235: 
  236:         if ((n = str_end(temp)) < '1' || n > '9')
  237:                 for (n = 1; vma - n >= 0; n++) {
  238:                         sprintf(st, "%d", n);
  239:                         strcat(temp, st);
  240:                         new = score(f, t, temp, rakeme);
  241:                         if (new > *high && (!rakeme || rakeyou)) {
  242:                                 *high = new;
  243:                                 strcpy(command, temp);
  244:                         }
  245:                         try(f, t, command, temp, ma-n, ta, af, vma-n,
  246:                                 dir, high, rakeme);
  247:                         rmend(temp);
  248:                 }
  249:         if ((ma > 0 && ta > 0 && (n = str_end(temp)) != 'l' && n != 'r') || !strlen(temp)) {
  250:                 strcat(temp, "r");
  251:                 new = score(f, t, temp, rakeme);
  252:                 if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))) {
  253:                         *high = new;
  254:                         strcpy(command, temp);
  255:                 }
  256:                 try(f, t, command, temp, ma-1, ta-1, af, min(ma-1, maxmove(f, (dir == 8 ? 1 : dir+1), 0)), (dir == 8 ? 1 : dir+1), high, rakeme);
  257:                 rmend(temp);
  258:         }
  259:         if ((ma > 0 && ta > 0 && (n = str_end(temp)) != 'l' && n != 'r') || !strlen(temp)){
  260:                 strcat(temp, "l");
  261:                 new = score(f, t, temp, rakeme);
  262:                 if (new > *high && (!rakeme || (gunsbear(f, t) && !gunsbear(t, f)))){
  263:                         *high = new;
  264:                         strcpy(command, temp);
  265:                 }
  266:                 try(f, t, command, temp, ma-1, ta-1, af, (min(ma-1,maxmove(f, (dir-1 ? dir-1 : 8), 0))), (dir-1 ? dir -1 : 8), high, rakeme);
  267:                 rmend(temp);
  268:         }
  269: }
  270: 
  271: static void
  272: rmend(char *str)
  273: {
  274:         char *p;
  275: 
  276:         for (p = str; *p; p++)
  277:                 ;
  278:         if (p != str)
  279:                 *--p = 0;
  280: }
Syntax (Markdown)