BSD 4_3_Net_2 release
[unix-history] / usr / src / games / mille / comp.c
index 2d8bbf8..64929fe 100644 (file)
@@ -1,18 +1,59 @@
+/*
+ * Copyright (c) 1982 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)comp.c     5.4 (Berkeley) 6/1/90";
+#endif /* not lint */
+
 # include      "mille.h"
 
 # include      "mille.h"
 
-# define       V_VALUABLE      40
+/*
+ * @(#)comp.c  1.1 (Berkeley) 4/1/82
+ */
 
 
-calcmove() {
+# define       V_VALUABLE      40
 
 
-       reg CARD        card;
-       reg int         *value;
-       reg PLAY        *pp, *op;
-       reg bool        foundend, cango, canstop, foundlow;
-       reg unsgn int   i, count200, badcount, nummin, nummax, diff;
-       reg int         curmin, curmax;
-       reg CARD        safe, oppos;
-       int             valbuf[HAND_SZ], count[NUM_CARDS];
-       bool            playit[HAND_SZ];
+calcmove()
+{
+       register CARD           card;
+       register int            *value;
+       register PLAY           *pp, *op;
+       register bool           foundend, cango, canstop, foundlow;
+       register unsgn int      i, count200, badcount, nummin, nummax, diff;
+       register int            curmin, curmax;
+       register CARD           safe, oppos;
+       int                     valbuf[HAND_SZ], count[NUM_CARDS];
+       bool                    playit[HAND_SZ];
 
        wmove(Score, ERR_Y, ERR_X);     /* get rid of error messages    */
        wclrtoeol(Score);
 
        wmove(Score, ERR_Y, ERR_X);     /* get rid of error messages    */
        wclrtoeol(Score);
@@ -52,8 +93,8 @@ norm:
                        break;
                  case C_GAS_SAFE:      case C_DRIVE_SAFE:
                  case C_SPARE_SAFE:    case C_RIGHT_WAY:
                        break;
                  case C_GAS_SAFE:      case C_DRIVE_SAFE:
                  case C_SPARE_SAFE:    case C_RIGHT_WAY:
-                       if (pp->battle == opposite(card)
-                          || (pp->speed == C_LIMIT && card == C_RIGHT_WAY)) {
+                       if (pp->battle == opposite(card) ||
+                           (pp->speed == C_LIMIT && card == C_RIGHT_WAY)) {
                                Movetype = M_PLAY;
                                Card_no = i;
                                return;
                                Movetype = M_PLAY;
                                Card_no = i;
                                return;
@@ -68,30 +109,43 @@ norm:
                Movetype = M_DRAW;
                return;
        }
                Movetype = M_DRAW;
                return;
        }
+#ifdef DEBUG
        if (Debug)
        if (Debug)
-               fprintf(outf, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n", cango, canstop, safe);
+               fprintf(outf, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n",
+                       cango, canstop, safe);
+#endif
        if (foundend)
                foundend = !check_ext(TRUE);
        for (i = 0; safe && i < HAND_SZ; i++) {
                if (issafety(pp->hand[i])) {
                        if (onecard(op) || (foundend && cango && !canstop)) {
        if (foundend)
                foundend = !check_ext(TRUE);
        for (i = 0; safe && i < HAND_SZ; i++) {
                if (issafety(pp->hand[i])) {
                        if (onecard(op) || (foundend && cango && !canstop)) {
+#ifdef DEBUG
                                if (Debug)
                                if (Debug)
-                                       fprintf(outf, "CALCMOVE: onecard(op) = %d, foundend = %d\n", onecard(op), foundend);
+                                       fprintf(outf,
+                                               "CALCMOVE: onecard(op) = %d, foundend = %d\n",
+                                               onecard(op), foundend);
+#endif
 playsafe:
                                Movetype = M_PLAY;
                                Card_no = i;
                                return;
                        }
                        oppos = opposite(pp->hand[i]);
 playsafe:
                                Movetype = M_PLAY;
                                Card_no = i;
                                return;
                        }
                        oppos = opposite(pp->hand[i]);
-                       if (Numseen[oppos] == Numcards[oppos])
+                       if (Numseen[oppos] == Numcards[oppos] &&
+                           !(pp->hand[i] == C_RIGHT_WAY &&
+                             Numseen[C_LIMIT] != Numcards[C_LIMIT]))
                                goto playsafe;
                        else if (!cango
                            && (op->can_go || !pp->can_go || Topcard < Deck)) {
                                card = (Topcard - Deck) - roll(1, 10);
                                if ((!pp->mileage) != (!op->mileage))
                                        card -= 7;
                                goto playsafe;
                        else if (!cango
                            && (op->can_go || !pp->can_go || Topcard < Deck)) {
                                card = (Topcard - Deck) - roll(1, 10);
                                if ((!pp->mileage) != (!op->mileage))
                                        card -= 7;
+#ifdef DEBUG
                                if (Debug)
                                if (Debug)
-                                       fprintf(outf, "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n", card, DECK_SZ / 4);
+                                       fprintf(outf,
+                                               "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n",
+                                               card, DECK_SZ / 4);
+#endif
                                if (card < DECK_SZ / 4)
                                        goto playsafe;
                        }
                                if (card < DECK_SZ / 4)
                                        goto playsafe;
                        }
@@ -116,8 +170,11 @@ redoit:
        for (i = 0; i < HAND_SZ; i++) {
                card = pp->hand[i];
                if (issafety(card) || playit[i] == (cango != 0)) {
        for (i = 0; i < HAND_SZ; i++) {
                card = pp->hand[i];
                if (issafety(card) || playit[i] == (cango != 0)) {
+#ifdef DEBUG
                        if (Debug)
                        if (Debug)
-                               fprintf(outf, "CALCMOVE: switch(\"%s\")\n", C_name[card]);
+                               fprintf(outf, "CALCMOVE: switch(\"%s\")\n",
+                                       C_name[card]);
+#endif
                        switch (card) {
                          case C_25:    case C_50:
                                diff = End - pp->mileage;
                        switch (card) {
                          case C_25:    case C_50:
                                diff = End - pp->mileage;
@@ -166,8 +223,10 @@ miles:
                                break;
                          case C_END_LIMIT:
                                if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
                                break;
                          case C_END_LIMIT:
                                if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
-                                       *value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 1);
-                               else if (pp->speed == C_LIMIT && End - pp->mileage <= 50)
+                                       *value = (pp->safety[S_RIGHT_WAY] ==
+                                                 S_PLAYED ? -1 : 1);
+                               else if (pp->speed == C_LIMIT &&
+                                        End - pp->mileage <= 50)
                                        *value = 1;
                                else if (pp->speed == C_LIMIT
                                    || Numseen[C_LIMIT] != Numcards[C_LIMIT]) {
                                        *value = 1;
                                else if (pp->speed == C_LIMIT
                                    || Numseen[C_LIMIT] != Numcards[C_LIMIT]) {
@@ -184,16 +243,20 @@ miles:
                                safe = safety(card) - S_CONV;
                                oppos = opposite(card);
                                if (pp->safety[safe] != S_UNKNOWN)
                                safe = safety(card) - S_CONV;
                                oppos = opposite(card);
                                if (pp->safety[safe] != S_UNKNOWN)
-                                       *value = (pp->safety[safe] == S_PLAYED ? -1 : 1);
+                                       *value = (pp->safety[safe] ==
+                                                 S_PLAYED ? -1 : 1);
                                else if (pp->battle != oppos
                                else if (pp->battle != oppos
-                                   && (Numseen[oppos] == Numcards[oppos] || Numseen[oppos] + count[card] > Numcards[oppos])) {
+                                   && (Numseen[oppos] == Numcards[oppos] ||
+                                       Numseen[oppos] + count[card] >
+                                       Numcards[oppos])) {
                                        *value = 0;
                                        --count[card];
                                }
                                else {
 repair:
                                        *value = Numcards[oppos] * 6;
                                        *value = 0;
                                        --count[card];
                                }
                                else {
 repair:
                                        *value = Numcards[oppos] * 6;
-                                       *value += (Numseen[card] - Numseen[oppos]);
+                                       *value += Numseen[card] -
+                                                 Numseen[oppos];
                                        if (!cango)
                                            *value /= (count[card]*count[card]);
                                        count[card]--;
                                        if (!cango)
                                            *value /= (count[card]*count[card]);
                                        count[card]--;
@@ -201,7 +264,8 @@ repair:
                                break;
                          case C_GO:
                                if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
                                break;
                          case C_GO:
                                if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
-                                       *value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 2);
+                                       *value = (pp->safety[S_RIGHT_WAY] ==
+                                                 S_PLAYED ? -1 : 2);
                                else if (pp->can_go
                                 && Numgos + count[C_GO] == Numneed[C_GO]) {
                                        *value = 0;
                                else if (pp->can_go
                                 && Numgos + count[C_GO] == Numneed[C_GO]) {
                                        *value = 0;
@@ -222,7 +286,8 @@ repair:
                                if (canstop || (cango && !op->can_go))
                                        *value = 1;
                                else {
                                if (canstop || (cango && !op->can_go))
                                        *value = 1;
                                else {
-                                       *value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 2 : 3);
+                                       *value = (pp->safety[S_RIGHT_WAY] !=
+                                                 S_UNKNOWN ? 2 : 3);
                                        safe = S_RIGHT_WAY;
                                        oppos = C_END_LIMIT;
                                        goto normbad;
                                        safe = S_RIGHT_WAY;
                                        oppos = C_END_LIMIT;
                                        goto normbad;
@@ -236,36 +301,44 @@ normbad:
                                if (op->safety[safe] == S_PLAYED)
                                        *value = -1;
                                else {
                                if (op->safety[safe] == S_PLAYED)
                                        *value = -1;
                                else {
-                                   *value *= (Numneed[oppos] + Numseen[oppos] + 2);
-                                   if (!pp->mileage || foundend || onecard(op))
-                                       *value += 5;
-                                   if (op->mileage == 0 || onecard(op))
-                                       *value += 5;
-                                   if (op->speed == C_LIMIT)
-                                       *value -= 3;
-                                   if (cango && pp->safety[safe] != S_UNKNOWN)
-                                       *value += 3;
-                                   if (!cango)
-                                       *value /= ++badcount;
+                                       *value *= Numneed[oppos] +
+                                                 Numseen[oppos] + 2;
+                                       if (!pp->mileage || foundend ||
+                                           onecard(op))
+                                               *value += 5;
+                                       if (op->mileage == 0 || onecard(op))
+                                               *value += 5;
+                                       if (op->speed == C_LIMIT)
+                                               *value -= 3;
+                                       if (cango &&
+                                           pp->safety[safe] != S_UNKNOWN)
+                                               *value += 3;
+                                       if (!cango)
+                                               *value /= ++badcount;
                                }
                                break;
                          case C_STOP:
                                if (op->safety[S_RIGHT_WAY] == S_PLAYED)
                                        *value = -1;
                                else {
                                }
                                break;
                          case C_STOP:
                                if (op->safety[S_RIGHT_WAY] == S_PLAYED)
                                        *value = -1;
                                else {
-                                   *value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 3 : 4);
-                                   *value *= (Numcards[C_STOP] + Numseen[C_GO]);
-                                   if (!pp->mileage || foundend || onecard(op))
-                                       *value += 5;
-                                   if (!cango)
-                                       *value /= ++badcount;
-                                   if (op->mileage == 0)
-                                       *value += 5;
-                                   if ((card == C_LIMIT
-                                     && op->speed == C_LIMIT) || (!op->can_go))
-                                       *value -= 5;
-                                   if (cango && pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
-                                       *value += 5;
+                                       *value = (pp->safety[S_RIGHT_WAY] !=
+                                                 S_UNKNOWN ? 3 : 4);
+                                       *value *= Numcards[C_STOP] +
+                                                 Numseen[C_GO];
+                                       if (!pp->mileage || foundend ||
+                                           onecard(op))
+                                               *value += 5;
+                                       if (!cango)
+                                               *value /= ++badcount;
+                                       if (op->mileage == 0)
+                                               *value += 5;
+                                       if ((card == C_LIMIT &&
+                                            op->speed == C_LIMIT) ||
+                                           !op->can_go)
+                                               *value -= 5;
+                                       if (cango && pp->safety[S_RIGHT_WAY] !=
+                                                    S_UNKNOWN)
+                                               *value += 5;
                                }
                                break;
                          case C_GAS_SAFE:      case C_DRIVE_SAFE:
                                }
                                break;
                          case C_GAS_SAFE:      case C_DRIVE_SAFE:
@@ -274,6 +347,7 @@ normbad:
                                break;
                          case C_INIT:
                                *value = 0;
                                break;
                          case C_INIT:
                                *value = 0;
+                               break;
                        }
                }
                else
                        }
                }
                else
@@ -288,26 +362,42 @@ normbad:
                                curmin = *value;
                        }
                }
                                curmin = *value;
                        }
                }
+#ifdef DEBUG
                if (Debug)
                if (Debug)
-                       mvprintw(i+6,2,"%3d %-14s",*value,C_name[pp->hand[i]]);
+                       mvprintw(i + 6, 2, "%3d %-14s", *value,
+                                C_name[pp->hand[i]]);
+#endif
                value++;
        }
        if (!pp->can_go && !isrepair(pp->battle))
                Numneed[opposite(pp->battle)]++;
        if (cango) {
                value++;
        }
        if (!pp->can_go && !isrepair(pp->battle))
                Numneed[opposite(pp->battle)]++;
        if (cango) {
+play_it:
                mvaddstr(MOVE_Y + 1, MOVE_X, "PLAY\n");
                mvaddstr(MOVE_Y + 1, MOVE_X, "PLAY\n");
+#ifdef DEBUG
                if (Debug)
                        getmove();
                if (!Debug || Movetype == M_DRAW) {
                if (Debug)
                        getmove();
                if (!Debug || Movetype == M_DRAW) {
+#else
+               if (Movetype == M_DRAW) {
+#endif
                        Movetype = M_PLAY;
                        Card_no = nummax;
                }
        }
        else {
                        Movetype = M_PLAY;
                        Card_no = nummax;
                }
        }
        else {
+               if (issafety(pp->hand[nummin])) { /* NEVER discard a safety */
+                       nummax = nummin;
+                       goto play_it;
+               }
                mvaddstr(MOVE_Y + 1, MOVE_X, "DISCARD\n");
                mvaddstr(MOVE_Y + 1, MOVE_X, "DISCARD\n");
+#ifdef DEBUG
                if (Debug)
                        getmove();
                if (!Debug || Movetype == M_DRAW) {
                if (Debug)
                        getmove();
                if (!Debug || Movetype == M_DRAW) {
+#else
+               if (Movetype == M_DRAW) {
+#endif
                        Movetype = M_DISCARD;
                        Card_no = nummin;
                }
                        Movetype = M_DISCARD;
                        Card_no = nummin;
                }
@@ -316,21 +406,22 @@ normbad:
 }
 
 onecard(pp)
 }
 
 onecard(pp)
-reg PLAY       *pp; {
-
-       reg CARD        bat, spd, card;
+register PLAY  *pp;
+{
+       register CARD   bat, spd, card;
 
        bat = pp->battle;
        spd = pp->speed;
        card = -1;
 
        bat = pp->battle;
        spd = pp->speed;
        card = -1;
-       if (pp->can_go || ((isrepair(bat) || bat == C_STOP
-           || spd == C_LIMIT) && Numseen[S_RIGHT_WAY] != 0)
-           || Numseen[safety(bat)] != 0)
+       if (pp->can_go || ((isrepair(bat) || bat == C_STOP || spd == C_LIMIT) &&
+                          Numseen[S_RIGHT_WAY] != 0) ||
+           Numseen[safety(bat)] != 0)
                switch (End - pp->mileage) {
                  case 200:
                        if (pp->nummiles[C_200] == 2)
                                return FALSE;
                        card = C_200;
                switch (End - pp->mileage) {
                  case 200:
                        if (pp->nummiles[C_200] == 2)
                                return FALSE;
                        card = C_200;
+                       /* FALLTHROUGH */
                  case 100:
                  case 75:
                        if (card == -1)
                  case 100:
                  case 75:
                        if (card == -1)
@@ -347,19 +438,22 @@ reg PLAY  *pp; {
 }
 
 canplay(pp, op, card)
 }
 
 canplay(pp, op, card)
-reg PLAY       *pp, *op;
-reg CARD       card; {
-
+register PLAY  *pp, *op;
+register CARD  card;
+{
        switch (card) {
          case C_200:
                if (pp->nummiles[C_200] == 2)
                        break;
        switch (card) {
          case C_200:
                if (pp->nummiles[C_200] == 2)
                        break;
+               /* FALLTHROUGH */
          case C_75:    case C_100:
                if (pp->speed == C_LIMIT)
                        break;
          case C_75:    case C_100:
                if (pp->speed == C_LIMIT)
                        break;
+               /* FALLTHROUGH */
          case C_50:
                if (pp->mileage + Value[card] > End)
                        break;
          case C_50:
                if (pp->mileage + Value[card] > End)
                        break;
+               /* FALLTHROUGH */
          case C_25:
                if (pp->can_go)
                        return TRUE;
          case C_25:
                if (pp->can_go)
                        return TRUE;
@@ -370,8 +464,9 @@ reg CARD    card; {
                        return TRUE;
                break;
          case C_LIMIT:
                        return TRUE;
                break;
          case C_LIMIT:
-               if (op->speed != C_LIMIT && op->safety[S_RIGHT_WAY] != S_PLAYED
-                   && op->mileage + 50 < End)
+               if (op->speed != C_LIMIT &&
+                   op->safety[S_RIGHT_WAY] != S_PLAYED &&
+                   op->mileage + 50 < End)
                        return TRUE;
                break;
          case C_GAS:   case C_SPARE:   case C_REPAIRS:
                        return TRUE;
                break;
          case C_GAS:   case C_SPARE:   case C_REPAIRS:
@@ -379,8 +474,8 @@ reg CARD    card; {
                        return TRUE;
                break;
          case C_GO:
                        return TRUE;
                break;
          case C_GO:
-               if (!pp->can_go
-                   && (isrepair(pp->battle) || pp->battle == C_STOP))
+               if (!pp->can_go &&
+                   (isrepair(pp->battle) || pp->battle == C_STOP))
                        return TRUE;
                break;
          case C_END_LIMIT:
                        return TRUE;
                break;
          case C_END_LIMIT: