home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume36 / ldb / part02 < prev    next >
Encoding:
Text File  |  1993-04-10  |  50.9 KB  |  1,488 lines

  1. Newsgroups: comp.sources.misc
  2. From: ross@teserv.den.mmc.com (Perry R. Ross)
  3. Subject: v36i099:  ldb - Play backgammon by e-mail, v1.3, Part02/12
  4. Message-ID: <1993Apr11.232922.17861@sparky.imd.sterling.com>
  5. X-Md4-Signature: 25a95ccd33bb6f81f016d287dc2bf11f
  6. Date: Sun, 11 Apr 1993 23:29:22 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: ross@teserv.den.mmc.com (Perry R. Ross)
  10. Posting-number: Volume 36, Issue 99
  11. Archive-name: ldb/part02
  12. Environment: UNIX, C, VMS, VAXC, CURSES, 32BIT
  13. Supersedes: ldb: Volume 28, Issue 93-97
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 2 (of 12)."
  22. # Contents:  control.c dostats.c ldbstarter move.c r_xrand.c vars.c
  23. # Wrapped by ross@teserv.den.mmc.com on Tue Apr  6 14:52:17 1993
  24. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  25. if test -f 'control.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'control.c'\"
  27. else
  28. echo shar: Extracting \"'control.c'\" \(9911 characters\)
  29. sed "s/^X//" >'control.c' <<'END_OF_FILE'
  30. X/*    control.c        9/12/91
  31. X *
  32. X * Copyright 1991  Perry R. Ross
  33. X *
  34. X * Permission to use, copy, modify, and distribute this software and its
  35. X * documentation without fee is hereby granted, subject to the restrictions
  36. X * detailed in the README file, which is included here by reference.
  37. X * Any other use requires written permission from the author.  This software
  38. X * is distributed "as is" without any warranty, including any implied
  39. X * warranties of merchantability or fitness for a particular purpose.
  40. X * The author shall not be liable for any damages resulting from the
  41. X * use of this software.  By using this software, the user agrees
  42. X * to these terms.
  43. X */
  44. X
  45. X#include "ldb.h"
  46. X
  47. X/*----------------------------------------------------------------------
  48. X *    control -- control a game
  49. X *
  50. X * This function is called to process the -control command line option.
  51. X * It currently allows the following:
  52. X *    -    The board may be inverted.  The points are still numbered the
  53. X *    same, the board is merely drawn upside down.  This can help users
  54. X *    who are playing a number of games simultaneously by allowing him
  55. X *    to make all of his games move in the same direction on the screen.
  56. X *    - The last packet sent may be resent.  This is useful when moves
  57. X *    are lost in the mail, or if players forget whose turn it is.
  58. X *    Ldb rejects packets that have already been received, so both
  59. X *    players may simply resend their last packet, and ldb will display
  60. X *    the board to the player who is supposed to move.
  61. X *----------------------------------------------------------------------
  62. X */
  63. X
  64. Xcontrol()
  65. X{
  66. Xregister struct game *g;
  67. Xstatic char *m[] = {"Invert","Resend","Get Resend","Screen Dump","Delete Game",
  68. X            "Next Game","Quit",NULL};
  69. Xchar buf[60], c, done;
  70. Xint mod;
  71. Xchar pm = '\0';
  72. Xstatic char oldmsg[] = "Your opponent's ldb does not support resend requests.";
  73. Xstatic char gmover[] = "This game is over -- you cannot request a resend.";
  74. X
  75. Xif (ghead == NULL) {
  76. X    printf("You don't have any games in progress.\n");
  77. X    printf("Use the -start option to start one.\n");
  78. X    usage(0);
  79. X    ldbexit(STAT_ABORT);
  80. X    }
  81. Xmod = 0;                /* init to no mods */
  82. Xrc.chkpt = "no";            /* disable checkpoint in sendpkt */
  83. XFeInitialize();                /* initialize front end */
  84. XFeDrawScreen();                /* draw board outline */
  85. Xdone = 0;
  86. Xfor (g = ghead; (done < 2) && (g != NULL); g = g->next) {/* for all games */
  87. X    g->curbd = BD_CUR;        /* make sure we draw the current bd */
  88. X    FeDrawGame(g);
  89. X    FeDrawMenu(m);
  90. X    sprintf(buf,"Current state: %s",states[g->state]);
  91. X    FeMessage(buf);
  92. X    done = 0;
  93. X    GameState = STATE_CONTROL;
  94. X    while (! done) {
  95. X        c = FeMenu(m,0,0," \n\r",pm);
  96. X        pm = c;
  97. X        switch (c) {
  98. X        case 'I':            /* invert board */
  99. X            g->flags ^= F_INVERT;    /* toggle invert bit */
  100. X            FeDrawGame(g);        /* redraw the screen */
  101. X            mod++;            /* games have been modified */
  102. X            break;
  103. X        case 'R':            /* resend last packet */
  104. X            if ((g->state>=OPSTATES)&&(g->state!=ST_GAMEOVER)) {
  105. X                FeMessage("Can't resend -- it is your move.");
  106. X                break;
  107. X                }
  108. X            resendpkt(g);
  109. X            FeMessage("Last packet re-sent.");
  110. X            break;
  111. X        case 'G':
  112. X            if (g->state == ST_GAMEOVER) {
  113. X                FeMessage(gmover);
  114. X                break;
  115. X                }
  116. X            if (g->opver < 110) {
  117. X                FeMessage(oldmsg);
  118. X                break;
  119. X                }
  120. X            sendpkt(g,RESEND);
  121. X            FeMessage("Resend requested.");
  122. X            break;
  123. X        case 'S':            /* dump screen */
  124. X            FeMessage(buf);        /* restore state msg */
  125. X            FeDumpScreen("ldb_screen.dmp");    /* do the dump */
  126. X            FeMessage("Screen dumped to ldb_screen.dmp");
  127. X            break;
  128. X        case 'D':            /* delete game */
  129. X            mod++;            /* games have been modified */
  130. X            if (g->flags & F_DELETE) {    /* undelete */
  131. X                g->flags &= ~F_DELETE;
  132. X                FeMessage("Game undeleted.");
  133. X                }
  134. X            else {
  135. X                g->flags |= F_DELETE;    /* delete */
  136. X                FeMessage(
  137. X                 "Game deleted -- press D again to undelete.");
  138. X                }
  139. X            break;
  140. X        case 'Q':            /* exit ldb */
  141. X            done = 2;        /* 2 means Really done */
  142. X            break;
  143. X        case ' ':
  144. X        case '\n':
  145. X        case '\r':
  146. X            FeOnMenuItem(m,'N');    /* highlight Next Game item */
  147. X            pm = 'N';        /* remember to unhighlight */
  148. X            /* Fall through */
  149. X        case 'N':
  150. X            done = 1;    /* 1 means just done with this game */
  151. X            break;        /* go to next game */
  152. X            }
  153. X        }
  154. X    }
  155. XFeFinishSession();
  156. Xwhile (mod) {
  157. X    printf("Save changes? [yn]: ");
  158. X    fflush(stdout);
  159. X    if ( ( (c = getchar()) == 'y') || (c == 'Y') ) {
  160. X        writegames(rc.gfile,rc.gbackup,rc.pfile);
  161. X        break;
  162. X        }
  163. X    if ( (c == 'n') || (c == 'N') ) {
  164. X        printf("Changes discarded.\n");
  165. X        break;
  166. X        }
  167. X    if ( (c != '\n') && (c != EOF) )
  168. X        while ( ( (c = getchar()) != '\n') && (c != EOF) );
  169. X    printf("Please respond with y or n.\n");
  170. X    }
  171. X}
  172. X
  173. X
  174. X/*----------------------------------------------------------------------
  175. X *    recons -- reconstruct games from opponent's .ldbdata
  176. X *
  177. X * This function allows a game to be reconstructed when the .ldbdata
  178. X * file has been irretrievably lost.  The opponent merely mails
  179. X * his .ldbdata file, and we scan it for all the important information.
  180. X * Games that are in the OPSTART or GAMEOVER states cannot be reconstructed
  181. X * due to the lack of adequate information, but these games either have
  182. X * not started or are already over.  If the game is in state OPSTART
  183. X * because the next game of a match is being started, the match can
  184. X * be rescued by starting a new match that plays up to the number of
  185. X * points remaining in the old match.
  186. X *
  187. X * Before sending the .ldbdata file, your opponent should incorporate
  188. X * any moves you sent before you lost your file.  If your move is lost
  189. X * as well, it may be necessary for you to replay your last move, with
  190. X * a new roll.  This should not be considered cheating, as it is unavoidable.
  191. X * Alternatively, if you remember your last roll, you could plug the rolls
  192. X * into your .ldbdata after the reconstruct.
  193. X *
  194. X * You will have to edit the mail header off the file before feeding it
  195. X * to -reconstruct.  The first line of the file MUST be the first line
  196. X * of the data file.
  197. X *
  198. X * Because data fields are frequently added to data files between
  199. X * revisions, -reconstruct is only guaranteed to work when you
  200. X * are using the same ldb revision as your opponent.
  201. X *
  202. X * If you started the game being reconstructed, and you used the
  203. X * -myaddr argument when you started it, you will need to use
  204. X * the -myaddr argument when you reconstruct it.
  205. X *----------------------------------------------------------------------
  206. X */
  207. X
  208. Xrecons(file)
  209. Xchar *file;
  210. X{
  211. XFILE *fp;
  212. Xchar c;
  213. Xint i, j;
  214. Xstruct mv m;
  215. Xstruct game *g;
  216. Xstruct people *p;
  217. Xchar *s;
  218. Xchar buf[80];
  219. X
  220. Xif ( (fp = fopen(file,"r")) == NULL) {
  221. X    fprintf(stderr,"ERROR: cannot open %s for reconstruct\n",file);
  222. X    ldbexit(STAT_ABORT);
  223. X    }
  224. Xg = addgame();            /* get a game structure */
  225. Xwhile ( (c = getc(fp)) != EOF) {
  226. X    ungetc(c,fp);            /* put char back */
  227. X    nvscan(fp,nv_gfile,g);
  228. X    if (strcmp(g->opaddr,rc.myaddr))    /* this game wasn't with me */
  229. X        continue;
  230. X    if ( (g->state == ST_OPSTART) || (g->state == ST_GAMEOVER) )
  231. X        continue;        /* can't handle these */
  232. X    printf("\n--- Reconstruct found game %s ---\n",g->gameid);
  233. X    s = g->gameid;            /* copy out gameid */
  234. X    g->gameid = "";            /* temporarily delete gameid field */
  235. X    if (findgame(s) != NULL) {
  236. X        printf("ERROR: This game already exists -- ignoring.\n");
  237. X        continue;
  238. X        }
  239. X    g->gameid = s;            /* restore gameid field */
  240. X    printf("Enter opponent address or alias: ");
  241. X    if (fgets(buf,sizeof(buf),stdin) == NULL) {
  242. X        printf("\n--- Reconstruct deleting game %s ---\n",g->gameid);
  243. X        continue;
  244. X        }
  245. X    buf[strlen(buf)-1] = '\0';        /* clobber newline */
  246. X    if ( (p = findppl(buf,P_ADDR|P_ALIAS)) == NULL) {/* not in ppl file */
  247. X        g->opaddr = save(buf);        /* save address in game */
  248. X        printf("Enter opponent name: ");
  249. X        if (fgets(buf,sizeof(buf),stdin) == NULL) {
  250. X            printf("\n--- Reconstruct deleting game %s ---\n",
  251. X                g->gameid);
  252. X            continue;
  253. X            }
  254. X        buf[strlen(buf)-1] = '\0';    /* clobber newline */
  255. X        g->opname = save(buf);        /* save opponent's name */
  256. X        newppl(g);        /* generate a new people rec */
  257. X        }
  258. X    else {                /* it was an alias */
  259. X        g->opname = save(p->name);    /* copy name from people rec */
  260. X        g->opaddr = save(p->addr);    /* address too */
  261. X        g->ppl = p;            /* store people pointer */
  262. X        }
  263. X    g->dispmsg = NULL;
  264. X    g->myaddr = save(rc.myaddr);
  265. X    for (i = 0; i < 4; i++) {
  266. X        g->blot[i] = 0;        /* clear blot array */
  267. X        m = g->mvs[i];        /* switch mvs and opmvs fields */
  268. X        g->mvs[i] = g->opmvs[i];
  269. X        g->opmvs[i] = m;
  270. X        }
  271. X    for (i = 0; i < 6; i++) {
  272. X        j = g->rolls[i];    /* switch rolls and oprolls */
  273. X        g->rolls[i] = g->oprolls[i];
  274. X        g->oprolls[i] = j;
  275. X        j = g->doubles[i];    /* switch doubles and opdoubles */
  276. X        g->doubles[i] = g->opdoubles[i];
  277. X        g->opdoubles[i] = j;
  278. X        }
  279. X    i = g->mydir;            /* switch mydir and opdir */
  280. X    g->mydir = g->opdir;
  281. X    g->opdir = i;
  282. X    i = g->mycolor;            /* switch mycolor and opcolor */
  283. X    g->mycolor = g->opcolor;
  284. X    g->opcolor = i;
  285. X    s = g->mycmt;
  286. X    g->mycmt = g->opcmt;
  287. X    g->opcmt = s;
  288. X    s = g->mycmt2;
  289. X    g->mycmt2 = g->opcmt2;
  290. X    g->opcmt2 = s;
  291. X    i = g->mcurrent[WHO_ME];        /* switch match scores */
  292. X    g->mcurrent[WHO_ME] = g->mcurrent[WHO_OPP];
  293. X    g->mcurrent[WHO_OPP] = i;
  294. X    copyboard(g->mybd,g->opbd);    /* my before bd == op's after bd */
  295. X    if (g->state < OPSTATES) {    /* I'm sending next */
  296. X        g->seq++;    /* set seq# to what opp expects in next pkt */
  297. X        copyboard(g->board,g->mybd);    /* my after bd == cur board */
  298. X        }
  299. X    else {                /* he's sending next */
  300. X        g->seq--;    /* set seq# to what we're expecting */
  301. X        copyboard(g->mybd,g->board);    /* erase his moves */
  302. X        }
  303. X    g->lastop = START;        /* has to be set to something */
  304. X    switch (g->state) {        /* invert state */
  305. X    case ST_OPTURN:
  306. X        g->state = ST_MYTURN;    /* it's my turn */
  307. X        break;
  308. X    case ST_OPACCEPT:
  309. X        g->state = ST_MYACCEPT;    /* waiting for me to accept double */
  310. X        break;
  311. X    case ST_MYTURN:
  312. X    case ST_MYMOVE:
  313. X        g->state = ST_OPTURN;    /* waiting for op to move */
  314. X        break;
  315. X    case ST_MYACCEPT:
  316. X        g->state = ST_OPACCEPT;    /* waiting for op to accept double */
  317. X        break;
  318. X        }
  319. X    printf("--- Reconstructed game %s ---\n",g->gameid);
  320. X    g = addgame();        /* get new buffer to read into */
  321. X    }
  322. Xdeletegame(g);            /* get rid of buffer */
  323. Xwritegames(rc.gfile,rc.gbackup,rc.pfile);    /* save new games */
  324. X}
  325. END_OF_FILE
  326. if test 9911 -ne `wc -c <'control.c'`; then
  327.     echo shar: \"'control.c'\" unpacked with wrong size!
  328. fi
  329. # end of 'control.c'
  330. fi
  331. if test -f 'dostats.c' -a "${1}" != "-c" ; then 
  332.   echo shar: Will not clobber existing file \"'dostats.c'\"
  333. else
  334. echo shar: Extracting \"'dostats.c'\" \(6126 characters\)
  335. sed "s/^X//" >'dostats.c' <<'END_OF_FILE'
  336. X/* dostats.c        4/20/92
  337. X *
  338. X * Copyright 1992  Earle F. Ake
  339. X *
  340. X * Permission to use, copy, modify, and distribute this software and its
  341. X * documentation without fee is hereby granted, subject to the restrictions
  342. X * detailed in the README file, which is included here by reference.
  343. X * Any other use requires written permission from the author.  This software
  344. X * is distributed "as is" without any warranty, including any implied
  345. X * warranties of merchantability or fitness for a particular purpose.
  346. X * The author shall not be liable for any damages resulting from the
  347. X * use of this software.  By using this software, the user agrees
  348. X * to these terms.
  349. X *
  350. X * Original coding by Earle F. Ake <ake@dayton.saic.com> - 20 April 1992.
  351. X *
  352. X */
  353. X
  354. X#include "ldb.h"
  355. X
  356. X/*----------------------------------------------------------------------
  357. X *    dostats -- display online statistics of dice rolls
  358. X *
  359. X * This function creates a new curses window and displays dice statistics
  360. X * to the user.  The user then presses any key to return to the game.
  361. X *----------------------------------------------------------------------
  362. X */
  363. X
  364. Xdostats(g)
  365. Xstruct game *g;
  366. X{
  367. XWINDOW *statwin;
  368. Xint row, i, col, rolls, dice;
  369. Xint mypip, oppip;
  370. Xchar temp[80];
  371. Xchar c;
  372. Xint Total = 0, OpTotal = 0;
  373. X
  374. Xstatwin = newwin(0,0,0,0);    /* get a new window to post help to */
  375. X
  376. Xmvwaddstr(statwin,0,30,"ldb Dice Statistics");        /* print title */
  377. Xmvwaddstr(statwin,1,30,"-------------------");        /* underline title */
  378. Xrow = 3;
  379. X
  380. Xmvwaddstr(statwin,row++,0,"You:");
  381. Xmvwaddstr(statwin,row++,0,"----");
  382. X
  383. Xrow++;
  384. Xmvwaddstr(statwin,row++,0,"Singles   1  2  3  4  5  6  Doubles   1  2  3  4  5  6");
  385. Xtemp[0] = '\0';
  386. Xfor (i = 0; i < 6; i++) {
  387. X    sprintf(temp, "%s%3d", temp, g->rolls[i]);
  388. X    Total += (g->rolls[i] * (i+1));
  389. X    }
  390. Xsprintf(temp, "%s          ",temp);
  391. Xfor (i = 0; i < 6; i++) {
  392. X    sprintf(temp, "%s%3d", temp, g->doubles[i]);
  393. X    Total += (g->doubles[i] * (i+1) * 4);
  394. X    }
  395. X
  396. Xmvwaddstr(statwin,row++,8,temp);
  397. Xrow++;
  398. Xpipcount(g->board,g,&mypip,&oppip);
  399. Xsprintf(temp,"Total of your dice rolls = %-3d        Pips remaining = %-3d",
  400. X    Total,mypip);
  401. Xmvwaddstr(statwin,row++,0,temp);
  402. Xrow++;
  403. Xrow++;
  404. X
  405. Xmvwaddstr(statwin,row++,0,"Opponent:");
  406. Xmvwaddstr(statwin,row++,0,"---------");
  407. X
  408. Xrow++;
  409. Xmvwaddstr(statwin,row++,0,"Singles   1  2  3  4  5  6  Doubles   1  2  3  4  5  6");
  410. Xtemp[0] = '\0';
  411. Xfor (i = 0; i < 6; i++) {
  412. X    sprintf(temp, "%s%3d", temp, g->oprolls[i]);
  413. X    OpTotal += (g->oprolls[i] * (i+1));
  414. X    }
  415. Xsprintf(temp, "%s          ",temp);
  416. Xfor (i = 0; i < 6; i++) {
  417. X    sprintf(temp, "%s%3d", temp, g->opdoubles[i]);
  418. X    OpTotal += (g->opdoubles[i] * (i+1) * 4);
  419. X    }
  420. X
  421. Xmvwaddstr(statwin,row++,8,temp);
  422. Xrow++;
  423. Xsprintf(temp,"Total of opponent dice rolls = %-3d    Pips remaining = %-3d",
  424. X    OpTotal,oppip);
  425. Xmvwaddstr(statwin,row++,0,temp);
  426. X
  427. X
  428. Xmvwaddstr(statwin,23,16,"Press H for histogram or <return> to continue: ");
  429. X
  430. Xtouchwin(statwin);        /* Make sure the screen is updated */
  431. Xwrefresh(statwin);        /* update the window clearing screen */
  432. Xc = wgetch(statwin) & 0x7f;    /* Wait for user response */
  433. X
  434. Xif (c == 'h' || c == 'H') {    /* Histogram wanted */
  435. X    wclear(statwin);        /* clear the window */
  436. X
  437. X/*
  438. X * Draw the axis themselves
  439. X *
  440. X */
  441. X
  442. X
  443. X    for (i = 2; i < 18; i++) {        /* Vertical axis */
  444. X        mvwaddstr(statwin,i,11,"|");
  445. X        mvwaddstr(statwin,i,44,"|");
  446. X        }
  447. X
  448. X    for (i = 12; i < 41; i++) {        /* Horizontal axis */
  449. X        mvwaddstr(statwin,17,i,"-");
  450. X        mvwaddstr(statwin,17,i+33,"-");
  451. X        }
  452. X
  453. X/*
  454. X * Number the vertical axis
  455. X *
  456. X */
  457. X
  458. X    mvwaddstr(statwin,2,8,"15");
  459. X    mvwaddstr(statwin,2,41,"15");
  460. X
  461. X    mvwaddstr(statwin,7,8,"10");
  462. X    mvwaddstr(statwin,7,41,"10");
  463. X
  464. X    mvwaddstr(statwin,12,9,"5");
  465. X    mvwaddstr(statwin,12,42,"5");
  466. X
  467. X/*
  468. X * Put the numbers across the bottom of the axis
  469. X *
  470. X */
  471. X
  472. X    col = 13;
  473. X    for (i = 1; i < 7; i++) {
  474. X        sprintf(temp,"%d", i);
  475. X        mvwaddch(statwin,18,col,temp[0]);
  476. X        mvwaddch(statwin,18,col+33,temp[0]);
  477. X        col += 5;
  478. X        }
  479. X
  480. X/*
  481. X * Label the top and bottom of the graph
  482. X *
  483. X */
  484. X
  485. X    mvwaddstr(statwin,0,17,"H i s t o g r a m   o f   D I C E   R o l l s");
  486. X    mvwaddstr(statwin,19,20,"S I N G L E S");
  487. X    mvwaddstr(statwin,19,53,"D O U B L E S");
  488. X    mvwaddstr(statwin,21,4,"Legend:");
  489. X    sprintf(temp,"X = You, dice total = %3d", Total);
  490. X    sprintf(temp,"%s     O = Opponent, dice total = %3d", temp, OpTotal);
  491. X    mvwaddstr(statwin,21,14,temp);
  492. X    wmove(statwin,22,23);
  493. X    wprintw(statwin,"pips       = %3d",mypip);
  494. X    wmove(statwin,22,58);
  495. X    wprintw(statwin,"pips       = %3d",oppip);
  496. X
  497. X/*
  498. X * Label the left side of the graph
  499. X *
  500. X */
  501. X
  502. X    sprintf(temp,"Number");
  503. X    for (i = 0; i < strlen(temp); i++)
  504. X        mvwaddch(statwin,7+i,0,temp[i]);
  505. X
  506. X    sprintf(temp,"of");
  507. X    for (i = 0; i < strlen(temp); i++)
  508. X        mvwaddch(statwin,9+i,3,temp[i]);
  509. X
  510. X    sprintf(temp,"Occurrences");
  511. X    for (i = 0; i < strlen(temp); i++)
  512. X        mvwaddch(statwin,5+i,6,temp[i]);
  513. X
  514. X/*
  515. X * Now that we have the axis drawn and labeled, fill in the data
  516. X *
  517. X */
  518. X
  519. X    for (dice = 0; dice < 6; dice++) {
  520. X        for (i = 0; i < 4; i++) {
  521. X            switch (i) {
  522. X            case 0:
  523. X                rolls = g->rolls[dice];
  524. X                col = 12 + dice * 5;
  525. X                c = 'X';
  526. X                break;
  527. X            case 1:
  528. X                rolls = g->oprolls[dice];
  529. X                col = 14 + dice * 5;
  530. X                c = 'O';
  531. X                break;
  532. X            case 2:
  533. X                rolls = g->doubles[dice];
  534. X                col = 45 + dice * 5;
  535. X                c = 'X';
  536. X                break;
  537. X            case 3:
  538. X                rolls = g->opdoubles[dice];
  539. X                col = 47 + dice * 5;
  540. X                c = 'O';
  541. X                break;
  542. X                }
  543. X    
  544. X/*
  545. X * Special case.  If we have more than 30 of one roll, put a * at the
  546. X * top of the second column and show 29 X's or O's.
  547. X *
  548. X */
  549. X
  550. X            row = 16;
  551. X            if (rolls > 30) {
  552. X                rolls = 29;
  553. X                mvwaddch(statwin,2,col+1,'*');
  554. X                }
  555. X
  556. X/*
  557. X * While the roll counter is greater than zero, put out X's or O's.
  558. X *
  559. X */
  560. X
  561. X            while (rolls > 0) {
  562. X                mvwaddch(statwin,row--,col,c);
  563. X                rolls--;
  564. X                if (row < 2) {    /* move to 2nd column */
  565. X                    row = 16;
  566. X                    col++;
  567. X                    }
  568. X                }
  569. X            }
  570. X        }
  571. X
  572. X/*
  573. X * We are done with the graph.  Refresh and wait for a keypress
  574. X *
  575. X */
  576. X
  577. X    mvwaddstr(statwin,23,25,"Press <return> to continue: ");
  578. X    touchwin(statwin);        /* Make sure the screen is updated */
  579. X    wrefresh(statwin);        /* update the window clearing screen */
  580. X    wgetch(statwin);        /* Wait for user response */
  581. X    }
  582. X
  583. Xwclear(statwin);        /* clear the window */
  584. Xwrefresh(statwin);        /* update the window clearing screen */
  585. Xdelwin(statwin);        /* delete the window */
  586. X}
  587. END_OF_FILE
  588. if test 6126 -ne `wc -c <'dostats.c'`; then
  589.     echo shar: \"'dostats.c'\" unpacked with wrong size!
  590. fi
  591. # end of 'dostats.c'
  592. fi
  593. if test -f 'ldbstarter' -a "${1}" != "-c" ; then 
  594.   echo shar: Will not clobber existing file \"'ldbstarter'\"
  595. else
  596. echo shar: Extracting \"'ldbstarter'\" \(5255 characters\)
  597. sed "s/^X//" >'ldbstarter' <<'END_OF_FILE'
  598. X#! /bin/csh -x
  599. Xset host=cs.umb.edu home=/u/ra/ugrad/mrubin/ldb user=mrubin
  600. Xsource /usr/local/lib/.cshrc
  601. Xset nonomatch fld='^From |^Return-Path:' edscr=(-e 's/<//g' -e 's/>//g')
  602. Xcd $home
  603. Xsetenv LDBRC $home/starter.ldbrc
  604. Xsetenv HOME $home
  605. X# first handle bad addresses.
  606. Xcd badaddr
  607. Xset f=(*)
  608. Xif ("$f" == "*") set f=""
  609. Xforeach x ($f)
  610. X    set rptmp=(`egrep "($fld)" $x | awk '{print $2;}' | tail -1 | sed $edscr`)
  611. X    set rp=$rptmp[$#rptmp]
  612. X    set to=(`fgrep To: $x | tail -1 | sed 's/To://g'`)
  613. X    echo "`date`  badaddr        $rp    $to" >> ../ldbstarter.log
  614. X    mail -s "Mail to invalid ldb address" $rp:q <<EOF
  615. X
  616. X----------------------------------------------------------------------
  617. X    The following is an automatic reply from
  618. X    the ldb game starter at $host.
  619. X
  620. X    The address you sent to:
  621. X        $to
  622. X    is not a valid ldb starter address.  For more information,
  623. X    send a message to ldb-help@$host.
  624. X----------------------------------------------------------------------
  625. X
  626. XEOF
  627. X    rm $x
  628. Xend
  629. X# Now handle all requests for more information.
  630. Xcd $home/help
  631. Xset f=(*)
  632. Xif ("$f" == "*") set f=""
  633. Xforeach x ($f)
  634. X    set rptmp=(`egrep "($fld)" $x | awk '{print $2;}' | tail -1 | sed $edscr`)
  635. X    set rp=$rptmp[$#rptmp]
  636. X    echo "`date`  help        $rp" >> ../ldbstarter.log
  637. X    mail -s "Information on automatic ldb game starter" $rp:q <<EOF
  638. X
  639. X----------------------------------------------------------------------
  640. X    The following is an automatic reply from
  641. X    the ldb game starter at $host.
  642. X
  643. XWelcome to the automatic ldb game starter system.  Ldb is a program that
  644. Xallows two people to easily play backgammon by e-mail.  This system
  645. Xuses the remote start capability of ldb to automatically start a
  646. Xgame between two people of similar ability.  Before you can use
  647. Xthe ldb starter, you will need to get and compile ldb on your system.
  648. XLdb is accessible via anonymous ftp from ftp.uu.net or any other host that
  649. Xarchives the comp.sources.misc newsgroup.  Retrieve all parts, uncompress
  650. Xthem, un-tar them, and read the file README for compilation and
  651. Xinstallation instructions.  Ldb runs on most 32-bit UNIX systems
  652. Xand on VAXes under VMS 5.0 or higher.
  653. X
  654. XTo use the ldb starter, simply send a mail message to one of the
  655. Xfollowing addresses:
  656. X    ldb-novice@$host
  657. X    ldb-intermediate@$host
  658. X    ldb-expert@$host
  659. Xdepending on what level of ability you are at.  You choose your level
  660. Xof play for yourself, there are no restrictions on which level you
  661. Xplay at.  The game starter system does not keep any record of your
  662. Xlevel, or whether you win or lose.  It is merely a convenient way
  663. Xto meet new backgammon players that are at more or less the same
  664. Xlevel of ability as you are.  It doesn't matter what you put in
  665. Xthe message, the game starter only uses your return address.
  666. XThe message can be empty as far as the game starter is concerned,
  667. Xbut your local mail program may complain about empty messages.
  668. X
  669. XEach time you send a message to one of the above addresses, you are
  670. Xmatched at random with another person who sent to the same address.
  671. XEach message you send only starts one game.  When you are ready for
  672. Xanother game, you must send another message.
  673. X
  674. XThe game starter will try to avoid having you play yourself,
  675. Xbut it cannot guarantee this will not happen if you send
  676. Xmultiple requests to the same address within a short time.
  677. XTo avoid this problem, only send one request at a time, and
  678. Xdo not send another one until the first game has been started.
  679. X
  680. XNote that there could be an arbitrary delay between when you
  681. Xsend the message and when the game is started.  The game starter
  682. Xdoes not currently send acknowledgements other than the
  683. Xactual start command.  This is sent to one of the two opponents
  684. Xat random, and will not reach the other one until the first
  685. Xprocesses it through ldb.
  686. X
  687. XThis system will work best with "pure" domain-style e-mail addresses.
  688. XIt *should* work with UUCP addresses too, but there could be problems
  689. Xwith this, since the path messages take to get to the game starter
  690. Xmay not be the same path they should take to get to your opponent.
  691. XIf you want ldb to use an address for you other than the return
  692. Xaddress from your message, put the following line in your message:
  693. X
  694. XReturn-Path: address@you.wanna.use.instead
  695. X
  696. XThe Return-Path: must be at the beginning of the line, and must be
  697. Xexactly as shown (case *is* significant).
  698. X
  699. XPlease note that this system is still experimental.  If you have a
  700. Xproblem using it, or if you have questions about ldb or the
  701. Xautomatic game starter, contact Perry Ross by e-mail at
  702. Xross@emf780.den.mmc.com or Mark Rubin by e-mail at mrubin@cs.umb.edu.
  703. X
  704. XGood Luck!
  705. X----------------------------------------------------------------------
  706. X
  707. XEOF
  708. X    rm $x
  709. Xend
  710. Xforeach x (novice intermediate expert)
  711. X    cd $home/$x
  712. X    set z=$x
  713. X    if ($x != intermediate) set z="$x    "
  714. X    set y=(`ls | head -2`)
  715. X    while ($#y > 1)
  716. X        set u1tmp=(`egrep "($fld)" $y[1] | awk '{print $2;}' | tail -1 | sed $edscr`)
  717. X        set u1=$u1tmp[$#u1tmp]
  718. X        set u2tmp=(`egrep "($fld)" $y[2] | awk '{print $2;}' | tail -1 | sed $edscr`)
  719. X        set u2=$u2tmp[$#u2tmp]
  720. X        if ("$u1" == "$u2") then    # duplicate
  721. X            rm $y[1]        # eliminate one of them
  722. X            set y=(`ls | head -2`)    # and try again
  723. X            continue
  724. X        endif
  725. X        /u/ra/ugrad/mrubin/bin/sun4/ldb -remotestart $u1:q $u2:q
  726. X        rm $y
  727. X        echo "`date`  $z    $u1:q $u2:q" >> ../ldbstarter.log
  728. X        set y=(`ls | head -2`)
  729. X    end
  730. Xend
  731. Xexit
  732. END_OF_FILE
  733. if test 5255 -ne `wc -c <'ldbstarter'`; then
  734.     echo shar: \"'ldbstarter'\" unpacked with wrong size!
  735. fi
  736. # end of 'ldbstarter'
  737. fi
  738. if test -f 'move.c' -a "${1}" != "-c" ; then 
  739.   echo shar: Will not clobber existing file \"'move.c'\"
  740. else
  741. echo shar: Extracting \"'move.c'\" \(5447 characters\)
  742. sed "s/^X//" >'move.c' <<'END_OF_FILE'
  743. X/*    move.c        8/5/91
  744. X *
  745. X * Copyright 1991  Perry R. Ross
  746. X *
  747. X * Permission to use, copy, modify, and distribute this software and its
  748. X * documentation without fee is hereby granted, subject to the restrictions
  749. X * detailed in the README file, which is included here by reference.
  750. X * Any other use requires written permission from the author.  This software
  751. X * is distributed "as is" without any warranty, including any implied
  752. X * warranties of merchantability or fitness for a particular purpose.
  753. X * The author shall not be liable for any damages resulting from the
  754. X * use of this software.  By using this software, the user agrees
  755. X * to these terms.
  756. X */
  757. X
  758. X#include "ldb.h"
  759. X
  760. X/*-----------------------------------------------------------------------
  761. X *    apply -- apply a move to a board
  762. X *
  763. X * Apply applies a move to a board, detecting the following errors:
  764. X *    RJ_NOROLL    The mv struct did not contain a valid roll.
  765. X *    RJ_ONBAR    The move attempted to move from a point other than
  766. X *            the bar when pieces are on the bar.
  767. X *    RJ_NOOFF    The move attempted to move pieces off before all
  768. X *            pieces are in the inner table.
  769. X *    RJ_NOPIECE    The move attempted to take a piece from an empty point.
  770. X *    RJ_NOTYOURS    The move attempted to move the opponent's piece.
  771. X *    RJ_OCC        The move attempted to move to an occupied point.
  772. X *    RJ_EXACT    The move attempted to bear off a piece with a
  773. X *            larger roll than necessary when that piece was
  774. X *            not the outermost piece.
  775. X * If the move was legal, apply returns:
  776. X *    MVOK        if no blot was hit, or
  777. X *    point number    where the blot was before it was hit.
  778. X * Note that blot numbers are in the range [1-24], MVOK is 0, and
  779. X * the reject codes are negative.  When the move is rejected,
  780. X * the board is unchanged.  When a blot is hit, it is moved to the
  781. X * appropriate bar point automatically.
  782. X *
  783. X * If A_REDRAW is set in flags, apply redraws the relevant portions of
  784. X * the screen to reflect the move.  If A_CHKONLY is set in flags, the
  785. X * move is checked but the board is not modified.
  786. X *-----------------------------------------------------------------------
  787. X */
  788. X
  789. Xapply(g,who,mn,flags,dest)
  790. Xstruct game *g;            /* game structure */
  791. Xint who;            /* WHO_OPP = opponent, WHO_ME = me */
  792. Xint mn;                /* which element of mv array */
  793. Xint flags;            /* A_* */
  794. Xint *dest;            /* where to store destination point */
  795. X{
  796. Xint i, j, blot;
  797. Xint op, np;
  798. Xint dir;
  799. Xchar clr;
  800. Xstruct mv *m;
  801. Xregister struct point *b = g->board;
  802. X
  803. Xdir = (who == WHO_ME) ? g->mydir : g->opdir;
  804. Xclr = (who == WHO_ME) ? g->mycolor : g->opcolor;
  805. Xblot = MVOK;            /* no blot hit yet */
  806. Xm = (who == WHO_ME) ? &g->mvs[mn] : &g->opmvs[mn];
  807. Xif (m->roll <= 0)        /* sanity check */
  808. X    return(RJ_NOROLL);    /* reject move */
  809. Xop = m->pt;        /* starting point number */
  810. Xif (op < 0)        /* this roll is unused */
  811. X    return(MVOK);    /* and that's ok */
  812. Xif ( (op == 0) || (op == 25) )    /* moving off bar */
  813. X    op = BARPT(dir);    /* use correct bar point */
  814. Xelse {            /* not moving off bar */
  815. X    j = BARPT(dir);    /* make sure no pieces still on bar */
  816. X    if (b[j].qty > 0)
  817. X        return(RJ_ONBAR);    /* can't move, pieces on bar */
  818. X    }
  819. Xnp = op + m->roll*dir;    /* move piece correct number of pts */
  820. Xif ( (np <= 0) || (np >= 25) ) {
  821. X    i = (dir > 0) ? 19 : 1;
  822. X    j = (dir > 0) ? 24 : 6;
  823. X    if (addpcs(b,clr,i,j)+b[OFFPT(dir)].qty < 15) /* all pcs not */
  824. X        return(RJ_NOOFF);    /* in inner table, can't move off */
  825. X    if ( (np != 0) && (np != 25) ) {/* using bigger roll than needed */
  826. X        i = (dir > 0) ? 19   : op+1; /* check for pcs on higher pts */
  827. X        j = (dir > 0) ? op-1 : 6;
  828. X        if (addpcs(b,clr,i,j) > 0)    /* there are some */
  829. X            return(RJ_EXACT);    /* must use roll on them */
  830. X        }
  831. X    np = OFFPT(dir);    /* this piece is moving off */
  832. X    }
  833. Xif (b[op].qty <= 0)        /* no piece here to move */
  834. X    return(RJ_NOPIECE);
  835. Xif (b[op].color != clr)    /* trying to move opponent's pieces? */
  836. X    return(RJ_NOTYOURS);
  837. Xif (b[np].qty == 0)        /* moving to an empty point */
  838. X    b[np].color = b[op].color;    /* copy color */
  839. Xif (b[np].color != b[op].color) {    /* moving to occupied pt */
  840. X    if (b[np].qty == 1) {        /* whacked a blot */
  841. X        blot = np;        /* save point number for return */
  842. X        if ( (flags & A_CHKONLY) == 0) {
  843. X            b[np].qty = 0;        /* bye bye */
  844. X            j = BARPT(REV(dir));    /* send it to opponents bar */
  845. X            b[j].color = b[np].color; /* copy color to bar pt */
  846. X            b[j].qty++;        /* bump counter */
  847. X            if (flags & A_REDRAW) {    /* update screen */
  848. X                FeDrawPoint(b,j,0,g->flags & F_INVERT);
  849. X                FeDrawPip(b,g);
  850. X                }
  851. X            b[np].color = b[op].color;    /* my point now */
  852. X            }
  853. X        }
  854. X    else
  855. X        return(RJ_OCC);        /* point is occupied */
  856. X    }
  857. Xif ( (flags & A_CHKONLY) == 0) {
  858. X    b[op].qty--;                /* take piece from old pt */
  859. X    b[np].qty++;                /* and put in on new pt */
  860. X    if (flags & A_REDRAW) {
  861. X        FeDrawPip(b,g);
  862. X        FeDrawPoint(b,op,0,g->flags & F_INVERT);/* update the screen */
  863. X        FeDrawPoint(b,np,0,g->flags & F_INVERT);
  864. X        }
  865. X    }
  866. Xif (dest != NULL)            /* return new position */
  867. X    *dest = np;
  868. Xreturn(blot);                /* succeeded, return MVOK or blot */
  869. X}
  870. X
  871. X
  872. X/*----------------------------------------------------------------------
  873. X *    addpcs -- add the number of pieces in a range of points
  874. X *
  875. X * This function returns the number of pieces of a certain color
  876. X * that reside within a range of points.
  877. X *----------------------------------------------------------------------
  878. X */
  879. X
  880. Xaddpcs(b,clr,f,t)
  881. Xboard b;
  882. Xchar clr;
  883. Xint f, t;
  884. X{
  885. Xint i, q;
  886. X
  887. Xq = 0;                /* quantity we have found so far */
  888. Xfor (i = f; i <= t; i++)
  889. X    if (b[i].color == clr)    /* found some */
  890. X        q += b[i].qty;    /* count them */
  891. Xreturn(q);            /* return quantity found */
  892. X}
  893. END_OF_FILE
  894. if test 5447 -ne `wc -c <'move.c'`; then
  895.     echo shar: \"'move.c'\" unpacked with wrong size!
  896. fi
  897. # end of 'move.c'
  898. fi
  899. if test -f 'r_xrand.c' -a "${1}" != "-c" ; then 
  900.   echo shar: Will not clobber existing file \"'r_xrand.c'\"
  901. else
  902. echo shar: Extracting \"'r_xrand.c'\" \(8762 characters\)
  903. sed "s/^X//" >'r_xrand.c' <<'END_OF_FILE'
  904. X/*    r_xrand.c
  905. X */
  906. X
  907. X#include "ldb.h"
  908. X#include <math.h>
  909. X
  910. Xlong rnd_ri();
  911. X
  912. X/*======================================================================
  913. X * This file contains the random number generator.  It is accessed by
  914. X * calling RandomInit with a 32-bit seed, then calling Rolldie() to
  915. X * generate integers in the range [1-6].  This particular implementation
  916. X * was taken from xrand in volume 2 of comp.sources.misc.  It was
  917. X * written by Andreas Nowatzyk, then of Carnegie-Mellon University, and
  918. X * is reproduced here essentially unchanged (although I omitted
  919. X * all routines but the ones needed for integers in [1-6]).
  920. X * It is used by permission of the author, whose original copyright
  921. X * and permission-to-use appears below.
  922. X *======================================================================
  923. X */
  924. X
  925. X
  926. X
  927. X/*----------------------------------------------------------------------
  928. X *    Rolldie -- return a random number between 1 and 6
  929. X *----------------------------------------------------------------------
  930. X */
  931. X
  932. XRolldie()
  933. X{
  934. X
  935. Xreturn( ( (int) rnd_ri(6L) ) + 1);
  936. X}
  937. X
  938. X
  939. X
  940. X/*----------------------------------------------------------------------
  941. X *    RandomInit -- initialize the random number generator
  942. X *
  943. X * This function should be called once, before Rolldie is called.
  944. X * The seed may be any more or less random number; the time seems
  945. X * to be conventional.
  946. X *----------------------------------------------------------------------
  947. X */
  948. X
  949. XRandomInit(seed)
  950. Xlong seed;
  951. X{
  952. X
  953. Xrnd_init(seed);
  954. X}
  955. X
  956. X
  957. X
  958. X/*----------------------------------------------------------------------
  959. X *From:    EMF780::WINS%"Andreas.Nowatzyk@eng.sun.com" 20-NOV-1991 17:50:38.73
  960. X *To:    ROSS
  961. X *CC:    
  962. X *Subj:    Re:  xrand
  963. X *
  964. X *Return-Path: <Andreas.Nowatzyk@eng.sun.com>
  965. X *Received: from everest.den.mmc.com by emf780.den.mmc.com with SMTP ; 
  966. X *          Wed, 20 Nov 91 16:50:29 MDT
  967. X *Received: from Sun.COM by everest.den.mmc.com (4.1/1.34.a)
  968. X *    id AA27426; Wed, 20 Nov 91 17:52:10 MST
  969. X *Received: from Eng.Sun.COM (zigzag-bb.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.1)
  970. X *    id AA07190; Wed, 20 Nov 91 16:50:53 PST
  971. X *Received: from bovic.Eng.Sun.COM by Eng.Sun.COM (4.1/SMI-4.1)
  972. X *    id AA21474; Wed, 20 Nov 91 16:49:44 PST
  973. X *Received: by bovic.Eng.Sun.COM (4.1/SMI-4.1)
  974. X *    id AA02462; Wed, 20 Nov 91 16:49:16 PST
  975. X *Date: Wed, 20 Nov 91 16:49:16 PST
  976. X *From: Andreas.Nowatzyk@eng.sun.com (Andreas G. Nowatzyk)
  977. X *Message-Id: <9111210049.AA02462@bovic.Eng.Sun.COM>
  978. X *To: ross@emf780.den.mmc.com
  979. X *Subject: Re:  xrand
  980. X *
  981. X *I have no objection to distributing xrand, provided that this is not done
  982. X *for profit and that the source is credited.
  983. X *
  984. X *  --  Andreas
  985. X *
  986. X *PS: There was a bug is some version of xrand.c: The constant for the most
  987. X *    positive integer (0x7fffffff) had an 'f' missing in two places. It should
  988. X *    have used a #define MAX_INT with apropriate value instead of hardwiring
  989. X *    an hex-constant.
  990. X *----------------------------------------------------------------------
  991. X */
  992. X
  993. X#define MAX_INT 0x7fffffff
  994. X
  995. X/* Random number generators:
  996. X *
  997. X *  rnd_init (unsigned seed) 
  998. X *            : initializes the generator
  999. X *
  1000. X *  rnd_i ()        : returns positive integers [0,0x7fffffff]
  1001. X *  rnd_ri (long n)    : returns positive integers [0,n-1]
  1002. X *
  1003. X *  Algorithm M as describes in Knuth's "Art of Computer Programming", Vol 2. 1969
  1004. X *  is used with a linear congruential generator (to get a good uniform
  1005. X *  distribution) that is permuted with a Fibonacci additive congruential
  1006. X *  generator to get good independence.
  1007. X *
  1008. X *  Bit, byte, and word distributions were extensively tested and pass
  1009. X *  Chi-squared test near perfect scores (>7E8 numbers tested, Uniformity
  1010. X *  assumption holds with probability > 0.999)
  1011. X *
  1012. X *  Run-up tests for on 7E8 numbers confirm independence with
  1013. X *  probability > 0.97.
  1014. X *
  1015. X *  Plotting random points in 2d reveals no apparent structure.
  1016. X *
  1017. X *  Autocorrelation on sequences of 5E5 numbers (A(i) = SUM X(n)*X(n-i), i=1..512)
  1018. X *  results in no obvious structure (A(i) ~ const).
  1019. X *
  1020. X *  On a SUN 3/60, rnd_u() takes about 19.4 usec per call, which is about 44%
  1021. X *  slower than Berkeley's random() (13.5 usec/call).
  1022. X *
  1023. X *  Except for speed and memory requirements, this generator outperforms
  1024. X *  random() for all tests. (random() scored rather low on uniformity tests,
  1025. X *  while independence test differences were less dramatic).
  1026. X *
  1027. X *  Thanks to M.Mauldin, H.Walker, J.Saxe and M.Molloy for inspiration & help.
  1028. X *
  1029. X *  (c) Copyright 1988 by A. Nowatzyk
  1030. X *
  1031. X */
  1032. X
  1033. X/* LC-parameter selection follows recommendations in 
  1034. X * "Handbook of Mathematical Functions" by Abramowitz & Stegun 10th, edi.
  1035. X */
  1036. X#define LC_A 66049L            /* = 251^2, ~= sqrt(2^32)            */
  1037. X#define LC_C 390786457L    /* result of a long trial & error series    */
  1038. X
  1039. X/*
  1040. X#define Xrnd(x) (long)((long)x * LC_A + LC_C) */   /* the LC polynomial            */
  1041. X            
  1042. Xstatic unsigned long Fib[55];        /* will use X(n) = X(n-55) - X(n-24)    */
  1043. Xstatic int Fib_ind;            /* current index in circular buffer        */
  1044. Xstatic unsigned long Xrnd_var;        /* LCA - recurrence variable        */
  1045. Xstatic unsigned long auxtab[256];   /* temporal permutation table        */
  1046. Xstatic unsigned long prmtab[64] = { /* spatial permutation table        */
  1047. X    0xffffffff, 0x00000000,  0x00000000,  0x00000000,  /* 3210 */
  1048. X    0x0000ffff, 0x00ff0000,  0x00000000,  0xff000000,  /* 2310 */
  1049. X    0xff0000ff, 0x0000ff00,  0x00000000,  0x00ff0000,  /* 3120 */
  1050. X    0x00ff00ff, 0x00000000,  0xff00ff00,  0x00000000,  /* 1230 */
  1051. X
  1052. X    0xffff0000, 0x000000ff,  0x00000000,  0x0000ff00,  /* 3201 */
  1053. X    0x00000000, 0x00ff00ff,  0x00000000,  0xff00ff00,  /* 2301 */
  1054. X    0xff000000, 0x00000000,  0x000000ff,  0x00ffff00,  /* 3102 */
  1055. X    0x00000000, 0x00000000,  0x00000000,  0xffffffff,  /* 2103 */
  1056. X
  1057. X    0xff00ff00, 0x00000000,  0x00ff00ff,  0x00000000,  /* 3012 */
  1058. X    0x0000ff00, 0x00000000,  0x00ff0000,  0xff0000ff,  /* 2013 */
  1059. X    0x00000000, 0x00000000,  0xffffffff,  0x00000000,  /* 1032 */
  1060. X    0x00000000, 0x0000ff00,  0xffff0000,  0x000000ff,  /* 1023 */
  1061. X
  1062. X    0x00000000, 0xffffffff,  0x00000000,  0x00000000,  /* 0321 */
  1063. X    0x00ffff00, 0xff000000,  0x00000000,  0x000000ff,  /* 0213 */
  1064. X    0x00000000, 0xff000000,  0x0000ffff,  0x00ff0000,  /* 0132 */
  1065. X    0x00000000, 0xff00ff00,  0x00000000,  0x00ff00ff   /* 0123 */
  1066. X};
  1067. X
  1068. Xunion hack {                /* used to access doubles as unsigneds    */
  1069. X    double d;
  1070. X    unsigned long u[2];
  1071. X};
  1072. X
  1073. Xstatic union hack man;            /* mantissa bit vector            */
  1074. X
  1075. Xlong Xrnd(x) 
  1076. Xlong x;
  1077. X{
  1078. X    long tmp;
  1079. X
  1080. X    tmp = x* LC_A;
  1081. X    tmp += LC_C;
  1082. X    return tmp;
  1083. X}
  1084. X
  1085. Xrnd_init (seed)                /* modified: seed 0-31 use precomputed stuff */
  1086. X    unsigned seed;
  1087. X{
  1088. X    register unsigned long u;
  1089. X    register int i;
  1090. X    double x, y;
  1091. X    union hack t;
  1092. X
  1093. X    static unsigned seed_tab[32] = {
  1094. X        0xbdcc47e5, 0x54aea45d, 0xec0df859, 0xda84637b,
  1095. X        0xc8c6cb4f, 0x35574b01, 0x28260b7d, 0x0d07fdbf,
  1096. X        0x9faaeeb0, 0x613dd169, 0x5ce2d818, 0x85b9e706,
  1097. X        0xab2469db, 0xda02b0dc, 0x45c60d6e, 0xffe49d10,
  1098. X        0x7224fea3, 0xf9684fc9, 0xfc7ee074, 0x326ce92a,
  1099. X        0x366d13b5, 0x17aaa731, 0xeb83a675, 0x7781cb32,
  1100. X        0x4ec7c92d, 0x7f187521, 0x2cf346b4, 0xad13310f,
  1101. X        0xb89cff2b, 0x12164de1, 0xa865168d, 0x32b56cdf  };
  1102. X
  1103. X    if (seed < 32)
  1104. X    u = seed_tab[seed];
  1105. X    else
  1106. X    u = seed ^ seed_tab[seed & 31];
  1107. X
  1108. X    for (i = 55; i--;)            /* set up Fibonacci additive congruential    */
  1109. X    Fib[i] = u = Xrnd(u);
  1110. X
  1111. X    for (i = 256; i--;)
  1112. X    auxtab[i] = u = Xrnd(u);
  1113. X
  1114. X    Fib_ind = u % 55;            /* select a starting point            */
  1115. X
  1116. X    Xrnd_var = u;
  1117. X
  1118. X    /*    The following tests to see if a double fits into
  1119. X        2 unsigned longs.  If not, rnd_01d will not work
  1120. X        on this machine.                    */
  1121. X
  1122. X    if (sizeof(x) != 2 * sizeof(unsigned long))
  1123. X    fatal("ERROR: xrand roller does not work on this machine!");
  1124. X
  1125. X    x = 1.0;
  1126. X    y = 0.5;
  1127. X    do {                /* find largest fp-number < 2.0    */
  1128. X    t.d = x;
  1129. X    x += y;
  1130. X    y *= 0.5;
  1131. X    } while (x != t.d && x < 2.0);
  1132. X
  1133. X    man.d = 1.0;
  1134. X    man.u[0] ^= t.u[0];
  1135. X    man.u[1] ^= t.u[1];            /* man is now 1 for each mantissa bit    */
  1136. X}
  1137. X
  1138. Xlong rnd_i ()
  1139. X/*
  1140. X * returns a positive, uniformly distributed random number in [0,0x7fffffff]
  1141. X */
  1142. X{ 
  1143. X    register unsigned long i, j, *t = Fib;
  1144. X
  1145. X    i = Fib_ind;
  1146. X    j = t[i];                    /* = X(n-55) */
  1147. X    j -= (i >= 24) ? t[i - 24] : t[i + 21]; /* = X(n-24) */
  1148. X    t[i] = j;
  1149. X    if (++i >= 55) i = 0;
  1150. X    Fib_ind = i;
  1151. X
  1152. X    t = &auxtab[(j >> 24) & 0xff];
  1153. X    i = *t;
  1154. X    Xrnd_var = *t = Xrnd(Xrnd_var);
  1155. X    t = &prmtab[j & 0x3c];
  1156. X
  1157. X    j =  *t++ & i;
  1158. X    j |= *t++ & ((i << 24) | ((i >>  8) & 0x00ffffff));
  1159. X    j |= *t++ & ((i << 16) | ((i >> 16) & 0x0000ffff));
  1160. X    j |= *t   & ((i <<  8) | ((i >> 24) & 0x000000ff));
  1161. X    
  1162. X    return j & MAX_INT;
  1163. X}
  1164. X
  1165. X
  1166. Xlong rnd_ri (rng)
  1167. X    long rng;
  1168. X/*
  1169. X * randint: Return a random integer in a given Range [0..rng-1]
  1170. X *          Note:  0 < rng
  1171. X */
  1172. X{
  1173. X    register unsigned long  r, a;
  1174. X
  1175. X    do {
  1176. X    r = rnd_i();
  1177. X    a = (r / rng) + 1;
  1178. X    a *= rng;
  1179. X    } while (a >= MAX_INT);
  1180. X    
  1181. X    a--;
  1182. X    return a - r;
  1183. X}
  1184. END_OF_FILE
  1185. if test 8762 -ne `wc -c <'r_xrand.c'`; then
  1186.     echo shar: \"'r_xrand.c'\" unpacked with wrong size!
  1187. fi
  1188. # end of 'r_xrand.c'
  1189. fi
  1190. if test -f 'vars.c' -a "${1}" != "-c" ; then 
  1191.   echo shar: Will not clobber existing file \"'vars.c'\"
  1192. else
  1193. echo shar: Extracting \"'vars.c'\" \(11599 characters\)
  1194. sed "s/^X//" >'vars.c' <<'END_OF_FILE'
  1195. X/*    vars.c        8/4/91
  1196. X *
  1197. X * Copyright 1991  Perry R. Ross
  1198. X *
  1199. X * Permission to use, copy, modify, and distribute this software and its
  1200. X * documentation without fee is hereby granted, subject to the restrictions
  1201. X * detailed in the README file, which is included here by reference.
  1202. X * Any other use requires written permission from the author.  This software
  1203. X * is distributed "as is" without any warranty, including any implied
  1204. X * warranties of merchantability or fitness for a particular purpose.
  1205. X * The author shall not be liable for any damages resulting from the
  1206. X * use of this software.  By using this software, the user agrees
  1207. X * to these terms.
  1208. X */
  1209. X
  1210. X#include "ldb.h"
  1211. X
  1212. X/*======================================================================
  1213. X * This file contains the definition for all global variables, as well
  1214. X * as the static initialization values for those that need it.
  1215. X *======================================================================
  1216. X */
  1217. X
  1218. Xint Pflag;            /* should I process local input? */
  1219. Xint Rflag;            /* should I look for mail? */
  1220. Xstruct game *ghead;        /* head of linked list of games */
  1221. Xstruct game *gtail;        /* tail of linked list of games */
  1222. Xstruct legal *lhead;        /* head of list of legal moves */
  1223. Xstruct legal *ltail;        /* tail of list of legal moves */
  1224. Xstruct people *phead;        /* head of people list */
  1225. Xstruct packet P;        /* last packet read */
  1226. Xchar cr_mycolor;        /* my color when game is created */
  1227. Xchar cr_opcolor;        /* opponent's color for new games */
  1228. Xchar cr_mydir;            /* my direction for new games */
  1229. Xchar *notify;            /* address to notify when game ends */
  1230. Xchar blk76[] =            /* 76 blanks */
  1231. X"                                                                            ";
  1232. X
  1233. Xchar FeIsActive = 0;        /* has the front-end been initialized? */
  1234. Xchar FeWaitInit = 0;        /* non-0 if message() has been called */
  1235. X
  1236. X#ifdef NEED_READDIR
  1237. Xstruct direct dirbuf;        /* mem used by readdir emulation #define */
  1238. X#endif
  1239. X
  1240. Xint GameState = 0;        /* Current game state for help */
  1241. Xint boardnums[3] = {BD_AFTOP, BD_BEFOP, BD_CUR};
  1242. Xchar *states[] = {        /* description of the states */
  1243. X    "Waiting for opponent to start game",
  1244. X    "Waiting for opponent to move",
  1245. X    "Waiting for opponent to accept double",
  1246. X    "Your turn (you haven't rolled yet)",
  1247. X    "Your move (you have rolled)",
  1248. X    "Waiting for you to accept double",
  1249. X    "Game over"
  1250. X    };
  1251. X
  1252. Xstruct opt options[] = {
  1253. X    "broadcast",    OPT_BCAST,    " [file]",
  1254. X    "\tSend a mail message to all opponents",
  1255. X    "colors",    OPT_COLOR,    " xx",
  1256. X    "\t\tSet colors for new game",
  1257. X    "control",    OPT_CONTROL,    "",
  1258. X    "\t\tPerform control functions on games",
  1259. X    "crawford",    OPT_CRAWFORD,    "",
  1260. X    "\t\tEnable crawford rule for new games",
  1261. X    "direction",    OPT_DIRECTION,    " dir",
  1262. X    "\t\tSet direction for new game [up or down]",
  1263. X    "european",    OPT_EUROPE,    "",
  1264. X    "\t\tEnable european rule for new games",
  1265. X    "help",        OPT_HELP,    "",
  1266. X    "\t\t\tPrint this message",
  1267. X    "jacoby",    OPT_JACOBY,    "",
  1268. X    "\t\t\tEnable jacoby rule for new games",
  1269. X    "match",    OPT_MATCH,    " number",
  1270. X    "\t\tSet number of points in match",
  1271. X    "myaddr",    OPT_MYADDR,    " addr",
  1272. X    "\t\tSet local e-mail address",
  1273. X    "newaddr",    OPT_NEWADDR,    "",
  1274. X    "\t\tNotify opponents that your address changed",
  1275. X    "notify",    OPT_NOTIFY,    " addr",
  1276. X    "\t\tSend mail to addr when game ends",
  1277. X    "permanent",    OPT_PERM,    "",
  1278. X    "\t\tMake new games permanent",
  1279. X    "play",        OPT_PLAY,    "",
  1280. X    "\t\t\tPlay any waiting games but do not read mail",
  1281. X    "read",        OPT_READ,    "",
  1282. X    "\t\t\tRead incoming mail but do not play",
  1283. X    "reconstruct",    OPT_RECONS,    " file",
  1284. X    "\tReconstruct a game from opponent's data file",
  1285. X    "remotestart",    OPT_RSTART,    " u1 u2",
  1286. X    "\tStart a game between u1 and u2",
  1287. X    "score",    OPT_SCORE,    "",
  1288. X    "\t\t\tPrint cumulative score by opponent",
  1289. X    "start",    OPT_START,    " user",
  1290. X    "\t\tStart a game with another user",
  1291. X    NULL,        -1,        NULL,        NULL
  1292. X    };
  1293. X
  1294. Xchar *opcodes[] = {
  1295. X        "START", "USTART", "TIE",  "MOVE", "OFFERDOUBLE", "ACCEPTDOUBLE",
  1296. X    "DECLINEDOUBLE", "CONCEDE", "REMOTESTART", "RESTART", "MSTART",
  1297. X    "RESEND", "NOTIFY",
  1298. X    NULL
  1299. X        };
  1300. X
  1301. Xstruct namevalue nv_rcfile[] = {
  1302. X    "myname",    FT_STRING,    Offset(struct ldbrc *,myname),    NULL,
  1303. X    "myaddr",    FT_STRING,    Offset(struct ldbrc *,myaddr),    NULL,
  1304. X    "peoplefile",    FT_STRING,    Offset(struct ldbrc *,pfile),    NULL,
  1305. X    "gamefile",    FT_STRING,    Offset(struct ldbrc *,gfile),    NULL,
  1306. X    "backupfile",    FT_STRING,    Offset(struct ldbrc *,gbackup),    NULL,
  1307. X    "mailfile",    FT_STRING,    Offset(struct ldbrc *,mfile),    NULL,
  1308. X    "delmail",    FT_STRING,    Offset(struct ldbrc *,delmail),    NULL,
  1309. X    "lockfile",    FT_STRING,    Offset(struct ldbrc *,lockfile),NULL,
  1310. X    "sendcmd",    FT_STRING,    Offset(struct ldbrc *,sendcmd),    NULL,
  1311. X    "tempfile",    FT_STRING,    Offset(struct ldbrc *,tempfile),NULL,
  1312. X    "colors",    FT_STRING,    Offset(struct ldbrc *,defclrs),    NULL,
  1313. X    "direction",    FT_STRING,    Offset(struct ldbrc *,defdir),    NULL,
  1314. X    "initialboard",    FT_STRING,    Offset(struct ldbrc *,initboard),NULL,
  1315. X    "autoroll",    FT_STRING,    Offset(struct ldbrc *,autoroll),NULL,
  1316. X    "automove",    FT_STRING,    Offset(struct ldbrc *,automove),NULL,
  1317. X    "autodouble",    FT_INT,        Offset(struct ldbrc *,autodouble),0,
  1318. X    "supercmd",    FT_STRING,    Offset(struct ldbrc *,supercmd),NULL,
  1319. X    "superkey",    FT_CHAR,    Offset(struct ldbrc *,superkey),0,
  1320. X    "checkpoint",    FT_STRING,    Offset(struct ldbrc *,chkpt),    NULL,
  1321. X    "timeout",    FT_INT,        Offset(struct ldbrc *,acctime),    0,
  1322. X    "keepold",    FT_INT,        Offset(struct ldbrc *,keepold),    0,
  1323. X    "debug",    FT_INT,        Offset(struct ldbrc *,debug),    0,
  1324. X    NULL,        0,        -1,    0
  1325. X    };
  1326. X
  1327. Xstruct namevalue nv_gfile[] = {        /* extracts into global var G */
  1328. X    "gameid",    FT_STRING,    Offset(struct game *,gameid),    NULL,
  1329. X    "opaddr",    FT_STRING,    Offset(struct game *,opaddr),    NULL,
  1330. X    "opname",    FT_STRING,    Offset(struct game *,opname),    NULL,
  1331. X    "myaddr",    FT_STRING,    Offset(struct game *,myaddr),    NULL,
  1332. X    "mycolor",    FT_CHAR,    Offset(struct game *,mycolor),    0,
  1333. X    "opcolor",    FT_CHAR,    Offset(struct game *,opcolor),    0,
  1334. X    "mydir",    FT_CHAR,    Offset(struct game *,mydir),    0,
  1335. X    "opdir",    FT_CHAR,    Offset(struct game *,opdir),    0,
  1336. X    "gameval",    FT_INT,        Offset(struct game *,gameval),    0,
  1337. X    "flags",    FT_INT,        Offset(struct game *,flags),    0,
  1338. X    "opversion",    FT_INT,        Offset(struct game *,opver),    0,
  1339. X    "state",    FT_CHAR,    Offset(struct game *,state),    0,
  1340. X    "term",        FT_CHAR,    Offset(struct game *,term),    0,
  1341. X    "seq",        FT_INT,        Offset(struct game *,seq),    0,
  1342. X    "lastop",    FT_STRLKUP,    Offset(struct game *,lastop),
  1343. X        (int) opcodes,
  1344. X    "mycmt",    FT_STRING,    Offset(struct game *,mycmt),    NULL,
  1345. X    "mycmt2",    FT_STRING,    Offset(struct game *,mycmt2),    NULL,
  1346. X    "opcmt",    FT_STRING,    Offset(struct game *,opcmt),    NULL,
  1347. X    "opcmt2",    FT_STRING,    Offset(struct game *,opcmt2),    NULL,
  1348. X    "dispmsg",    FT_STRING,    Offset(struct game *,dispmsg),    NULL,
  1349. X    "opmvs0",    FT_MOVE,    Offset(struct game *,opmvs[0]),    0,
  1350. X    "opmvs1",    FT_MOVE,    Offset(struct game *,opmvs[1]),    0,
  1351. X    "opmvs2",    FT_MOVE,    Offset(struct game *,opmvs[2]),    0,
  1352. X    "opmvs3",    FT_MOVE,    Offset(struct game *,opmvs[3]),    0,
  1353. X    "blot0",    FT_CHAR,    Offset(struct game *,blot[0]),    0,
  1354. X    "blot1",    FT_CHAR,    Offset(struct game *,blot[1]),    0,
  1355. X    "blot2",    FT_CHAR,    Offset(struct game *,blot[2]),    0,
  1356. X    "blot3",    FT_CHAR,    Offset(struct game *,blot[3]),    0,
  1357. X    "mvs0",        FT_MOVE,    Offset(struct game *,mvs[0]),    0,
  1358. X    "mvs1",        FT_MOVE,    Offset(struct game *,mvs[1]),    0,
  1359. X    "mvs2",        FT_MOVE,    Offset(struct game *,mvs[2]),    0,
  1360. X    "mvs3",        FT_MOVE,    Offset(struct game *,mvs[3]),    0,
  1361. X    "maxused",    FT_INT,        Offset(struct game *,maxused),    0,
  1362. X    "hiused",    FT_INT,        Offset(struct game *,hiused),    0,
  1363. X    "adcnt",    FT_INT,        Offset(struct game *,adcnt),    0,
  1364. X    "admax",    FT_INT,        Offset(struct game *,admax),    0,
  1365. X    "opbd",        FT_BOARD,    Offset(struct game *,opbd[0]),    0,
  1366. X    "mybd",        FT_BOARD,    Offset(struct game *,mybd[0]),    0,
  1367. X    "board",    FT_BOARD,    Offset(struct game *,board[0]),    0,
  1368. X    "curbd",    FT_CHAR,    Offset(struct game *,curbd),    -1,
  1369. X    "rolls",    FT_INTARRAY,    Offset(struct game *,rolls[0]),    6,
  1370. X    "doubles",    FT_INTARRAY,    Offset(struct game *,doubles[0]),6,
  1371. X    "oprolls",    FT_INTARRAY, Offset(struct game *,oprolls[0]),    6,
  1372. X    "opdoubles",    FT_INTARRAY, Offset(struct game *,opdoubles[0]),6,
  1373. X    "starttime",    FT_TIME,    Offset(struct game *,starttime),0,
  1374. X    "lastacc",    FT_TIME,    Offset(struct game *,lastacc),    0,
  1375. X    "mcurrent",    FT_INTARRAY,    Offset(struct game *,mcurrent[0]),2,
  1376. X    "mtotal",    FT_INT,        Offset(struct game *,mtotal),    0,
  1377. X    "notify",    FT_STRING,    Offset(struct game *,notify),    NULL,
  1378. X    "end",        FT_END,        -1,    0,
  1379. X    NULL,        0,        -1,    0
  1380. X    };
  1381. X
  1382. Xstruct namevalue nv_packet[] = {
  1383. X    "version",    FT_INT,        Offset(struct packet *,version),0,
  1384. X    "timestamp",    FT_TIME,    Offset(struct packet *,timestamp),0,
  1385. X    "gameid",    FT_STRING,    Offset(struct packet *,gameid),    NULL,
  1386. X    "opcode",    FT_STRLKUP,    Offset(struct packet *,opcode),
  1387. X        (int) opcodes,
  1388. X    "move0",    FT_MOVE,    Offset(struct packet *,mvs[0]),    0,
  1389. X    "move1",    FT_MOVE,    Offset(struct packet *,mvs[1]),    0,
  1390. X    "move2",    FT_MOVE,    Offset(struct packet *,mvs[2]),    0,
  1391. X    "move3",    FT_MOVE,    Offset(struct packet *,mvs[3]),    0,
  1392. X    "name",        FT_STRING,    Offset(struct packet *,name),    NULL,
  1393. X    "addr",        FT_STRING,    Offset(struct packet *,addr),    NULL,
  1394. X    "comment",    FT_STRING,    Offset(struct packet *,comment),NULL,
  1395. X    "comment2",    FT_STRING,    Offset(struct packet *,comment2),NULL,
  1396. X    "seq",        FT_INT,        Offset(struct packet *,seq),    0,
  1397. X    "colors",    FT_STRING,    Offset(struct packet *,colors),    NULL,
  1398. X    "direction",    FT_STRING,    Offset(struct packet *,dir),    NULL,
  1399. X    "autodouble",    FT_STRING,    Offset(struct packet *,autodbl),NULL,
  1400. X    "jacoby",    FT_STRING,    Offset(struct packet *,jacoby), NULL,
  1401. X    "crawford",    FT_STRING,    Offset(struct packet *,crawford),NULL,
  1402. X    "european",    FT_STRING,    Offset(struct packet *,european),NULL,
  1403. X    "permanent",    FT_STRING,    Offset(struct packet *,perm),    NULL,
  1404. X    "match",    FT_STRING,    Offset(struct packet *,match),  NULL,
  1405. X    "notify",    FT_STRING,    Offset(struct packet *,notify),    NULL,
  1406. X    "end",        FT_END,        -1,    0,
  1407. X    NULL,        0,        -1,    0
  1408. X    };
  1409. X
  1410. Xstruct namevalue nv_pfile[] = {
  1411. X    "addr",        FT_STRING,    Offset(struct people *,addr),    NULL,
  1412. X    "name",        FT_STRING,    Offset(struct people *,name),    NULL,
  1413. X    "alias",    FT_STRING,    Offset(struct people *,alias),    NULL,
  1414. X    "myaddr",    FT_STRING,    Offset(struct people *,myaddr),    NULL,
  1415. X    "newaddr",    FT_INT,        Offset(struct people *,newaddr),0,
  1416. X    "equiv",    FT_STRING,    Offset(struct people *,equiv),    NULL,
  1417. X    "opversion",    FT_INT,        Offset(struct people *,opver),    0,
  1418. X    "fence",    FT_TIME,    Offset(struct people *,fence),    0,
  1419. X    "score",    FT_INTARRAY,    Offset(struct people *,score[0]), 10,
  1420. X    "end",        FT_END,        -1,    0,
  1421. X    NULL,        0,        -1,    0
  1422. X    };
  1423. X
  1424. Xstruct namevalue nv_pequiv[] = {
  1425. X    "addr",        FT_STRING,    Offset(struct people *,addr),    NULL,
  1426. X    "equiv",    FT_STRING,    Offset(struct people *,equiv),    NULL,
  1427. X    "end",        FT_END,        -1,    0,
  1428. X    NULL,        0,        -1,    0
  1429. X    };
  1430. X
  1431. Xint (*func[OPSTATES][NOP])() = {
  1432. X/*    START    USTART    TIE    MOVE    OFRDBL    ACPTDBL
  1433. X        DECDBL    CONCEDE    RSTART    RESTART    MSTART    RESEND    NOTIFY    */
  1434. X    start,    istart,    tie,    opmove,    smerr,    smerr,
  1435. X        smerr,    opconc,    smerr,    restart,mstart,    smerr,    smerr,
  1436. X    smerr,    smerr,    smerr,    opmove,    opofr,    smerr,
  1437. X        smerr,    opconc,    smerr,    smerr,    smerr,    smerr,    smerr,
  1438. X    smerr,    smerr,    smerr,    smerr,    smerr,    opacpt,
  1439. X        opdec,    opconc,    smerr,    smerr,    smerr,    smerr,    smerr
  1440. X    };
  1441. X
  1442. Xchar *rejlcl[] = {            /* reject messages for local player */
  1443. X    "",                    /* no error */
  1444. X    "Move does not contain a legal roll.",    /* shouldn't happen */
  1445. X    "You must fill your inner table before bearing off.",
  1446. X    "There is no piece on that point.",
  1447. X    "The destination of that move is occupied.",
  1448. X    "You cannot move while you are on the bar.",
  1449. X    "You can't move your opponent's pieces.",
  1450. X    "You must bear that piece off with an exact roll."
  1451. X    };
  1452. X
  1453. Xchar *rejmsg[] = {        /* reject messages for received moves */
  1454. X    "Move Accepted.",                /* no error */
  1455. X    "Move does not contain a legal roll.",        /* bad roll */
  1456. X    "Cannot remove pieces before filling inner table.",
  1457. X    "There is no piece at the specified location.",
  1458. X    "The destination of this move is occupied.",
  1459. X    "Attempt to move while pieces are on the bar.",
  1460. X    "Attempt to move wrong color.",
  1461. X    "That piece must be borne off by an exact roll."
  1462. X    };
  1463. END_OF_FILE
  1464. if test 11599 -ne `wc -c <'vars.c'`; then
  1465.     echo shar: \"'vars.c'\" unpacked with wrong size!
  1466. fi
  1467. # end of 'vars.c'
  1468. fi
  1469. echo shar: End of archive 2 \(of 12\).
  1470. cp /dev/null ark2isdone
  1471. MISSING=""
  1472. for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
  1473.     if test ! -f ark${I}isdone ; then
  1474.     MISSING="${MISSING} ${I}"
  1475.     fi
  1476. done
  1477. if test "${MISSING}" = "" ; then
  1478.     echo You have unpacked all 12 archives.
  1479.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1480. else
  1481.     echo You still need to unpack the following archives:
  1482.     echo "        " ${MISSING}
  1483. fi
  1484. ##  End of shell archive.
  1485. exit 0
  1486.  
  1487. exit 0 # Just in case...
  1488.