home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume1 / pcurses / part11 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  46.4 KB

  1. Subject:  Terminfo/Curses Part 11 of 11
  2.  
  3. : Run this shell script with "sh" not "csh"
  4. PATH=:/bin:/usr/bin:/usr/ucb
  5. export PATH
  6. echo 'Making directory "=test"'
  7. mkdir =test
  8. echo 'Making directory "=test/=mille"'
  9. mkdir =test/=mille
  10. echo 'x - =test/=mille/Makefile'
  11. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/Makefile
  12. HEADERS=mille.h
  13. CFILES=    comp.c end.c extern.c init.c mille.c misc.c move.c print.c \
  14.     roll.c save.c types.c varpush.c
  15. OBJS=    comp.o end.o extern.o init.o mille.o misc.o move.o print.o \
  16.     roll.o save.o types.o varpush.o
  17. POBJS=    comp.po end.po extern.po init.po mille.po misc.po move.po \
  18.     roll.po print.po save.po types.po varpush.po
  19. LIBS=    ../../=src/libpcurses.a
  20. CFLAGS=    -O -DSTANDOUT -I../../=src
  21. X.SUFFIXES: .po .i
  22.  
  23. X.c.po:
  24.     rm -f x.c ; ln $*.c x.c
  25.     ${CC} ${CFLAGS} -pg -c x.c
  26.     mv x.o $*.po
  27.  
  28. X.c.i:
  29.     ${CC} ${CFLAGS} -P $*.c
  30.  
  31. mille: ${OBJS} 
  32.     ${CC} ${CFLAGS} -n -o mille ${OBJS} ${LIBS}
  33.  
  34. install: mille
  35.     cp mille /usr/games
  36.  
  37. pmb: ${POBJS}
  38.     ${CC} ${CFLAGS} -n -pg -o pmb ${POBJS} $(LIBS)
  39.  
  40. mille.po: mille.c
  41.     rm -f x.c ; ln mille.c x.c
  42.     ${CC} ${CFLAGS} -DPROF -p -c x.c
  43.     mv x.o mille.po
  44.  
  45. table: table.o extern.o
  46.     ${CC} ${CFLAGS} -i -o table table.o extern.o
  47.  
  48. readdump: readdump.o extern.o varpush.o
  49.     ${CC} ${CFLAGS} -i -o readdump readdump.o extern.o varpush.o
  50.  
  51. ctags:
  52.     ctags ${HEADERS} ${CFILES}
  53.     ed - tags < :ctfix
  54.     sort tags -o tags
  55.  
  56. lint:
  57.     lint -hxb ${CFILES} > lint.out
  58.  
  59. mille.ar:
  60.     ar ruv mille.ar Makefile tags ${HEADERS} ${CFILES}
  61.  
  62. tar:
  63.     tar crvf mille.tar Makefile tags :ctfix ${HEADERS} ${CFILES}
  64.  
  65. lpr:
  66.     pr Makefile ${HEADERS} ${CFILES} tags | lpr ; lpq
  67. //go.sysin dd *
  68. echo 'x - =test/=mille/comp.c'
  69. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/comp.c
  70. # include    "mille.h"
  71.  
  72. # define    V_VALUABLE    40
  73.  
  74. calcmove() {
  75.  
  76.     reg CARD    card;
  77.     reg int        *value;
  78.     reg PLAY    *pp, *op;
  79.     reg bool    foundend, cango, canstop, foundlow;
  80.     reg unsgn int    i, count200, badcount, nummin, nummax, diff;
  81.     reg int        curmin, curmax;
  82.     reg CARD    safe, oppos;
  83.     int        valbuf[HAND_SZ], count[NUM_CARDS];
  84.     bool        playit[HAND_SZ];
  85.  
  86.     wmove(Score, ERR_Y, ERR_X);    /* get rid of error messages    */
  87.     wclrtoeol(Score);
  88.     pp = &Player[COMP];
  89.     op = &Player[PLAYER];
  90.     safe = 0;
  91.     cango = 0;
  92.     canstop = FALSE;
  93.     foundend = FALSE;
  94.     for (i = 0; i < NUM_CARDS; i++)
  95.         count[i] = 0;
  96.     for (i = 0; i < HAND_SZ; i++) {
  97.         card = pp->hand[i];
  98.         switch (card) {
  99.           case C_STOP:    case C_CRASH:
  100.           case C_FLAT:    case C_EMPTY:
  101.             if (playit[i] = canplay(pp, op, card))
  102.                 canstop = TRUE;
  103.             goto norm;
  104.           case C_LIMIT:
  105.             if ((playit[i] = canplay(pp, op, card))
  106.                 && Numseen[C_25] == Numcards[C_25]
  107.                 && Numseen[C_50] == Numcards[C_50])
  108.                 canstop = TRUE;
  109.             goto norm;
  110.           case C_25:    case C_50:    case C_75:
  111.           case C_100:    case C_200:
  112.             if ((playit[i] = canplay(pp, op, card))
  113.                 && pp->mileage + Value[card] == End)
  114.                 foundend = TRUE;
  115.             goto norm;
  116.           default:
  117.             playit[i] = canplay(pp, op, card);
  118. norm:
  119.             if (playit[i])
  120.                 ++cango;
  121.             break;
  122.           case C_GAS_SAFE:    case C_DRIVE_SAFE:
  123.           case C_SPARE_SAFE:    case C_RIGHT_WAY:
  124.             if (pp->battle == opposite(card)
  125.                || (pp->speed == C_LIMIT && card == C_RIGHT_WAY)) {
  126.                 Movetype = M_PLAY;
  127.                 Card_no = i;
  128.                 return;
  129.             }
  130.             ++safe;
  131.             playit[i] = TRUE;
  132.             break;
  133.         }
  134.         ++count[card];
  135.     }
  136.     if (pp->hand[0] == C_INIT && Topcard > Deck) {
  137.         Movetype = M_DRAW;
  138.         return;
  139.     }
  140.     if (Debug)
  141.         fprintf(outf, "CALCMOVE: cango = %d, canstop = %d, safe = %d\n", cango, canstop, safe);
  142.     if (foundend)
  143.         foundend = !check_ext(TRUE);
  144.     for (i = 0; safe && i < HAND_SZ; i++) {
  145.         if (issafety(pp->hand[i])) {
  146.             if (onecard(op) || (foundend && cango && !canstop)) {
  147.                 if (Debug)
  148.                     fprintf(outf, "CALCMOVE: onecard(op) = %d, foundend = %d\n", onecard(op), foundend);
  149. playsafe:
  150.                 Movetype = M_PLAY;
  151.                 Card_no = i;
  152.                 return;
  153.             }
  154.             oppos = opposite(pp->hand[i]);
  155.             if (Numseen[oppos] == Numcards[oppos])
  156.                 goto playsafe;
  157.             else if (!cango
  158.                 && (op->can_go || !pp->can_go || Topcard < Deck)) {
  159.                 card = (Topcard - Deck) - roll(1, 10);
  160.                 if ((!pp->mileage) != (!op->mileage))
  161.                     card -= 7;
  162.                 if (Debug)
  163.                     fprintf(outf, "CALCMOVE: card = %d, DECK_SZ / 4 = %d\n", card, DECK_SZ / 4);
  164.                 if (card < DECK_SZ / 4)
  165.                     goto playsafe;
  166.             }
  167.             safe--;
  168.             playit[i] = cango;
  169.         }
  170.     }
  171.     if (!pp->can_go && !isrepair(pp->battle))
  172.         Numneed[opposite(pp->battle)]++;
  173. redoit:
  174.     foundlow = (cango || count[C_END_LIMIT] != 0
  175.               || Numseen[C_LIMIT] == Numcards[C_LIMIT]
  176.               || pp->safety[S_RIGHT_WAY] != S_UNKNOWN);
  177.     foundend = FALSE;
  178.     count200 = pp->nummiles[C_200];
  179.     badcount = 0;
  180.     curmax = -1;
  181.     curmin = 101;
  182.     nummin = -1;
  183.     nummax = -1;
  184.     value = valbuf;
  185.     for (i = 0; i < HAND_SZ; i++) {
  186.         card = pp->hand[i];
  187.         if (issafety(card) || playit[i] == (cango != 0)) {
  188.             if (Debug)
  189.                 fprintf(outf, "CALCMOVE: switch(\"%s\")\n", C_name[card]);
  190.             switch (card) {
  191.               case C_25:    case C_50:
  192.                 diff = End - pp->mileage;
  193.                 /* avoid getting too close */
  194.                 if (Topcard > Deck && cango && diff <= 100
  195.                     && diff / Value[card] > count[card]
  196.                     && (card == C_25 || diff % 50 == 0)) {
  197.                     if (card == C_50 && diff - 50 == 25
  198.                         && count[C_25] > 0)
  199.                         goto okay;
  200.                     *value = 0;
  201.                     if (--cango <= 0)
  202.                         goto redoit;
  203.                     break;
  204.                 }
  205. okay:
  206.                 *value = (Value[card] >> 3);
  207.                 if (pp->speed == C_LIMIT)
  208.                     ++*value;
  209.                 else
  210.                     --*value;
  211.                 if (!foundlow
  212.                    && (card == C_50 || count[C_50] == 0)) {
  213.                     *value = (pp->mileage ? 10 : 20);
  214.                     foundlow = TRUE;
  215.                 }
  216.                 goto miles;
  217.               case C_200:
  218.                 if (++count200 > 2) {
  219.                     *value = 0;
  220.                     break;
  221.                 }
  222.               case C_75:    case C_100:
  223.                 *value = (Value[card] >> 3);
  224.                 if (pp->speed == C_LIMIT)
  225.                     --*value;
  226.                 else
  227.                     ++*value;
  228. miles:
  229.                 if (pp->mileage + Value[card] > End)
  230.                     *value = (End == 700 ? card : 0);
  231.                 else if (pp->mileage + Value[card] == End) {
  232.                     *value = (foundend ? card : V_VALUABLE);
  233.                     foundend = TRUE;
  234.                 }
  235.                 break;
  236.               case C_END_LIMIT:
  237.                 if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
  238.                     *value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 1);
  239.                 else if (pp->speed == C_LIMIT && End - pp->mileage <= 50)
  240.                     *value = 1;
  241.                 else if (pp->speed == C_LIMIT
  242.                     || Numseen[C_LIMIT] != Numcards[C_LIMIT]) {
  243.                     safe = S_RIGHT_WAY;
  244.                     oppos = C_LIMIT;
  245.                     goto repair;
  246.                 }
  247.                 else {
  248.                     *value = 0;
  249.                     --count[C_END_LIMIT];
  250.                 }
  251.                 break;
  252.               case C_REPAIRS:    case C_SPARE:    case C_GAS:
  253.                 safe = safety(card) - S_CONV;
  254.                 oppos = opposite(card);
  255.                 if (pp->safety[safe] != S_UNKNOWN)
  256.                     *value = (pp->safety[safe] == S_PLAYED ? -1 : 1);
  257.                 else if (pp->battle != oppos
  258.                     && (Numseen[oppos] == Numcards[oppos] || Numseen[oppos] + count[card] > Numcards[oppos])) {
  259.                     *value = 0;
  260.                     --count[card];
  261.                 }
  262.                 else {
  263. repair:
  264.                     *value = Numcards[oppos] * 6;
  265.                     *value += (Numseen[card] - Numseen[oppos]);
  266.                     if (!cango)
  267.                         *value /= (count[card]*count[card]);
  268.                     count[card]--;
  269.                 }
  270.                 break;
  271.               case C_GO:
  272.                 if (pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
  273.                     *value = (pp->safety[S_RIGHT_WAY] == S_PLAYED ? -1 : 2);
  274.                 else if (pp->can_go
  275.                  && Numgos + count[C_GO] == Numneed[C_GO]) {
  276.                     *value = 0;
  277.                     --count[C_GO];
  278.                 }
  279.                 else {
  280.                     *value = Numneed[C_GO] * 3;
  281.                     *value += (Numseen[C_GO] - Numgos);
  282.                     *value /= (count[C_GO] * count[C_GO]);
  283.                     count[C_GO]--;
  284.                 }
  285.                 break;
  286.               case C_LIMIT:
  287.                 if (op->mileage + 50 >= End) {
  288.                     *value = (End == 700 && !cango);
  289.                     break;
  290.                 }
  291.                 if (canstop || (cango && !op->can_go))
  292.                     *value = 1;
  293.                 else {
  294.                     *value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 2 : 3);
  295.                     safe = S_RIGHT_WAY;
  296.                     oppos = C_END_LIMIT;
  297.                     goto normbad;
  298.                 }
  299.                 break;
  300.               case C_CRASH:    case C_EMPTY:    case C_FLAT:
  301.                 safe = safety(card) - S_CONV;
  302.                 oppos = opposite(card);
  303.                 *value = (pp->safety[safe]!=S_UNKNOWN ? 3 : 4);
  304. normbad:
  305.                 if (op->safety[safe] == S_PLAYED)
  306.                     *value = -1;
  307.                 else {
  308.                     *value *= (Numneed[oppos] + Numseen[oppos] + 2);
  309.                     if (!pp->mileage || foundend || onecard(op))
  310.                     *value += 5;
  311.                     if (op->mileage == 0 || onecard(op))
  312.                     *value += 5;
  313.                     if (op->speed == C_LIMIT)
  314.                     *value -= 3;
  315.                     if (cango && pp->safety[safe] != S_UNKNOWN)
  316.                     *value += 3;
  317.                     if (!cango)
  318.                     *value /= ++badcount;
  319.                 }
  320.                 break;
  321.               case C_STOP:
  322.                 if (op->safety[S_RIGHT_WAY] == S_PLAYED)
  323.                     *value = -1;
  324.                 else {
  325.                     *value = (pp->safety[S_RIGHT_WAY] != S_UNKNOWN ? 3 : 4);
  326.                     *value *= (Numcards[C_STOP] + Numseen[C_GO]);
  327.                     if (!pp->mileage || foundend || onecard(op))
  328.                     *value += 5;
  329.                     if (!cango)
  330.                     *value /= ++badcount;
  331.                     if (op->mileage == 0)
  332.                     *value += 5;
  333.                     if ((card == C_LIMIT
  334.                       && op->speed == C_LIMIT) || (!op->can_go))
  335.                     *value -= 5;
  336.                     if (cango && pp->safety[S_RIGHT_WAY] != S_UNKNOWN)
  337.                     *value += 5;
  338.                 }
  339.                 break;
  340.               case C_GAS_SAFE:    case C_DRIVE_SAFE:
  341.               case C_SPARE_SAFE:    case C_RIGHT_WAY:
  342.                 *value = cango ? 0 : 101;
  343.                 break;
  344.               case C_INIT:
  345.                 *value = 0;
  346.             }
  347.         }
  348.         else
  349.             *value = cango ? 0 : 101;
  350.         if (card != C_INIT) {
  351.             if (*value >= curmax) {
  352.                 nummax = i;
  353.                 curmax = *value;
  354.             }
  355.             if (*value <= curmin) {
  356.                 nummin = i;
  357.                 curmin = *value;
  358.             }
  359.         }
  360.         if (Debug)
  361.             mvprintw(i+6,2,"%3d %-14s",*value,C_name[pp->hand[i]]);
  362.         value++;
  363.     }
  364.     if (!pp->can_go && !isrepair(pp->battle))
  365.         Numneed[opposite(pp->battle)]++;
  366.     if (cango) {
  367.         mvaddstr(MOVE_Y + 1, MOVE_X, "PLAY\n");
  368.         if (Debug)
  369.             getmove();
  370.         if (!Debug || Movetype == M_DRAW) {
  371.             Movetype = M_PLAY;
  372.             Card_no = nummax;
  373.         }
  374.     }
  375.     else {
  376.         mvaddstr(MOVE_Y + 1, MOVE_X, "DISCARD\n");
  377.         if (Debug)
  378.             getmove();
  379.         if (!Debug || Movetype == M_DRAW) {
  380.             Movetype = M_DISCARD;
  381.             Card_no = nummin;
  382.         }
  383.     }
  384.     mvprintw(MOVE_Y + 2, MOVE_X, "%16s", C_name[pp->hand[Card_no]]);
  385. }
  386.  
  387. onecard(pp)
  388. reg PLAY    *pp; {
  389.  
  390.     reg CARD    bat, spd, card;
  391.  
  392.     bat = pp->battle;
  393.     spd = pp->speed;
  394.     card = -1;
  395.     if (pp->can_go || ((isrepair(bat) || bat == C_STOP
  396.         || spd == C_LIMIT) && Numseen[S_RIGHT_WAY] != 0)
  397.         || Numseen[safety(bat)] != 0)
  398.         switch (End - pp->mileage) {
  399.           case 200:
  400.             if (pp->nummiles[C_200] == 2)
  401.                 return FALSE;
  402.             card = C_200;
  403.           case 100:
  404.           case 75:
  405.             if (card == -1)
  406.                 card = (End - pp->mileage == 75 ? C_75 : C_100);
  407.             if (spd == C_LIMIT)
  408.                 return Numseen[S_RIGHT_WAY] == 0;
  409.           case 50:
  410.           case 25:
  411.             if (card == -1)
  412.                 card = (End - pp->mileage == 25 ? C_25 : C_50);
  413.             return Numseen[card] != Numcards[card];
  414.         }
  415.     return FALSE;
  416. }
  417.  
  418. canplay(pp, op, card)
  419. reg PLAY    *pp, *op;
  420. reg CARD    card; {
  421.  
  422.     switch (card) {
  423.       case C_200:
  424.         if (pp->nummiles[C_200] == 2)
  425.             break;
  426.       case C_75:    case C_100:
  427.         if (pp->speed == C_LIMIT)
  428.             break;
  429.       case C_50:
  430.         if (pp->mileage + Value[card] > End)
  431.             break;
  432.       case C_25:
  433.         if (pp->can_go)
  434.             return TRUE;
  435.         break;
  436.       case C_EMPTY:    case C_FLAT:    case C_CRASH:
  437.       case C_STOP:
  438.         if (op->can_go && op->safety[safety(card) - S_CONV] != S_PLAYED)
  439.             return TRUE;
  440.         break;
  441.       case C_LIMIT:
  442.         if (op->speed != C_LIMIT && op->safety[S_RIGHT_WAY] != S_PLAYED
  443.             && op->mileage + 50 < End)
  444.             return TRUE;
  445.         break;
  446.       case C_GAS:    case C_SPARE:    case C_REPAIRS:
  447.         if (pp->battle == opposite(card))
  448.             return TRUE;
  449.         break;
  450.       case C_GO:
  451.         if (!pp->can_go
  452.             && (isrepair(pp->battle) || pp->battle == C_STOP))
  453.             return TRUE;
  454.         break;
  455.       case C_END_LIMIT:
  456.         if (pp->speed == C_LIMIT)
  457.             return TRUE;
  458.     }
  459.     return FALSE;
  460. }
  461. //go.sysin dd *
  462. echo 'x - =test/=mille/end.c'
  463. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/end.c
  464. # include    "mille.h"
  465.  
  466. X/*
  467.  *    print out the score as if it was final, and add the totals for
  468.  * the end-of-games points to the user who deserves it (if any).
  469.  */
  470. finalscore(pp)
  471. reg PLAY    *pp; {
  472.  
  473.     reg int        temp, tot, num;
  474.  
  475.     num = pp - Player;
  476.     temp = num * 6 + 21 + 3;
  477.     for (tot = 5; tot <= 9; tot++)
  478.         mvaddch(tot, temp, '0');
  479.     if (pp->mileage == End) {
  480.         temp -= 2;
  481.         mvaddstr(5, temp, "40");
  482.         tot = SC_TRIP;
  483.         if (pp->nummiles[C_200] == 0) {
  484.             mvaddstr(6, temp, "30");
  485.             tot = SC_TRIP + SC_SAFE;
  486.         }
  487.         if (Topcard <= Deck) {
  488.             mvaddstr(7, temp, "30");
  489.             tot += SC_DELAY;
  490.         }
  491.         if (End == 1000) {
  492.             mvaddstr(8, temp, "20");
  493.             tot += SC_EXTENSION;
  494.         }
  495.         if (Player[other(num)].mileage == 0) {
  496.             mvaddstr(9, temp, "50");
  497.             tot += SC_SHUT_OUT;
  498.         }
  499.         pp->total += tot;
  500.         pp->hand_tot += tot;
  501.     }
  502. }
  503.  
  504. # ifdef EXTRAP
  505. static int    Last_tot[2];    /* last tot used for extrapolate    */
  506.  
  507. X/*
  508.  *    print out the score as if it was final, and add the totals for
  509.  * the end-of-games points to the user who deserves it (if any).
  510.  */
  511. extrapolate(pp)
  512. reg PLAY    *pp; {
  513.  
  514.     reg int        x, num, tot, count;
  515.  
  516.     num = pp - Player;
  517.     tot += SC_TRIP + SC_DELAY + SC_EXT;
  518.     x = num * 6 + 21 + 3;
  519.     for (tot = 5; tot <= 9; tot++)
  520.         mvaddch(tot, x, '0');
  521.     x -= 2;
  522.     pp = &Player[other(num)];
  523.     for (count = 0, tot = 0; tot < NUM_SAFE; tot++)
  524.         if (pp->safety[tot] != S_PLAYED)
  525.             count += SC_SAFE;
  526.     mvprintw(3, x, "%3d", count);
  527.     tot += count;
  528.     if (count == 400) {
  529.         mvaddstr(4, x, "30");
  530.         tot += SC_ALL_SAFE;
  531.     }
  532.     pp = &Player[num];
  533.     for (count = 0, tot = 0; tot < NUM_SAFE; tot++)
  534.         if (pp->safety[tot] != S_PLAYED)
  535.             count += SC_COUP / 10;
  536.     mvprintw(4, x - 1, "%3d", count);
  537.     tot += count;
  538.     tot += 1000 - pp->mileage;
  539.     mvaddstr(5, x, "40");
  540.     mvaddstr(7, x, "30");
  541.     mvaddstr(8, x, "20");
  542.     if (pp->nummiles[C_200] == 0) {
  543.         mvaddstr(6, x, "30");
  544.         tot = SC_TRIP + SC_SAFE;
  545.     }
  546.     if (Player[other(num)].mileage == 0) {
  547.         mvaddstr(9, x, "50");
  548.         tot += SC_SHUT_OUT;
  549.     }
  550.     pp->total += tot;
  551.     pp->hand_tot += tot;
  552.     Last_tot[num] = tot;
  553. }
  554.  
  555. undoex() {
  556.  
  557.     reg PLAY    *pp;
  558.     reg int        i;
  559.  
  560.     i = 0;
  561.     for (pp = Player; pp < &Player[2]; pp++) {
  562.         pp->total -= Last_tot[i];
  563.         pp->hand_tot -= Last_tot[i++];
  564.     }
  565. }
  566. # endif
  567. //go.sysin dd *
  568. echo 'x - =test/=mille/extern.c'
  569. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/extern.c
  570. # include    "mille.h"
  571.  
  572. bool    Debug,            /* set if debugging code on        */
  573.     Finished,        /* set if current hand is finished    */
  574.     Next,            /* set if changing players        */
  575.     On_exit,        /* set if game saved on exiting        */
  576.     Order,            /* set if hand should be sorted        */
  577.     Saved;            /* set if game just saved        */
  578.  
  579. char    *C_fmt = "%-18.18s",    /* format for printing cards        */
  580.     *Fromfile = NULL,    /* startup file for game        */
  581.     Initstr[100],        /* initial string for error field    */
  582.     *_cn[NUM_CARDS] = {    /* Card name buffer            */
  583.         "",
  584.         "25",
  585.         "50",
  586.         "75",
  587.         "100",
  588.         "200",
  589.         "Out of Gas",
  590.         "Flat Tire",
  591.         "Accident",
  592.         "Stop",
  593.         "Speed Limit", 
  594.         "Gasoline",
  595.         "Spare Tire",
  596.         "Repairs",
  597.         "Go",
  598.         "End of Limit",
  599.         "Extra Tank",
  600.         "Puncture Proof",
  601.         "Driving Ace",
  602.         "Right of Way"
  603.     },
  604.     **C_name = &_cn[1];    /* Card names                */
  605.  
  606. int    Card_no,        /* Card number for current move        */
  607.     End,            /* End value for current hand        */
  608.     Handstart = COMP,    /* Player who starts hand        */
  609.     Movetype,        /* Current move type            */
  610.     Play,            /* Current player            */
  611.     Numgos,            /* Number of Go cards used by computer    */
  612.     Window = W_SMALL,    /* Current window wanted        */
  613.     Numseen[NUM_CARDS],    /* Number of cards seen in current hand    */
  614.     Value[NUM_MILES] = {    /* Value of mileage cards        */
  615.         25, 50, 75, 100, 200
  616.     },
  617.     Numcards[NUM_CARDS] = {    /* Number of cards in deck        */
  618.         10,    /* C_25 */
  619.         10,    /* C_50 */
  620.         10,    /* C_75 */
  621.         12,    /* C_100 */
  622.         4,    /* C_200 */
  623.         2,    /* C_EMPTY */
  624.         2,    /* C_FLAT */
  625.         2,    /* C_CRASH */
  626.         4,    /* C_STOP */
  627.         3,    /* C_LIMIT */
  628.         6,    /* C_GAS */
  629.         6,    /* C_SPARE */
  630.         6,    /* C_REPAIRS */
  631.         14,    /* C_GO */
  632.         6,    /* C_END_LIMIT */
  633.         1,    /* C_GAS_SAFE */
  634.         1,    /* C_SPARE_SAFE */
  635.         1,    /* C_DRIVE_SAFE */
  636.         1,    /* C_RIGHT_WAY */
  637.         0    /* C_INIT */
  638.     };
  639.     Numneed[NUM_CARDS] = {    /* number of cards needed per hand    */
  640.         0,    /* C_25 */
  641.         0,    /* C_50 */
  642.         0,    /* C_75 */
  643.         0,    /* C_100 */
  644.         0,    /* C_200 */
  645.         2,    /* C_EMPTY */
  646.         2,    /* C_FLAT */
  647.         2,    /* C_CRASH */
  648.         4,    /* C_STOP */
  649.         3,    /* C_LIMIT */
  650.         2,    /* C_GAS */
  651.         2,    /* C_SPARE */
  652.         2,    /* C_REPAIRS */
  653.         10,    /* C_GO */
  654.         3,    /* C_END_LIMIT */
  655.         1,    /* C_GAS_SAFE */
  656.         1,    /* C_SPARE_SAFE */
  657.         1,    /* C_DRIVE_SAFE */
  658.         1,    /* C_RIGHT_WAY */
  659.         0    /* C_INIT */
  660.     };
  661.  
  662. CARD    Discard,        /* Top of discard pile            */
  663.     *Topcard,        /* Pointer to next card to be picked    */
  664.     Opposite[NUM_CARDS] = {    /* Opposites of each card        */
  665.         C_25, C_50, C_75, C_100, C_200, C_GAS, C_SPARE,
  666.         C_REPAIRS, C_GO, C_END_LIMIT, C_EMPTY, C_FLAT, C_CRASH,
  667.         C_STOP, C_LIMIT, C_EMPTY, C_FLAT, C_CRASH, C_STOP, C_INIT
  668.     },
  669.     Deck[DECK_SZ] = {    /* Current deck                */
  670.         C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25, C_25,
  671.         C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50, C_50,
  672.         C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75, C_75,
  673.         C_100, C_100, C_100, C_100, C_100, C_100, C_100, C_100, C_100,
  674.         C_100, C_100, C_100,
  675.         C_200, C_200, C_200, C_200,
  676.         C_EMPTY, C_EMPTY,
  677.         C_FLAT, C_FLAT,
  678.         C_CRASH, C_CRASH,
  679.         C_STOP, C_STOP, C_STOP, C_STOP,
  680.         C_LIMIT, C_LIMIT, C_LIMIT,
  681.         C_GAS, C_GAS, C_GAS, C_GAS, C_GAS, C_GAS,
  682.         C_SPARE, C_SPARE, C_SPARE, C_SPARE, C_SPARE, C_SPARE,
  683.         C_REPAIRS, C_REPAIRS, C_REPAIRS, C_REPAIRS, C_REPAIRS,
  684.             C_REPAIRS,
  685.         C_END_LIMIT, C_END_LIMIT, C_END_LIMIT, C_END_LIMIT, C_END_LIMIT,
  686.             C_END_LIMIT,
  687.         C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO, C_GO,
  688.             C_GO, C_GO, C_GO, C_GO,
  689.         C_GAS_SAFE, C_SPARE_SAFE, C_DRIVE_SAFE, C_RIGHT_WAY
  690.     };
  691.  
  692. XFILE    *outf;
  693.  
  694. PLAY    Player[2];        /* Player descriptions            */
  695.  
  696. WINDOW    *Board,            /* Playing field screen            */
  697.     *Miles,            /* Mileage screen            */
  698.     *Score;            /* Score screen                */
  699. //go.sysin dd *
  700. echo 'x - =test/=mille/init.c'
  701. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/init.c
  702. # include    "mille.h"
  703.  
  704. init() {
  705.  
  706.     reg PLAY    *pp;
  707.     reg int        i, j;
  708.     reg CARD    card;
  709.  
  710.     for (j = 0; j < C_RIGHT_WAY; j++)
  711.         Numseen[j] = 0;
  712.     Numgos = 0;
  713.  
  714.     for (i = 0; i < 2; i++) {
  715.         pp = &Player[i];
  716.         pp->hand[0] = C_INIT;
  717.         for (j = 0; j < NUM_SAFE; j++) {
  718.             pp->safety[j] = S_UNKNOWN;
  719.             pp->coups[j] = FALSE;
  720.         }
  721.         for (j = 1; j < HAND_SZ; j++) {
  722.             pp->hand[j] = *--Topcard;
  723.             if (i == COMP) {
  724.                 account(card = *Topcard);
  725.                 if (issafety(card))
  726.                     pp->safety[card - S_CONV] = S_IN_HAND;
  727.             }
  728.         }
  729.         pp->mileage = 0;
  730.         pp->hand_tot = 0;
  731.         pp->safescore = 0;
  732.         pp->coupscore = 0;
  733.         pp->can_go = FALSE;
  734.         pp->speed = C_INIT;
  735.         pp->battle = C_INIT;
  736.         pp->new_speed = FALSE;
  737.         pp->new_battle = FALSE;
  738.         for (j = 0; j < NUM_MILES; j++)
  739.             pp->nummiles[j] = 0;
  740.     }
  741.     if (Order)
  742.         sort(Player[PLAYER].hand);
  743.     Discard = C_INIT;
  744.     Finished = FALSE;
  745.     End = 700;
  746. }
  747.  
  748. shuffle() {
  749.  
  750.     reg int        i, r;
  751.     reg CARD    temp;
  752.  
  753.     for (i = 0; i < DECK_SZ; i++) {
  754.         r = roll(1, DECK_SZ) - 1;
  755.         if (r < 0 || r > DECK_SZ - 1) {
  756.             fprintf(stderr, "shuffle: card no. error: %d\n", r);
  757.             die();
  758.         }
  759.         temp = Deck[r];
  760.         Deck[r] = Deck[i];
  761.         Deck[i] = temp;
  762.     }
  763.     Topcard = &Deck[DECK_SZ];
  764. }
  765.  
  766. newboard() {
  767.  
  768.     werase(Board);
  769.     werase(Score);
  770.     mvaddstr(5, 0, "--HAND--");
  771.     mvaddch(6, 0, 'P');
  772.     mvaddch(7, 0, '1');
  773.     mvaddch(8, 0, '2');
  774.     mvaddch(9, 0, '3');
  775.     mvaddch(10, 0, '4');
  776.     mvaddch(11, 0, '5');
  777.     mvaddch(12, 0, '6');
  778.     mvaddstr(13, 0, "--BATTLE--");
  779.     mvaddstr(15, 0, "--SPEED--");
  780.     mvaddstr(5, 20, "--DECK--");
  781.     mvaddstr(7, 20, "--DISCARD--");
  782.     mvaddstr(13, 20, "--BATTLE--");
  783.     mvaddstr(15, 20, "--SPEED--");
  784.     wmove(Miles, 0, 0);
  785.     if (winch(Miles) != '-') {
  786.         werase(Miles);
  787.         mvwaddstr(Miles, 0, 0, "--MILEAGE--");
  788.         mvwaddstr(Miles, 0, 41, "--MILEAGE--");
  789.     }
  790.     else {
  791.         wmove(Miles, 1, 0);
  792.         wclrtobot(Miles);
  793.     }
  794.     newscore();
  795.     stdscr = Board;
  796. }
  797.  
  798. newscore() {
  799.  
  800.     reg int    i;
  801.  
  802.     stdscr = Score;
  803.     move(0, 22);
  804.     if (inch() != 'Y') {
  805.         erase();
  806.         mvaddstr(0, 22,  "You   Comp   Value");
  807.         mvaddstr(1, 2, "Milestones Played");
  808.         mvaddstr(2, 8, "Each Safety");
  809.         mvaddstr(3, 5, "All 4 Safeties");
  810.         mvaddstr(4, 3, "Each Coup Fourre");
  811.         mvaddstr(2, 37, "100");
  812.         mvaddstr(3, 37, "300");
  813.         mvaddstr(4, 37, "300");
  814.     }
  815.     else {
  816.         move(5, 1);
  817.         clrtobot();
  818.     }
  819.     for (i = 0; i < SCORE_Y; i++)
  820.         mvaddch(i, 0, '|');
  821.     move(SCORE_Y - 1, 1);
  822.     while (addch('_') != ERR)
  823.         continue;
  824.     if (Window == W_FULL || Finished) {
  825.         mvaddstr(5, 5, "Trip Completed");
  826.         mvaddstr(6, 10, "Safe Trip");
  827.         mvaddstr(7, 5, "Delayed Action");
  828.         mvaddstr(8, 10, "Extension");
  829.         mvaddstr(9, 11, "Shut-Out");
  830.         mvaddstr(10, 21, "----   ----   -----");
  831.         mvaddstr(11, 9, "Hand Total");
  832.         mvaddstr(12, 20, "-----  -----");
  833.         mvaddstr(13, 6, "Overall Total");
  834.         mvaddstr(14, 15, "Games");
  835.         mvaddstr(5, 37, "400");
  836.         mvaddstr(6, 37, "300");
  837.         mvaddstr(7, 37, "300");
  838.         mvaddstr(8, 37, "200");
  839.         mvaddstr(9, 37, "500");
  840.     }
  841.     else {
  842.         mvaddstr(5, 21, "----   ----   -----");
  843.         mvaddstr(6, 9, "Hand Total");
  844.         mvaddstr(7, 20, "-----  -----");
  845.         mvaddstr(8, 6, "Overall Total");
  846.         mvaddstr(9, 15, "Games");
  847.         mvaddstr(11, 2, "p: pick");
  848.         mvaddstr(12, 2, "u: use #");
  849.         mvaddstr(13, 2, "d: discard #");
  850.         mvaddstr(14, 2, "w: toggle window");
  851.         mvaddstr(11, 21, "q: quit");
  852.         mvaddstr(12, 21, "o: order hand");
  853.         mvaddstr(13, 21, "s: save");
  854.         mvaddstr(14, 21, "r: reprint");
  855.     }
  856.     stdscr = Board;
  857. }
  858. //go.sysin dd *
  859. echo 'x - =test/=mille/mille.c'
  860. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/mille.c
  861. # include    "mille.h"
  862. # include    <signal.h>
  863. # include       <term.h>
  864.  
  865. int    rub();
  866.  
  867. char    _sobuf[BUFSIZ];
  868.  
  869. main(ac, av)
  870. reg int        ac;
  871. reg char    *av[]; {
  872.  
  873.     reg bool    restore;
  874.  
  875. # if 0
  876.     if (getuid() == GURP) {
  877.         printf("%s: Permission denied\n", av[0]);
  878.         exit(1);
  879.     }
  880. # endif
  881.     if (strcmp(av[0], "a.out") == 0) {
  882.         outf = fopen("q", "w");
  883.         setbuf(outf, 0);
  884.         Debug = TRUE;
  885.     }
  886.     restore = FALSE;
  887. # ifdef pdp11
  888.     if (geteuid() != ARNOLD)
  889.         maxusers(MAXUSERS, NULL);
  890. # endif
  891.     switch (ac) {
  892.       case 2:
  893.         rest_f(av[1]);
  894.         restore = TRUE;
  895.       case 1:
  896.         break;
  897.       default:
  898.         printf("usage: milles [ restore_file ]\n");
  899.         exit(-1);
  900.         /* NOTREACHED */
  901.     }
  902.     setbuf(stdout, _sobuf);
  903.     Play = PLAYER;
  904.     initscr();
  905.     if (! cursor_address) {
  906.         printf("Sorry.  Need cursor addressing to play mille\n");
  907.         exit(-1);
  908.     }
  909.     delwin(stdscr);
  910.     stdscr = Board = newwin(BOARD_Y, BOARD_X, 0, 0);
  911.     Score = newwin(SCORE_Y, SCORE_X, 0, 40);
  912.     Miles = newwin(MILES_Y, MILES_X, 17, 0);
  913.     leaveok(Score, TRUE);
  914.     leaveok(Miles, TRUE);
  915.     clearok(curscr, TRUE);
  916. # ifndef PROF
  917.     srand(getpid());
  918. # else
  919.     srand(0);
  920. # endif
  921.     crmode();
  922.     noecho();
  923.     nonl();
  924.     signal(SIGINT, rub);
  925.     for (;;) {
  926.         if (!restore || (Player[PLAYER].total >= 5000
  927.             || Player[COMP].total >= 5000)) {
  928.             if (Player[COMP].total < Player[PLAYER].total)
  929.                 Player[PLAYER].games++;
  930.             else if (Player[COMP].total > Player[PLAYER].total)
  931.                 Player[COMP].games++;
  932.             Player[COMP].total = 0;
  933.             Player[PLAYER].total = 0;
  934.         }
  935.         do {
  936.             if (!restore)
  937.                 Handstart = Play = other(Handstart);
  938.             if (!restore || On_exit) {
  939.                 shuffle();
  940.                 init();
  941.             }
  942.             newboard();
  943.             if (restore)
  944.                 mvwaddstr(Score, ERR_Y, ERR_X, Initstr);
  945.             prboard();
  946.             do {
  947.                 domove();
  948.                 if (Finished)
  949.                     newscore();
  950.                 prboard();
  951.             } while (!Finished);
  952.             check_more();
  953.             restore = On_exit = FALSE;
  954.         } while (Player[COMP].total < 5000
  955.             && Player[PLAYER].total < 5000);
  956.     }
  957. }
  958.  
  959. X/*
  960.  *    Routine to trap rubouts, and make sure they really want to
  961.  * quit.
  962.  */
  963. rub() {
  964.  
  965.     signal(SIGINT, 1);
  966.     if (getyn("Really? "))
  967.         die();
  968.     signal(SIGINT, rub);
  969. }
  970.  
  971. X/*
  972.  *    Time to go beddy-by
  973.  */
  974. die() {
  975.  
  976.     signal(SIGINT, 1);
  977.     if (outf)
  978.         fflush(outf);
  979.     mvcur(0, COLS - 1, LINES - 1, 0);
  980.     endwin();
  981.     exit(1);
  982. }
  983. //go.sysin dd *
  984. echo 'x - =test/=mille/mille.h'
  985. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/mille.h
  986. # include    <ctype.h>
  987. # include    <curses.h>
  988.  
  989. X/*
  990.  * Miscellaneous constants
  991.  */
  992.  
  993. # define    unsgn        unsigned
  994. # define        reg             register
  995. # define    CARD        short
  996.  
  997. # ifdef  vax
  998. #    define    ARNOLD        78    /* my uid            */
  999. # else
  1000. #    define    ARNOLD        24601    /* my uid            */
  1001. # endif
  1002.  
  1003. # define    GURP        28672    /* bad uid            */
  1004. # define    MAXUSERS    35    /* max # of users for startup    */
  1005. # define    HAND_SZ        7    /* number of cards in a hand    */
  1006. # define    DECK_SZ        101    /* number of cards in decks    */
  1007. # define    NUM_SAFE    4    /* number of saftey cards    */
  1008. # define    NUM_MILES    5    /* number of milestones types    */
  1009. # define    NUM_CARDS    20    /* number of types of cards    */
  1010. # define    BOARD_Y        17    /* size of board screen        */
  1011. # define    BOARD_X        40
  1012. # define    MILES_Y        7    /* size of mileage screen    */
  1013. # define    MILES_X        80
  1014. # define    SCORE_Y        17    /* size of score screen        */
  1015. # define    SCORE_X        40
  1016. # define    MOVE_Y        10    /* Where to print move prompt    */
  1017. # define    MOVE_X        20
  1018. # define    ERR_Y        15    /* Where to print errors    */
  1019. # define    ERR_X        5
  1020. # define    EXT_Y        4    /* Where to put Extension    */
  1021. # define    EXT_X        9
  1022.  
  1023. # define    PLAYER        0
  1024. # define    COMP        1
  1025.  
  1026. # define    W_SMALL        0    /* Small (initial) window    */
  1027. # define    W_FULL        1    /* Full (final) window        */
  1028.  
  1029. X/*
  1030.  * Move types
  1031.  */
  1032.  
  1033. # define    M_DISCARD    0
  1034. # define    M_DRAW        1
  1035. # define    M_PLAY        2
  1036. # define    M_ORDER        3
  1037.  
  1038. X/*
  1039.  * Scores
  1040.  */
  1041.  
  1042. # define    SC_SAFETY    100
  1043. # define    SC_ALL_SAFE    300
  1044. # define    SC_COUP        300
  1045. # define    SC_TRIP        400
  1046. # define    SC_SAFE        300
  1047. # define    SC_DELAY    300
  1048. # define    SC_EXTENSION    200
  1049. # define    SC_SHUT_OUT    500
  1050.  
  1051. X/*
  1052.  * safety descriptions
  1053.  */
  1054.  
  1055. # define    S_UNKNOWN    0    /* location of safety unknown    */
  1056. # define    S_IN_HAND    1    /* safety in player's hand    */
  1057. # define    S_PLAYED    2    /* safety has been played    */
  1058. # define    S_GAS_SAFE    0    /* Gas safety card index    */
  1059. # define    S_SPARE_SAFE    1    /* Tire safety card index    */
  1060. # define    S_DRIVE_SAFE    2    /* Driveing safety card index    */
  1061. # define    S_RIGHT_WAY    3    /* Right-of-Way card index    */
  1062. # define    S_CONV        15    /* conversion from C_ to S_    */
  1063.  
  1064. X/*
  1065.  * card numbers
  1066.  */
  1067.  
  1068. # define    C_INIT        -1
  1069. # define    C_25        0
  1070. # define    C_50        1
  1071. # define    C_75        2
  1072. # define    C_100        3
  1073. # define    C_200        4
  1074. # define    C_EMPTY        5
  1075. # define    C_FLAT        6    
  1076. # define    C_CRASH        7
  1077. # define    C_STOP        8
  1078. # define    C_LIMIT        9
  1079. # define    C_GAS        10
  1080. # define    C_SPARE        11
  1081. # define    C_REPAIRS    12
  1082. # define    C_GO        13
  1083. # define    C_END_LIMIT    14
  1084. # define    C_GAS_SAFE    15
  1085. # define    C_SPARE_SAFE    16
  1086. # define    C_DRIVE_SAFE    17
  1087. # define    C_RIGHT_WAY    18
  1088.  
  1089. typedef struct {
  1090.     bool    coups[NUM_SAFE];
  1091.     bool    can_go;
  1092.     bool    new_battle;
  1093.     bool    new_speed;
  1094.     short    safety[NUM_SAFE];
  1095.     short    nummiles[NUM_MILES];
  1096.     CARD    hand[HAND_SZ];
  1097.     CARD    battle;
  1098.     CARD    speed;
  1099.     int    mileage;
  1100.     int    hand_tot;
  1101.     int    safescore;
  1102.     int    coupscore;
  1103.     int    total;
  1104.     int    games;
  1105. } PLAY;
  1106.  
  1107. X/*
  1108.  * macros
  1109.  */
  1110.  
  1111. # define    other(x)    (1 - x)
  1112. # define    nextplay()    (Play = other(Play))
  1113. # define    nextwin(x)    (1 - x)
  1114. # define    opposite(x)    (Opposite[x])
  1115. # define    issafety(x)    (x >= C_GAS_SAFE)
  1116.  
  1117. X/*
  1118.  * externals
  1119.  */
  1120.  
  1121. extern bool    Debug, Finished, Next, On_exit, Order, Saved;
  1122.  
  1123. extern char    *C_fmt, **C_name, *Fromfile, Initstr[];
  1124.  
  1125. extern int    Card_no, End, Handstart, Movetype, Numcards[], Numgos,
  1126.         Numneed[], Numseen[NUM_CARDS], Play, Value[], Window;
  1127.  
  1128. extern CARD    Deck[DECK_SZ], Discard, Opposite[NUM_CARDS], *Topcard;
  1129.  
  1130. extern FILE    *outf;
  1131.  
  1132. extern PLAY    Player[2];
  1133.  
  1134. extern WINDOW    *Board, *Miles, *Score;
  1135.  
  1136. X/*
  1137.  * functions
  1138.  */
  1139.  
  1140. CARD    getcard();
  1141. //go.sysin dd *
  1142. echo 'x - =test/=mille/misc.c'
  1143. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/misc.c
  1144. #include    "mille.h"
  1145. #include    "unctrl.h"
  1146. #define    NUMSAFE    4
  1147.  
  1148. X/* VARARGS1 */
  1149. error(str, arg)
  1150. char    *str;
  1151. {
  1152.     stdscr = Score;
  1153.     mvprintw(ERR_Y, ERR_X, str, arg);
  1154.     clrtoeol();
  1155.     putchar('');
  1156.     refresh();
  1157.     stdscr = Board;
  1158.     return FALSE;
  1159. }
  1160.  
  1161. CARD
  1162. getcard()
  1163. {
  1164.     reg char    c, c1;
  1165.  
  1166.     for (;;) {
  1167.         while ((c = getch()) == '\n' || c == '\r' || c == ' ')
  1168.             continue;
  1169.         if (islower(c))
  1170.             c = toupper(c);
  1171.         if (c == killchar() || c == erasechar())
  1172.             return -1;
  1173.         addstr(unctrl(c));
  1174.         clrtoeol();
  1175.         switch (c) {
  1176.           case '1':    case '2':    case '3':
  1177.           case '4':    case '5':    case '6':
  1178.             c -= '0';
  1179.             break;
  1180.           case '0':    case 'P':    case 'p':
  1181.             c = 0;
  1182.             break;
  1183.           default:
  1184.             putchar('');
  1185.             addch('\b');
  1186.             if (!isprint(c))
  1187.                 addch('\b');
  1188.             c = -1;
  1189.             break;
  1190.         }
  1191.         refresh();
  1192.         if (c >= 0) {
  1193.             while ((c1=getch()) != '\r' && c1 != '\n' && c1 != ' ')
  1194.                 if (c1 == killchar())
  1195.                     return -1;
  1196.                 else if (c1 == erasechar()) {
  1197.                     addch('\b');
  1198.                     clrtoeol();
  1199.                     refresh();
  1200.                     goto cont;
  1201.                 }
  1202.                 else
  1203.                     write(0, "", 1);
  1204.             return c;
  1205.         }
  1206. cont:        ;
  1207.     }
  1208. }
  1209.  
  1210. check_ext(forcomp)
  1211. reg bool    forcomp; {
  1212.  
  1213.  
  1214.     if (End == 700)
  1215.         if (Play == PLAYER) {
  1216.             if (getyn("Extension? ")) {
  1217. extend:
  1218.                 if (!forcomp)
  1219.                     End = 1000;
  1220.                 return TRUE;
  1221.             }
  1222.             else {
  1223. done:
  1224.                 if (!forcomp)
  1225.                     Finished = TRUE;
  1226.                 return FALSE;
  1227.             }
  1228.         }
  1229.         else {
  1230.             reg PLAY    *pp, *op;
  1231.             reg int        i, safe, miles;
  1232.  
  1233.             pp = &Player[COMP];
  1234.             op = &Player[PLAYER];
  1235.             for (safe = 0, i = 0; i < NUMSAFE; i++)
  1236.                 if (pp->safety[i] != S_UNKNOWN)
  1237.                     safe++;
  1238.             if (safe < 2)
  1239.                 goto done;
  1240.             if (op->mileage == 0 || onecard(op)
  1241.                 || (op->can_go && op->mileage >= 500))
  1242.                 goto done;
  1243.             for (miles = 0, i = 0; i < NUMSAFE; i++)
  1244.                 if (op->safety[i] != S_PLAYED
  1245.                     && pp->safety[i] == S_UNKNOWN)
  1246.                     miles++;
  1247.             if (miles + safe == NUMSAFE)
  1248.                 goto extend;
  1249.             for (miles = 0, i = 0; i < HAND_SZ; i++)
  1250.                 if ((safe = pp->hand[i]) <= C_200)
  1251.                     miles += Value[safe]; 
  1252.             if (miles + (Topcard - Deck) * 3 > 1000)
  1253.                 goto extend;
  1254.             goto done;
  1255.         }
  1256.     else
  1257.         goto done;
  1258. }
  1259.  
  1260. X/*
  1261.  *    Get a yes or no answer to the given question.  Saves are
  1262.  * also allowed.  Return TRUE if the answer was yes, FALSE if no.
  1263.  */
  1264. getyn(prompt)
  1265. reg char    *prompt; {
  1266.  
  1267.     reg char    c;
  1268.  
  1269.     Saved = FALSE;
  1270.     for (;;) {
  1271.         leaveok(Board, FALSE);
  1272.         mvaddstr(MOVE_Y, MOVE_X, prompt);
  1273.         clrtoeol();
  1274.         refresh();
  1275.         switch (c = getch()) {
  1276.           case 'n':    case 'N':
  1277.             addch('N');
  1278.             refresh();
  1279.             leaveok(Board, TRUE);
  1280.             return FALSE;
  1281.           case 'y':    case 'Y':
  1282.             addch('Y');
  1283.             refresh();
  1284.             leaveok(Board, TRUE);
  1285.             return TRUE;
  1286.           case 's':    case 'S':
  1287.             addch('S');
  1288.             refresh();
  1289.             Saved = save();
  1290.             continue;
  1291.           default:
  1292.             addstr(unctrl(c));
  1293.             refresh();
  1294.             putchar('');
  1295.             break;
  1296.         }
  1297.     }
  1298. }
  1299.  
  1300. X/*
  1301.  *    Check to see if more games are desired.  If not, and game
  1302.  * came from a saved file, make sure that they don't want to restore
  1303.  * it.  Exit appropriately.
  1304.  */
  1305. check_more() {
  1306.  
  1307.     raw();    /* Flush input */
  1308.     noraw();
  1309.  
  1310.     On_exit = TRUE;
  1311.     if (Player[PLAYER].total >= 5000 || Player[COMP].total >= 5000)
  1312.         if (getyn("Another game? "))
  1313.             return;
  1314.         else {
  1315.             /*
  1316.              * must do accounting normally done in main()
  1317.              */
  1318.             if (Player[PLAYER].total > Player[COMP].total)
  1319.                 Player[PLAYER].games++;
  1320.             else if (Player[PLAYER].total < Player[COMP].total)
  1321.                 Player[COMP].games++;
  1322.             Player[COMP].total = 0;
  1323.             Player[PLAYER].total = 0;
  1324.         }
  1325.     else
  1326.         if (getyn("Another hand? "))
  1327.             return;
  1328.     if (!Saved && getyn("Save game? "))
  1329.         if (!save())
  1330.             return;
  1331.     die();
  1332. }
  1333. //go.sysin dd *
  1334. echo 'x - =test/=mille/move.c'
  1335. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/move.c
  1336. #include    "mille.h"
  1337. #include    "unctrl.h"
  1338.  
  1339. #define    CTRL(c)        (c - 'A' + 1)
  1340.  
  1341. char    *Movenames[] = {
  1342.         "M_DISCARD", "M_DRAW", "M_PLAY", "M_ORDER"
  1343.     };
  1344.  
  1345. domove()
  1346. {
  1347.     reg PLAY    *pp;
  1348.     reg int        i, j;
  1349.     reg bool    goodplay;
  1350.  
  1351.     pp = &Player[Play];
  1352.     if (Play == PLAYER)
  1353.         getmove();
  1354.     else
  1355.         calcmove();
  1356.     Next = FALSE;
  1357.     goodplay = TRUE;
  1358.     switch (Movetype) {
  1359.       case M_DISCARD:
  1360.         if (haspicked(pp)) {
  1361.             if (pp->hand[Card_no] == C_INIT)
  1362.                 if (Card_no == 6)
  1363.                     Finished = TRUE;
  1364.                 else
  1365.                     error("no card there");
  1366.             else {
  1367.                 Discard = pp->hand[Card_no];
  1368.                 pp->hand[Card_no] = C_INIT;
  1369.                 Next = TRUE;
  1370.                 if (Play == PLAYER)
  1371.                     account(Discard);
  1372.             }
  1373.         }
  1374.         else
  1375.             error("must pick first");
  1376.         break;
  1377.       case M_PLAY:
  1378.         goodplay = playcard(pp);
  1379.         break;
  1380.       case M_DRAW:
  1381.         Card_no = 0;
  1382.         if (Topcard <= Deck)
  1383.             error("no more cards");
  1384.         else if (haspicked(pp))
  1385.             error("already picked");
  1386.         else {
  1387.             pp->hand[0] = *--Topcard;
  1388.             if (Debug)
  1389.                 fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
  1390. acc:
  1391.             if (Play == COMP) {
  1392.                 account(*Topcard);
  1393.                 if (issafety(*Topcard))
  1394.                     pp->safety[*Topcard-S_CONV] = S_IN_HAND;
  1395.             }
  1396.             if (pp->hand[1] == C_INIT && Topcard > Deck) {
  1397.                 Card_no = 1;
  1398.                 pp->hand[1] = *--Topcard;
  1399.                 if (Debug)
  1400.                     fprintf(outf, "DOMOVE: Draw %s\n", C_name[*Topcard]);
  1401.                 goto acc;
  1402.             }
  1403.             pp->new_battle = FALSE;
  1404.             pp->new_speed = FALSE;
  1405.         }
  1406.         break;
  1407.  
  1408.       case M_ORDER:
  1409.         break;
  1410.     }
  1411.     /*
  1412.      * move blank card to top by one of two methods.  If the
  1413.      * computer's hand was sorted, the randomness for picking
  1414.      * between equally valued cards would be lost
  1415.      */
  1416.     if (Order && Movetype != M_DRAW && goodplay && pp == &Player[PLAYER])
  1417.         sort(pp->hand);
  1418.     else
  1419.         for (i = 1; i < HAND_SZ; i++)
  1420.             if (pp->hand[i] == C_INIT) {
  1421.                 for (j = 0; pp->hand[j] == C_INIT; j++)
  1422.                     if (j >= HAND_SZ) {
  1423.                         j = 0;
  1424.                         break;
  1425.                     }
  1426.                 pp->hand[i] = pp->hand[j];
  1427.                 pp->hand[j] = C_INIT;
  1428.             }
  1429.     if (Topcard <= Deck)
  1430.         check_go();
  1431.     if (Next)
  1432.         nextplay();
  1433. }
  1434.  
  1435. X/*
  1436.  *    Check and see if either side can go.  If they cannot,
  1437.  * the game is over
  1438.  */
  1439. check_go() {
  1440.  
  1441.     reg CARD    card;
  1442.     reg PLAY    *pp, *op;
  1443.     reg int        i;
  1444.  
  1445.     for (pp = Player; pp < &Player[2]; pp++) {
  1446.         op = (pp == &Player[COMP] ? &Player[PLAYER] : &Player[COMP]);
  1447.         for (i = 0; i < HAND_SZ; i++) {
  1448.             card = pp->hand[i];
  1449.             if (issafety(card) || canplay(pp, op, card)) {
  1450.                 if (Debug) {
  1451.                     fprintf(outf, "CHECK_GO: can play %s (%d), ", C_name[card], card);
  1452.                     fprintf(outf, "issafety(card) = %d, ", issafety(card));
  1453.                     fprintf(outf, "canplay(pp, op, card) = %d\n", canplay(pp, op, card));
  1454.                 }
  1455.                 return;
  1456.             }
  1457.             else if (Debug)
  1458.                 fprintf(outf, "CHECK_GO: cannot play %s\n",
  1459.                     C_name[card]);
  1460.         }
  1461.     }
  1462.     Finished = TRUE;
  1463. }
  1464.  
  1465. playcard(pp)
  1466. reg PLAY    *pp;
  1467. {
  1468.     reg int        v;
  1469.     reg CARD    card;
  1470.  
  1471.     /*
  1472.      * check and see if player has picked
  1473.      */
  1474.     switch (pp->hand[Card_no]) {
  1475.       default:
  1476.         if (!haspicked(pp))
  1477. mustpick:
  1478.             return error("must pick first");
  1479.       case C_GAS_SAFE:    case C_SPARE_SAFE:
  1480.       case C_DRIVE_SAFE:    case C_RIGHT_WAY:
  1481.         break;
  1482.     }
  1483.  
  1484.     card = pp->hand[Card_no];
  1485.     if (Debug)
  1486.         fprintf(outf, "PLAYCARD: Card = %s\n", C_name[card]);
  1487.     Next = FALSE;
  1488.     switch (card) {
  1489.       case C_200:
  1490.         if (pp->nummiles[C_200] == 2)
  1491.             return error("only two 200's per hand");
  1492.       case C_100:    case C_75:
  1493.         if (pp->speed == C_LIMIT)
  1494.             return error("limit of 50");
  1495.       case C_50:
  1496.         if (pp->mileage + Value[card] > End)
  1497.             return error("puts you over %d", End);
  1498.       case C_25:
  1499.         if (!pp->can_go)
  1500.             return error("cannot move now");
  1501.         pp->nummiles[card]++;
  1502.         v = Value[card];
  1503.         pp->total += v;
  1504.         pp->hand_tot += v;
  1505.         if ((pp->mileage += v) == End)
  1506.             check_ext(FALSE);
  1507.         break;
  1508.  
  1509.       case C_GAS:    case C_SPARE:    case C_REPAIRS:
  1510.         if (pp->battle != opposite(card))
  1511.             return error("can't play \"%s\"", C_name[card]);
  1512.         pp->battle = card;
  1513.         if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
  1514.             pp->can_go = TRUE;
  1515.         break;
  1516.  
  1517.       case C_GO:
  1518.         if (pp->battle != C_INIT && pp->battle != C_STOP
  1519.             && !isrepair(pp->battle))
  1520.             return error("cannot play \"Go\" on a \"%s\"",
  1521.                 C_name[pp->battle]);
  1522.         pp->battle = C_GO;
  1523.         pp->can_go = TRUE;
  1524.         break;
  1525.  
  1526.       case C_END_LIMIT:
  1527.         if (pp->speed != C_LIMIT)
  1528.             return error("not limited");
  1529.         pp->speed = C_END_LIMIT;
  1530.         break;
  1531.  
  1532.       case C_EMPTY:    case C_FLAT:    case C_CRASH:
  1533.       case C_STOP:
  1534.         pp = &Player[other(Play)];
  1535.         if (!pp->can_go)
  1536.             return error("opponent cannot go");
  1537.         else if (pp->safety[safety(card) - S_CONV] == S_PLAYED)
  1538. protected:
  1539.             return error("opponent is protected");
  1540.         pp->battle = card;
  1541.         pp->new_battle = TRUE;
  1542.         pp->can_go = FALSE;
  1543.         pp = &Player[Play];
  1544.         break;
  1545.  
  1546.       case C_LIMIT:
  1547.         pp = &Player[other(Play)];
  1548.         if (pp->speed == C_LIMIT)
  1549.             return error("opponent has limit");
  1550.         if (pp->safety[S_RIGHT_WAY] == S_PLAYED)
  1551.             goto protected;
  1552.         pp->speed = C_LIMIT;
  1553.         pp->new_speed = TRUE;
  1554.         pp = &Player[Play];
  1555.         break;
  1556.  
  1557.       case C_GAS_SAFE:    case C_SPARE_SAFE:
  1558.       case C_DRIVE_SAFE:    case C_RIGHT_WAY:
  1559.         if (pp->battle == opposite(card)
  1560.             || (card == C_RIGHT_WAY && pp->speed == C_LIMIT)) {
  1561.             if (!(card == C_RIGHT_WAY && !isrepair(pp->battle))) {
  1562.                 pp->battle = C_GO;
  1563.                 pp->can_go = TRUE;
  1564.             }
  1565.             if (card == C_RIGHT_WAY && pp->speed == C_LIMIT)
  1566.                 pp->speed = C_INIT;
  1567.             if (pp->new_battle
  1568.                 || (pp->new_speed && card == C_RIGHT_WAY)) {
  1569.                 pp->coups[card - S_CONV] = TRUE;
  1570.                 pp->total += SC_COUP;
  1571.                 pp->hand_tot += SC_COUP;
  1572.                 pp->coupscore += SC_COUP;
  1573.             }
  1574.         }
  1575.         /*
  1576.          * if not coup, must pick first
  1577.          */
  1578.         else if (pp->hand[0] == C_INIT && Topcard > Deck)
  1579.             goto mustpick;
  1580.         pp->safety[card - S_CONV] = S_PLAYED;
  1581.         pp->total += SC_SAFETY;
  1582.         pp->hand_tot += SC_SAFETY;
  1583.         if ((pp->safescore += SC_SAFETY) == NUM_SAFE * SC_SAFETY) {
  1584.             pp->total += SC_ALL_SAFE;
  1585.             pp->hand_tot += SC_ALL_SAFE;
  1586.         }
  1587.         if (card == C_RIGHT_WAY) {
  1588.             if (pp->speed == C_LIMIT)
  1589.                 pp->speed = C_INIT;
  1590.             if (pp->battle == C_STOP || pp->battle == C_INIT) {
  1591.                 pp->can_go = TRUE;
  1592.                 pp->battle = C_INIT;
  1593.             }
  1594.             if (!pp->can_go && isrepair(pp->battle))
  1595.                 pp->can_go = TRUE;
  1596.         }
  1597.         Next = -1;
  1598.         break;
  1599.  
  1600.       case C_INIT:
  1601.         error("no card there");
  1602.         Next = -1;
  1603.         break;
  1604.     }
  1605.     if (pp == &Player[PLAYER])
  1606.         account(card);
  1607.     pp->hand[Card_no] = C_INIT;
  1608.     Next = (Next == -1 ? FALSE : TRUE);
  1609.     return TRUE;
  1610. }
  1611.  
  1612. getmove()
  1613. {
  1614.     reg char    c, *sp;
  1615.     static char    moveprompt[] = ">>:Move:";
  1616. #ifdef EXTRAP
  1617.     static bool    last_ex = FALSE;    /* set if last command was E */
  1618.  
  1619.     if (last_ex) {
  1620.         undoex();
  1621.         prboard();
  1622.         last_ex = FALSE;
  1623.     }
  1624. #endif
  1625.     for (;;) {
  1626.         stand(MOVE_Y, MOVE_X, moveprompt);
  1627.         clrtoeol();
  1628.         move(MOVE_Y, MOVE_X + sizeof moveprompt);
  1629.         leaveok(Board, FALSE);
  1630.         refresh();
  1631.         while ((c = getch()) == killchar() || c == erasechar())
  1632.             continue;
  1633.         if (islower(c))
  1634.             c = toupper(c);
  1635.         if (isprint(c) && !isspace(c)) {
  1636.             addch(c);
  1637.             refresh();
  1638.         }
  1639.         switch (c)
  1640.         {
  1641.           case 'P':        /* Pick */
  1642.             Movetype = M_DRAW;
  1643.             goto ret;
  1644.           case 'U':        /* Use Card */
  1645.           case 'D':        /* Discard Card */
  1646.             if ((Card_no = getcard()) < 0)
  1647.                 break;
  1648.             Movetype = (c == 'U' ? M_PLAY : M_DISCARD);
  1649.             goto ret;
  1650.           case 'O':        /* Order */
  1651.             Order = !Order;
  1652.             Movetype = M_ORDER;
  1653.             goto ret;
  1654.           case 'Q':        /* Quit */
  1655.             rub();        /* Same as a rubout */
  1656.             break;
  1657.           case 'W':        /* Window toggle */
  1658.             Window = nextwin(Window);
  1659.             newscore();
  1660.             prscore(TRUE);
  1661.             wrefresh(Score);
  1662.             break;
  1663.           case 'R':        /* Redraw screen */
  1664.           case CTRL('L'):
  1665.             clearok(curscr, TRUE);
  1666.             newboard();
  1667.             prboard();
  1668.             break;
  1669.           case 'S':        /* Save game */
  1670.             On_exit = FALSE;
  1671.             save();
  1672.             break;
  1673.           case 'E':        /* Extrapolate */
  1674. #ifdef EXTRAP
  1675.             if (last_ex)
  1676.                 break;
  1677.             Finished = TRUE;
  1678.             if (Window != W_FULL)
  1679.                 newscore();
  1680.             prscore(FALSE);
  1681.             wrefresh(Score);
  1682.             last_ex = TRUE;
  1683.             Finished = FALSE;
  1684. #else
  1685.             error("%c: command not implemented", c);
  1686. #endif
  1687.             break;
  1688.           case '\r':        /* Ignore RETURNs and    */
  1689.           case '\n':        /* Line Feeds        */
  1690.           case ' ':        /* and Spaces        */
  1691.             break;
  1692.           case 'Z':        /* Debug code */
  1693.             if (geteuid() == ARNOLD) {
  1694.                 if (!Debug && outf == NULL) {
  1695.                     char    buf[40];
  1696. over:
  1697.                     mvaddstr(MOVE_Y, MOVE_X, "file: ");
  1698.                     clrtoeol();
  1699.                     leaveok(Board, FALSE);
  1700.                     refresh();
  1701.                     sp = buf;
  1702.                     while ((*sp = getch()) != '\n') {
  1703.                         if (*sp == killchar())
  1704.                             goto over;
  1705.                         else if (*sp == erasechar()) {
  1706.                             if (--sp < buf)
  1707.                                 sp = buf;
  1708.                             else {
  1709.                                 addch('\b');
  1710.                                 if (*sp < ' ')
  1711.                                     addch('\b');
  1712.                                 clrtoeol();
  1713.                             }
  1714.                         }
  1715.                         else
  1716.                             addstr(unctrl(*sp++));
  1717.                         refresh();
  1718.                     }
  1719.                     *sp = '\0';
  1720.                     leaveok(Board, TRUE);
  1721.                     if ((outf = fopen(buf, "w")) == NULL)
  1722.                         perror(buf);
  1723.                     setbuf(outf, 0);
  1724.                 }
  1725.                 Debug = !Debug;
  1726.                 break;
  1727.             }
  1728.             /* FALLTHROUGH */
  1729.           default:
  1730.             error("unknown command: %s", unctrl(c));
  1731.             break;
  1732.         }
  1733.     }
  1734. ret:
  1735.     leaveok(Board, TRUE);
  1736. }
  1737. X/*
  1738.  * return whether or not the player has picked
  1739.  */
  1740. haspicked(pp)
  1741. reg PLAY    *pp; {
  1742.  
  1743.     reg int    card;
  1744.  
  1745.     if (Topcard <= Deck)
  1746.         return TRUE;
  1747.     switch (pp->hand[Card_no]) {
  1748.       case C_GAS_SAFE:    case C_SPARE_SAFE:
  1749.       case C_DRIVE_SAFE:    case C_RIGHT_WAY:
  1750.         card = 1;
  1751.         break;
  1752.       default:
  1753.         card = 0;
  1754.         break;
  1755.     }
  1756.     return (pp->hand[card] != C_INIT);
  1757. }
  1758.  
  1759. account(card)
  1760. reg CARD    card; {
  1761.  
  1762.     reg CARD    oppos;
  1763.  
  1764.     if (card == C_INIT)
  1765.         return;
  1766.     ++Numseen[card];
  1767.     if (Play == COMP)
  1768.         switch (card) {
  1769.           case C_GAS_SAFE:
  1770.           case C_SPARE_SAFE:
  1771.           case C_DRIVE_SAFE:
  1772.             oppos = opposite(card);
  1773.             Numgos += Numcards[oppos] - Numseen[oppos];
  1774.             break;
  1775.           case C_CRASH:
  1776.           case C_FLAT:
  1777.           case C_EMPTY:
  1778.           case C_STOP:
  1779.             Numgos++;
  1780.             break;
  1781.         }
  1782. }
  1783.  
  1784. sort(hand)
  1785. reg CARD    *hand;
  1786. {
  1787.     reg CARD    *cp, *tp;
  1788.     reg int        j;
  1789.     reg CARD    temp;
  1790.  
  1791.     cp = hand;
  1792.     hand += HAND_SZ;
  1793.     for ( ; cp < &hand[-1]; cp++)
  1794.         for (tp = cp + 1; tp < hand; tp++)
  1795.             if (*cp > *tp) {
  1796.                 temp = *cp;
  1797.                 *cp = *tp;
  1798.                 *tp = temp;
  1799.             }
  1800. }
  1801. //go.sysin dd *
  1802. echo 'x - =test/=mille/print.c'
  1803. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/print.c
  1804. # include    "mille.h"
  1805.  
  1806. # define    COMP_STRT    20
  1807. # define    CARD_STRT    2
  1808.  
  1809. prboard() {
  1810.  
  1811.     reg PLAY    *pp;
  1812.     reg int        i, j, k, temp;
  1813.  
  1814.     for (k = 0; k < 2; k++) {
  1815.         pp = &Player[k];
  1816.         temp = k * COMP_STRT + CARD_STRT;
  1817.         for (i = 0; i < NUM_SAFE; i++)
  1818.             if (pp->safety[i] == S_PLAYED) {
  1819.                 mvaddstr(i, temp, C_name[i + S_CONV]);
  1820.                 if (pp->coups[i])
  1821.                     mvaddch(i, temp - CARD_STRT, '*');
  1822.             }
  1823.         mvprintw(14, temp, C_fmt, C_name[pp->battle]);
  1824.         mvprintw(16, temp, C_fmt, C_name[pp->speed]);
  1825.         for (i = C_25; i <= C_200; ) {
  1826.             reg char    *name;
  1827.             reg int        end;
  1828.  
  1829.             name = C_name[i];
  1830.             temp = k * 40;
  1831.             end = pp->nummiles[i++];
  1832.             for (j = 0; j < end; j++)
  1833.                 mvwaddstr(Miles, i, (j << 2) + temp, name);
  1834.         }
  1835.     }
  1836.     prscore(TRUE);
  1837.     temp = CARD_STRT;
  1838.     pp = &Player[PLAYER];
  1839.     for (i = 0; i < HAND_SZ; i++)
  1840.         mvprintw(i + 6, temp, C_fmt, C_name[pp->hand[i]]);
  1841.     mvprintw(6, COMP_STRT + CARD_STRT, "%2d", Topcard - Deck);
  1842.     mvprintw(8, COMP_STRT + CARD_STRT, C_fmt, C_name[Discard]);
  1843.     if (End == 1000) {
  1844.         static char    ext[] = "Extension";
  1845.  
  1846.         stand(EXT_Y, EXT_X, ext);
  1847.     }
  1848.     wrefresh(Board);
  1849.     wrefresh(Miles);
  1850.     wrefresh(Score);
  1851. }
  1852.  
  1853. X/*
  1854.  *    Put str at (y,x) in standout mode
  1855.  */
  1856. stand(y, x, str)
  1857. reg int        y, x;
  1858. reg char    *str; {
  1859.  
  1860.     standout();
  1861.     mvaddstr(y, x, str);
  1862.     standend();
  1863.     return TRUE;
  1864. }
  1865.  
  1866. prscore(for_real)
  1867. reg bool    for_real; {
  1868.  
  1869.     reg PLAY    *pp;
  1870.     reg int        x;
  1871.     reg char    *Score_fmt = "%4d";
  1872.  
  1873.     stdscr = Score;
  1874.     for (pp = Player; pp < &Player[2]; pp++) {
  1875.         x = (pp - Player) * 6 + 21;
  1876.         mvprintw(1, x, Score_fmt, pp->mileage);
  1877.         mvprintw(2, x, Score_fmt, pp->safescore);
  1878.         if (pp->safescore == 400)
  1879.             mvaddstr(3, x + 1, "300");
  1880.         else
  1881.             mvaddch(3, x + 3, '0');
  1882.         mvprintw(4, x, Score_fmt, pp->coupscore);
  1883.         if (Window == W_FULL || Finished) {
  1884. #ifdef EXTRAP
  1885.             if (for_real)
  1886.                 finalscore(pp);
  1887.             else
  1888.                 extrapolate(pp);
  1889. #else
  1890.             finalscore(pp);
  1891. #endif
  1892.             mvprintw(11, x, Score_fmt, pp->hand_tot);
  1893.             mvprintw(13, x, Score_fmt, pp->total);
  1894.             mvprintw(14, x, Score_fmt, pp->games);
  1895.         }
  1896.         else {
  1897.             mvprintw(6, x, Score_fmt, pp->hand_tot);
  1898.             mvprintw(8, x, Score_fmt, pp->total);
  1899.             mvprintw(9, x, Score_fmt, pp->games);
  1900.         }
  1901.     }
  1902.     stdscr = Board;
  1903. }
  1904. //go.sysin dd *
  1905. echo 'x - =test/=mille/roll.c'
  1906. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/roll.c
  1907. X/*
  1908.  *    This routine rolls ndie nside-sided dice.
  1909.  */
  1910.  
  1911. # define    reg    register
  1912.  
  1913. # ifndef vax
  1914. # define    MAXRAND    32767L
  1915.  
  1916. roll(ndie, nsides)
  1917. int    ndie, nsides; {
  1918.  
  1919.     reg long    tot;
  1920.     reg unsigned    n, r;
  1921.  
  1922.     tot = 0;
  1923.     n = ndie;
  1924.     while (n--)
  1925.         tot += rand();
  1926.     return (int) ((tot * (long) nsides) / ((long) MAXRAND + 1)) + ndie;
  1927. }
  1928.  
  1929. # else
  1930.  
  1931. roll(ndie, nsides)
  1932. reg int    ndie, nsides; {
  1933.  
  1934.     reg int        tot, r;
  1935.     reg double    num_sides;
  1936.  
  1937.     num_sides = nsides;
  1938.     tot = 0;
  1939.     while (ndie--)
  1940.         tot += (r = rand()) * (num_sides / 017777777777) + 1;
  1941.     return tot;
  1942. }
  1943. # endif
  1944. //go.sysin dd *
  1945. echo 'x - =test/=mille/save.c'
  1946. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/save.c
  1947. #include    "mille.h"
  1948. #include    "unctrl.h"
  1949. #include    <sys/types.h>
  1950. #include    <sys/stat.h>
  1951. #include    <time.h>
  1952.  
  1953. typedef    struct stat    STAT;
  1954. typedef    struct tm    TIME;
  1955.  
  1956. char    *ctime();
  1957.  
  1958. int    read(), write();
  1959.  
  1960. X/*
  1961.  *    This routine saves the current game for use at a later date
  1962.  */
  1963. extern int    errno;
  1964. extern char    *sys_errlist[];
  1965.  
  1966. save() {
  1967.  
  1968.     reg char    *sp;
  1969.     reg int        outf;
  1970.     reg TIME    *tp;
  1971.     char        buf[80];
  1972.     TIME        tme;
  1973.     STAT        junk;
  1974.  
  1975.     tp = &tme;
  1976.     if (Fromfile && getyn("Same file? "))
  1977.         strcpy(buf, Fromfile);
  1978.     else {
  1979. over:
  1980.         mvaddstr(MOVE_Y, MOVE_X, "file: ");
  1981.         clrtoeol();
  1982.         leaveok(Board, FALSE);
  1983.         refresh();
  1984. #ifdef UNDEFINED
  1985.         sp = buf;
  1986.         while ((*sp = getch()) != '\n') {
  1987.             if (*sp == killchar())
  1988.                 goto over;
  1989.             else if (*sp == erasechar()) {
  1990.                 if (--sp < buf)
  1991.                     sp = buf;
  1992.                 else {
  1993.                     addch('\b');
  1994.                     /*
  1995.                      * if the previous char was a control
  1996.                      * char, cover up two characters.
  1997.                      */
  1998.                     if (*sp < ' ')
  1999.                         addch('\b');
  2000.                     clrtoeol();
  2001.                 }
  2002.             }
  2003.             else
  2004.                 addstr(unctrl(*sp++));
  2005.             refresh();
  2006.         }
  2007.         *sp = '\0';
  2008. #else
  2009.         getstr(buf);
  2010. #endif
  2011.         leaveok(Board, TRUE);
  2012.     }
  2013.  
  2014.     /*
  2015.      * check for existing files, and confirm overwrite if needed
  2016.      */
  2017.  
  2018.     if (sp == buf || (!Fromfile && stat(buf, &junk) > -1
  2019.         && getyn("Overwrite File? ") == FALSE))
  2020.         return FALSE;
  2021.  
  2022.     if ((outf = creat(buf, 0644)) < 0) {
  2023.         error(sys_errlist[errno]);
  2024.         return FALSE;
  2025.     }
  2026.     mvwaddstr(Score, ERR_Y, ERR_X, buf);
  2027.     wrefresh(Score);
  2028.     time(tp);            /* get current time        */
  2029.     strcpy(buf, ctime(tp));
  2030.     for (sp = buf; *sp != '\n'; sp++)
  2031.         continue;
  2032.     *sp = '\0';
  2033.     varpush(outf, write);
  2034.     close(outf);
  2035.     wprintw(Score, " [%s]", buf);
  2036.     wclrtoeol(Score);
  2037.     wrefresh(Score);
  2038.     return TRUE;
  2039. }
  2040.  
  2041. X/*
  2042.  *    This does the actual restoring.  It returns TRUE if the
  2043.  * backup was made on exiting, in which case certain things must
  2044.  * be cleaned up before the game starts.
  2045.  */
  2046. rest_f(file)
  2047. reg char    *file; {
  2048.  
  2049.     reg char    *sp;
  2050.     reg int        inf;
  2051.     char        buf[80];
  2052.     STAT        sbuf;
  2053.  
  2054.     if ((inf = open(file, 0)) < 0) {
  2055.         perror(file);
  2056.         exit(1);
  2057.     }
  2058.     if (fstat(inf, &sbuf) < 0) {        /* get file stats    */
  2059.         perror(file);
  2060.         exit(1);
  2061.     }
  2062.     varpush(inf, read);
  2063.     close(inf);
  2064.     strcpy(buf, ctime(&sbuf.st_mtime));
  2065.     for (sp = buf; *sp != '\n'; sp++)
  2066.         continue;
  2067.     *sp = '\0';
  2068.     /*
  2069.      * initialize some necessary values
  2070.      */
  2071.     sprintf(Initstr, "%s [%s]\n", file, buf);
  2072.     Fromfile = file;
  2073.     return !On_exit;
  2074. }
  2075. //go.sysin dd *
  2076. echo 'x - =test/=mille/table.c'
  2077. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/table.c
  2078. # define    DEBUG
  2079. # include    "mille.h"
  2080.  
  2081. main() {
  2082.  
  2083.     reg int    i, j, count;
  2084.  
  2085.     printf("   %16s -> %5s %5s %4s %s\n", "Card", "cards", "count", "need", "opposite");
  2086.     for (i = 0; i < NUM_CARDS - 1; i++) {
  2087.         for (j = 0, count = 0; j < DECK_SZ; j++)
  2088.             if (Deck[j] == i)
  2089.                 count++;
  2090.         printf("%2d %16s -> %5d %5d %4d %s\n", i, C_name[i], Numcards[i], count, Numneed[i], C_name[opposite(i)]);
  2091.     }
  2092. }
  2093. //go.sysin dd *
  2094. echo 'x - =test/=mille/types.c'
  2095. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/types.c
  2096. # include    "mille.h"
  2097.  
  2098. isrepair(card)
  2099. reg CARD    card; {
  2100.  
  2101.     return card == C_GAS || card == C_SPARE || card == C_REPAIRS || card == C_INIT;
  2102. }
  2103.  
  2104. safety(card)
  2105. reg CARD    card; {
  2106.  
  2107.     switch (card) {
  2108.       case C_EMPTY:
  2109.       case C_GAS:
  2110.       case C_GAS_SAFE:
  2111.         return C_GAS_SAFE;
  2112.       case C_FLAT:
  2113.       case C_SPARE:
  2114.       case C_SPARE_SAFE:
  2115.         return C_SPARE_SAFE;
  2116.       case C_CRASH:
  2117.       case C_REPAIRS:
  2118.       case C_DRIVE_SAFE:
  2119.         return C_DRIVE_SAFE;
  2120.       case C_GO:
  2121.       case C_STOP:
  2122.       case C_RIGHT_WAY:
  2123.       case C_LIMIT:
  2124.       case C_END_LIMIT:
  2125.         return C_RIGHT_WAY;
  2126.     }
  2127.     /* NOTREACHED */
  2128. }
  2129. //go.sysin dd *
  2130. echo 'x - =test/=mille/unctrl.h'
  2131. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/unctrl.h
  2132. # include    <stdio.h>
  2133. # define    unctrl(ch)    (_unctrl[ch])
  2134.  
  2135. extern char    *_unctrl[];
  2136. //go.sysin dd *
  2137. echo 'x - =test/=mille/varpush.c'
  2138. sed 's/^X//' <<'//go.sysin dd *' >=test/=mille/varpush.c
  2139. # include    "mille.h"
  2140.  
  2141. int    read(), write();
  2142.  
  2143. X/*
  2144.  *    push variables around via the routine func() on the file
  2145.  * channel file.  func() is either read or write.
  2146.  */
  2147. varpush(file, func)
  2148. reg int    file;
  2149. reg int    (*func)(); {
  2150.  
  2151.     int    temp;
  2152.  
  2153.     (*func)(file, &Debug, sizeof Debug);
  2154.     (*func)(file, &Finished, sizeof Finished);
  2155.     (*func)(file, &Order, sizeof Order);
  2156.     (*func)(file, &End, sizeof End);
  2157.     (*func)(file, &On_exit, sizeof On_exit);
  2158.     (*func)(file, &Handstart, sizeof Handstart);
  2159.     (*func)(file, &Numgos, sizeof Numgos);
  2160.     (*func)(file,  Numseen, sizeof Numseen);
  2161.     (*func)(file, &Play, sizeof Play);
  2162.     (*func)(file, &Window, sizeof Window);
  2163.     (*func)(file,  Deck, sizeof Deck);
  2164.     (*func)(file, &Discard, sizeof Discard);
  2165.     (*func)(file,  Player, sizeof Player);
  2166.     if (func == read) {
  2167.         read(file, &temp, sizeof temp);
  2168.         Topcard = &Deck[temp];
  2169.         if (Debug) {
  2170.             char    buf[80];
  2171. over:
  2172.             printf("Debug file:");
  2173.             gets(buf);
  2174.             if ((outf = fopen(buf, "w")) == NULL) {
  2175.                 perror(buf);
  2176.                 goto over;
  2177.             }
  2178.             if (strcmp(buf, "/dev/null") != 0)
  2179.                 setbuf(outf, 0);
  2180.         }
  2181.     }
  2182.     else {
  2183.         temp = Topcard - Deck;
  2184.         write(file, &temp, sizeof temp);
  2185.     }
  2186. }
  2187. //go.sysin dd *
  2188. exit
  2189.