home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume28 / ldb / part02 < prev    next >
Encoding:
Text File  |  1992-03-14  |  48.9 KB  |  1,433 lines

  1. Newsgroups: comp.sources.misc
  2. From: ROSS@emf780.den.mmc.com ("Perry R. Ross")
  3. Subject:  v28i094:  ldb - Play backgammon by e-mail, Part02/05
  4. Message-ID: <1992Mar13.035456.11725@sparky.imd.sterling.com>
  5. X-Md4-Signature: 169056609dd00471941cf5bbd9b2e59c
  6. Date: Fri, 13 Mar 1992 03:54:56 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: ROSS@emf780.den.mmc.com (Perry R. Ross)
  10. Posting-number: Volume 28, Issue 94
  11. Archive-name: ldb/part02
  12. Environment: UNIX, C, VMS, VAXC, CURSES, 32BIT
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then unpack
  16. # it by saving it into a file and typing "sh file".  To overwrite existing
  17. # files, type "sh file -c".  You can also feed this as standard input via
  18. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  19. # will see the following message at the end:
  20. #        "End of archive 2 (of 5)."
  21. # Contents:  ldb.h main.c misc.c r_xrand.c vars.c
  22. # Wrapped by ross@emf780 on Tue Mar 10 09:24:16 1992
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f 'ldb.h' -a "${1}" != "-c" ; then 
  25.   echo shar: Will not clobber existing file \"'ldb.h'\"
  26. else
  27. echo shar: Extracting \"'ldb.h'\" \(11498 characters\)
  28. sed "s/^X//" >'ldb.h' <<'END_OF_FILE'
  29. X/*    ldb.h        8/3/91
  30. X *
  31. X * Copyright 1991  Perry R. Ross
  32. X *
  33. X * Permission to use, copy, modify, and distribute this software and its
  34. X * documentation without fee is hereby granted, subject to the restrictions
  35. X * detailed in the README file, which is included here by reference.
  36. X * Any other use requires written permission from the author.  This software
  37. X * is distributed "as is" without any warranty, including any implied
  38. X * warranties of merchantability or fitness for a particular purpose.
  39. X * The author shall not be liable for any damages resulting from the
  40. X * use of this software.  By using this software, the user agrees
  41. X * to these terms.
  42. X */
  43. X
  44. X#include "patchlevel.h"
  45. X
  46. X#define LDB_VER        ((VERSION*100)+PATCHLEVEL)    /* used in sendpkt */
  47. X
  48. X#include <stdio.h>
  49. X#include <ctype.h>
  50. X#include <curses.h>
  51. X#include <signal.h>
  52. X
  53. X#ifdef vaxc
  54. X#define OLD_CURSES 1
  55. X#define unlink(X) delete(X)
  56. X#endif
  57. X
  58. X#ifdef sequent
  59. X#define OLD_CURSES 1
  60. X#endif
  61. X
  62. X#ifdef OLD_CURSES
  63. X#define cbreak() crmode()    /* from ancient curses */
  64. X#define nocbreak() nocrmode()
  65. X#endif
  66. X
  67. X    /* swiped from X toolkit */
  68. X#define Offset(T,F) ((int)(((char *)(&(((T)NULL)->F)))-((char *)NULL)))
  69. X
  70. X#define PRIVATE static        /* for private functions */
  71. X
  72. X#define INTGFILE "interrupt.ldbdata"    /* file to save games to on ^C */
  73. X#define BLANKS(X) (&blk76[76-(X)])    /* blank string of specified length */
  74. X
  75. X        /* locations in board typedef */
  76. X#define UPBAR        0        /* BAR point for up-bound player */
  77. X#define DOWNBAR        25        /* BAR point for down-bound player */
  78. X#define UPOFF        26        /* off point for up-bound player */
  79. X#define DOWNOFF        27        /* off point for down-bound player */
  80. X#define BOARDSIZE    28        /* number of points in board */
  81. X
  82. X    /* BARPT takes a direction (-1 or 1) and returns the    */
  83. X    /* point in the board typedef that represents that    */
  84. X    /* players bar.  OFFPT does the same thing for the    */
  85. X    /* point that pieces go to when they are thrown off.    */
  86. X    /* REV(direction) returns the opposite direction.    */
  87. X#define BARPT(D)    (((D)>0)?UPBAR:DOWNBAR)
  88. X#define OFFPT(D)    (((D)>0)?UPOFF:DOWNOFF)
  89. X#define REV(D)        (-(D))
  90. X
  91. X        /* states we can be in */
  92. X#define ST_OPSTART    0        /* we have sent a START (or rcvd one)*/
  93. X#define ST_OPTURN    1        /* Its the opponent's turn */
  94. X#define ST_OPACCEPT    2        /* I have offered to double */
  95. X
  96. X#define OPSTATES    3        /* < OPSTATES needs remote input */
  97. X
  98. X#define ST_MYTURN    3        /* My turn, I haven't rolled yet */
  99. X#define ST_MYMOVE    4        /* I've rolled, but I haven't moved */
  100. X#define ST_MYACCEPT    5        /* Opponent has offered to double */
  101. X#define ST_GAMEOVER    6        /* game is dead, see T_* for reason */
  102. X#define NSTATE        7        /* number of possible states */
  103. X
  104. X        /* operations to send or receive */
  105. X#define START        0        /* start a game */
  106. X#define USTART        1        /* if rcvd, we won the initial roll */
  107. X#define TIE        2        /* tie on initial roll, restart */
  108. X#define MOVE        3        /* send a move */
  109. X#define OFRDBL        4        /* offer to double */
  110. X#define ACPTDBL        5        /* double accepted */
  111. X#define DECDBL        6        /* double declined, game over */
  112. X#define CONCEDE        7        /* we give up */
  113. X#define RSTART        8        /* remote start packet */
  114. X#define RESTART        9        /* repeat initial roll */
  115. X#define NOP        10        /* number of possible operations */
  116. X
  117. X        /* termination codes for state ST_GAMEOVER */
  118. X#define T_ICONCEDE    1        /* I gave up */
  119. X#define T_OPCONCEDE    2        /* opponent gave up */
  120. X#define T_IDECLINE    3        /* I declined double */
  121. X#define T_OPDECLINE    4        /* opponent declined double */
  122. X#define T_ILOSE        5        /* opponent moved all pieces off */
  123. X#define T_IWIN        6        /* I moved all pieces off */
  124. X
  125. X        /* flags passed to apply */
  126. X#define A_REDRAW    1    /* redraw the pieces moved */
  127. X#define A_CHKONLY    2    /* check move but don't move pieces */
  128. X
  129. X        /* codes returned by apply */
  130. X#define MVOK        0    /* move was accepted by apply() */
  131. X#define RJ_NOROLL    -1    /* move does not contain valid roll */
  132. X#define RJ_NOOFF    -2    /* all pcs not in inner tbl, can't throw off */
  133. X#define RJ_NOPIECE    -3    /* no piece at specified point */
  134. X#define RJ_OCC        -4    /* destination occupied */
  135. X#define RJ_ONBAR    -5    /* can't move, pieces are on bar */
  136. X#define RJ_NOTYOURS    -6    /* wrong color, dummy */
  137. X#define RJ_EXACT    -7    /* must use exact roll except for outer pc */
  138. X
  139. X        /* bits for flags field of game struct */
  140. X#define F_IDOUBLED    1    /* I doubled last */
  141. X#define F_SENTNAME    2    /* I sent my name */
  142. X#define F_INVERT    4    /* I want my board upside down */
  143. X#define F_DELETE    8    /* this game is deleted */
  144. X
  145. X        /* field types for reading name/value files */
  146. X#define FT_CHAR        1    /* store a single character */
  147. X#define FT_INT        2    /* store a single integer */
  148. X#define FT_STRING    3    /* store a char * (use save()) */
  149. X#define FT_MOVE        4    /* a struct mv */
  150. X#define FT_BOARD    5    /* a board image */
  151. X#define FT_STRLKUP    6    /* lookup string in table & store index */
  152. X#define FT_TIME        7    /* a timestamp */
  153. X#define FT_END        99    /* end of structure */
  154. X
  155. X        /* which board is currently displayed (g->curbd) */
  156. X#define BD_BEFOP    0    /* before op's move (after my previous) */
  157. X#define BD_AFTOP    1    /* after op's move (before my next) */
  158. X#define BD_CUR        2    /* current (with any moves I've made so far) */
  159. X
  160. X        /* these are the command line options */
  161. X#define OPT_START    1    /* start a game */
  162. X#define OPT_READ    2    /* read incoming mail */
  163. X#define OPT_PLAY    3    /* play any games that are waiting for me */
  164. X#define OPT_COLOR    4    /* set the color for created games */
  165. X#define OPT_DIRECTION    5    /* set the direction for created games */
  166. X#define OPT_RSTART    6    /* remote start a game */
  167. X#define OPT_HELP    7    /* print long help */
  168. X#define OPT_CONTROL    8    /* go into control mode */
  169. X#define OPT_MYADDR    9    /* set my e-mail address (override .ldbrc) */
  170. X#define OPT_BCAST    10    /* send a mail message to all opponents */
  171. X
  172. Xstruct opt {            /* used to make list of command line options */
  173. X    char    *name;        /* name of option (as used on command line) */
  174. X    int    index;        /* OPT_* */
  175. X    char    *args;        /* arguments the option takes, if any */
  176. X    char    *help;        /* 1-line help string for option */
  177. X    };
  178. X
  179. Xstruct ldbrc {        /* struct where all fields from .ldbrc are stored */
  180. X    char    *myaddr;    /* my e-mail address */
  181. X    char    *myname;    /* my name */
  182. X    char    *gfile;        /* games file */
  183. X    char    *gbackup;    /* where to save old game file */
  184. X    char    *mfile;        /* mail file */
  185. X    char    *sendcmd;    /* mail send command */
  186. X    char    *tempfile;    /* temp file for sendpkt */
  187. X    char    *defclrs;    /* default colors (2 from [rwb]) */
  188. X    char    *defdir;    /* default direction (up/down) */
  189. X    char    *initboard;    /* init. brd display (before/after/current) */
  190. X    char    *autoroll;    /* enable autoroll? (yes/no) */
  191. X    char    *automove;    /* enable automove? (yes/no) */
  192. X    int    autodouble;    /* autodouble count, 0 to disable */
  193. X    char    *supercmd;    /* command to run to fool supervisor */
  194. X    char    superkey;    /* key to activate supercmd */
  195. X    char    *chkpt;        /* keep games up to date? */
  196. X    };
  197. X
  198. X        /* the following structure is used to save/load */
  199. X        /* the games file, the .ldbrc, and to send    */
  200. X        /* packets between the players.  It stores a    */
  201. X        /* name, the type (see FT_* above), and the    */
  202. X        /* offset into a structure.  A pointer to the    */
  203. X        /* structure is provided at runtime.        */
  204. Xstruct namevalue {
  205. X       char *name;        /* name of the field */
  206. X       char type;        /* type of the field (T_*) */
  207. X       int offset;        /* where to store value */
  208. X       };
  209. X
  210. Xunion nvtypes {            /* convert char* to/from FT_* */
  211. X    char    *nvchar;    /* FT_CHAR */
  212. X    int    *nvint;        /* FT_INT */
  213. X    long    *nvtime;    /* FT_TIME */
  214. X    char    **nvstring;    /* FT_STRING */
  215. X    struct mv *nvmove;    /* FT_MOVE */
  216. X    struct point *nvboard;    /* FT_BOARD */
  217. X    };
  218. X
  219. Xstruct mv {
  220. X    char    roll;            /* # on 1 die, 0 = DOUBLE, -1=empty */
  221. X    char    pt;            /* point move is from, -1=UNUSED */
  222. X    };
  223. X
  224. Xstruct point {
  225. X    char    qty;            /* number of pieces on this point */
  226. X    char    color;            /* color of pieces on this point */
  227. X    };
  228. X
  229. Xtypedef struct point board[BOARDSIZE];    /* board is array of points */
  230. X
  231. Xstruct game {                /* all info about a game in progress */
  232. X    char    *gameid;        /* unique game id */
  233. X    char    *opaddr;        /* email path to opponent */
  234. X    char    *opname;        /* full name of opponent */
  235. X    char    mycolor;        /* char to represent my pieces */
  236. X    char    opcolor;        /* opponent's pieces */
  237. X    char    mydir;            /* 1/-1 direction I am moving */
  238. X    char    opdir;            /* 1/-1 direction opponent is moving */
  239. X    int    gameval;        /* current value of game */
  240. X    int    adcnt;            /* current number of autodoubles */
  241. X    int    admax;            /* max autodoubles allowed */
  242. X    int    flags;            /* various flags (F_*) */
  243. X    char    state;            /* my current state (ST_*) */
  244. X    char    term;            /* if game over, why (T_*) */
  245. X    int    seq;            /* sequence number of next pkt */
  246. X    int    lastop;            /* last opcode sent (for resends) */
  247. X    char    *mycmt;            /* comment I sent with last move */
  248. X    char    *mycmt2;        /* second line of mycmt */
  249. X    char    *opcmt;            /* comment I received with last move */
  250. X    char    *opcmt2;        /* second line of opcmt */
  251. X    char    *dispmsg;        /* msg to display when game drawn */
  252. X    struct mv opmvs[4];        /* opponent's last move */
  253. X    char    blot[4];        /* my blots that were hit */
  254. X    struct mv mvs[4];        /* my move, holds roll until I move */
  255. X    int    maxused;        /* # of rolls in mvs that can be used*/
  256. X    int    hiused;            /* highest roll that can be used */
  257. X    board    opbd;            /* board image before opmvs applied */
  258. X    board    mybd;            /* board before mvs (for Reset) */
  259. X    board    board;            /* current board image */
  260. X    char    curbd;            /* which brd is currently displayed */
  261. X    struct game *prev;        /* back link in game list */
  262. X    struct game *next;        /* forward link in game list */
  263. X    };
  264. X
  265. Xstruct packet {
  266. X    int    version;        /* ldb version */
  267. X    long    timestamp;        /* time packet was sent */
  268. X    char    *gameid;        /* the gameid string */
  269. X    int    opcode;            /* operation being performed */
  270. X    char    *name;            /* name */
  271. X    char    *addr;            /* mail address */
  272. X    char    *comment;        /* comment received */
  273. X    char    *comment2;        /* second line of comment */
  274. X    int    seq;            /* sequence number */
  275. X    char    *colors;        /* colors of new game */
  276. X    char    *dir;            /* direction of game starter */
  277. X    char    *autodbl;        /* autodouble count (sprintf'ed) */
  278. X    struct mv mvs[4];        /* moves (if opcode == MOVE) */
  279. X    struct game *gameptr;        /* not a pkt field, set by getpkt() */
  280. X    };
  281. X
  282. Xstruct legal {                /* list of legal moves */
  283. X    int nmove;            /* number of moves in this entry */
  284. X    int himove;            /* highest roll used in this entry */
  285. X    struct mv mvs[4];        /* the rolls and moves */
  286. X    struct legal *prev;        /* pointer to the previous entry */
  287. X    struct legal *next;        /* pointer to the previous entry */
  288. X    };
  289. X
  290. Xextern int Pflag;            /* should I process local input? */
  291. Xextern int Rflag;            /* should I look for mail? */
  292. Xextern struct game *ghead;        /* head of linked list of games */
  293. Xextern struct game *gtail;        /* tail of linked list of games */
  294. Xextern struct legal *lhead;        /* head of list of legal moves */
  295. Xextern struct legal *ltail;        /* tail of list of legal moves */
  296. Xextern int (*func[OPSTATES][NOP])();    /* receive state machine */
  297. Xstruct ldbrc rc;            /* stuff from .ldbrc */
  298. Xextern struct opt options[];        /* command line options */
  299. Xextern char *rejmsg[];            /* explanation of reject codes */
  300. Xextern char *opcodes[];
  301. Xextern char *bdlabels[];
  302. Xextern char blk76[];            /* 76 blanks */
  303. Xextern struct packet P;            /* last packet read */
  304. Xextern char cr_mycolor;            /* my color when game is created */
  305. Xextern char cr_opcolor;            /* opponent's color for new games */
  306. Xextern char cr_mydir;            /* my direction for new games */
  307. Xextern char *states[];            /* description of the states */
  308. X
  309. Xextern char FeIsActive;            /* front-end been initialized? */
  310. X
  311. Xextern struct namevalue nv_rcfile[], nv_gfile[], nv_packet[];
  312. X
  313. Xchar *tgetstr();
  314. Xchar *save(), *makeid(), *calloc();
  315. Xchar *nvscan(), *strchr(), *boardstr(), *colorname();
  316. Xstruct game *startgame(), *addgame(), *findgame();
  317. X
  318. Xint start(), istart(), tie(), restart();
  319. Xint opmove(), opofr(), opconc(), opacpt(), opdec();
  320. Xint smerr();
  321. X
  322. Xchar FeMenu();
  323. END_OF_FILE
  324. if test 11498 -ne `wc -c <'ldb.h'`; then
  325.     echo shar: \"'ldb.h'\" unpacked with wrong size!
  326. fi
  327. chmod +x 'ldb.h'
  328. # end of 'ldb.h'
  329. fi
  330. if test -f 'main.c' -a "${1}" != "-c" ; then 
  331.   echo shar: Will not clobber existing file \"'main.c'\"
  332. else
  333. echo shar: Extracting \"'main.c'\" \(10795 characters\)
  334. sed "s/^X//" >'main.c' <<'END_OF_FILE'
  335. X/*    main.c        8/3/91
  336. X *
  337. X * Copyright 1991  Perry R. Ross
  338. X *
  339. X * Permission to use, copy, modify, and distribute this software and its
  340. X * documentation without fee is hereby granted, subject to the restrictions
  341. X * detailed in the README file, which is included here by reference.
  342. X * Any other use requires written permission from the author.  This software
  343. X * is distributed "as is" without any warranty, including any implied
  344. X * warranties of merchantability or fitness for a particular purpose.
  345. X * The author shall not be liable for any damages resulting from the
  346. X * use of this software.  By using this software, the user agrees
  347. X * to these terms.
  348. X */
  349. X
  350. X#include "ldb.h"
  351. X
  352. X/*============================================================================
  353. X *    ldb --    Long Distance Backgammon
  354. X *
  355. X * The following arguments are recognized:
  356. X *    -read        Mail is read, and the games are updated and saved.
  357. X *            The user is not prompted for his moves.
  358. X *    -play        Any games that are waiting for local input are
  359. X *            displayed for the user to process.  No mail is read.
  360. X *    -color xy    The colors for any games started are set to x and y.
  361. X *            The first color is played by the local user, and the
  362. X *            other is played by the opponent.  Legal color
  363. X *            characters are r(red), w(white), and b(black).
  364. X *            The default is "-color rw".
  365. X *    -direction up/down
  366. X *            The direction of play for the local user is set
  367. X *            to the specified value.  The default is
  368. X *            "-direction up".
  369. X *    -myaddr addr    Override the "myaddr" field of .ldbrc for any
  370. X *            games started by this invocation of ldb.  This
  371. X *            is effective only for games started by -start
  372. X *            and only for -start's that appear after the -myaddr
  373. X *            on the command line.
  374. X *    -start user    A game is started with the specified user.
  375. X *    -remotestart user1 user2
  376. X *            A game is started between user1 and user2.  The local
  377. X *            host sends a remote start message to user1 instructing
  378. X *            it to start a game with user2.  The local host
  379. X *            does not participate thereafter in the game.
  380. X *            For the purposes of the -color and -direction options,
  381. X *            user1 is considered the local user.
  382. X *    -broadcast file
  383. X *            A file is mailed to all opponents.  This is useful
  384. X *            for announcing vacation absences, etc.
  385. X *
  386. X * If neither -read or -play is given, the default is to do both; incoming mail
  387. X * is read, then any games requiring the user's attention are displayed.
  388. X *
  389. X * Note that the -start and -remotestart options use the color and direction
  390. X * options that have been set *at the time the argument is processed*.
  391. X * Thus,
  392. X *
  393. X *    ldb -start joe@momma -color rb
  394. X *
  395. X * will NOT use the colors r and b for the game with joe, but
  396. X *
  397. X *    ldb -color rb -start joe@momma
  398. X *
  399. X * will.  The color and direction arguments may be changed between -start
  400. X * and -remotestart arguments.  For example,
  401. X *
  402. X *    ldb -color wr -direction down -start user1 -direction up -start user2
  403. X *
  404. X * will start a game with user1 with your direction being down, and one with
  405. X * user2 with your direction being up.
  406. X *----------------------------------------------------------------------------
  407. X */
  408. X
  409. Xmain(argc,argv)
  410. Xint argc;
  411. Xchar *argv[];
  412. X{
  413. Xstruct game *g;
  414. Xchar subj[128];
  415. Xint i, j;
  416. Xchar c;
  417. Xint done;
  418. Xint ldbsignal();
  419. X
  420. Xghead = NULL;            /* init game list to empty */
  421. Xgtail = NULL;
  422. Xsignal(SIGINT,ldbsignal);    /* set up interrupt trap to save games */
  423. XRflag = 1;        /* should we try to extract incoming mail? */
  424. XPflag = 1;        /* should we process waiting games? */
  425. XRandomInit(time(0));    /* seed the random number generator */
  426. X
  427. Xreadldbrc();        /* read startup file */
  428. X
  429. Xcr_mycolor = rc.defclrs[0];    /* default color when creating games */
  430. Xcr_opcolor = rc.defclrs[1];
  431. Xcr_mydir = (*rc.defdir == 'u') ? 1 : -1;    /* default direction */
  432. X
  433. Xreadgames();        /* load games in progress */
  434. X
  435. Xfor (i = 1; (i < argc) && (argv[i][0] == '-'); i++) {
  436. X    for (j = 0; options[j].name != NULL; j++)    /* look for arg */
  437. X        if (strcmp(options[j].name,&argv[i][1]) == 0)
  438. X            break;
  439. X    if (options[j].name == NULL) {
  440. X        printf("%s:\tunrecognized option: %s\n\n",*argv,argv[i]);
  441. X        usage(0);        /* print short help */
  442. X        exit(1);
  443. X        }
  444. X    switch (options[j].index) {
  445. X    case OPT_START:            /* start a game */
  446. X        i++;
  447. X        if (argv[i] == NULL) {
  448. X            printf("%s: -start needs argument\n",*argv);
  449. X            usage(0);
  450. X            exit(1);
  451. X            }
  452. X        startgame(argv[i],cr_mydir,cr_mycolor,cr_opcolor);
  453. X        break;
  454. X    case OPT_READ:
  455. X        Pflag = 0;        /* just read, no processing */
  456. X        break;
  457. X    case OPT_PLAY:
  458. X        Rflag = 0;        /* just process, no read */
  459. X        break;
  460. X    case OPT_MYADDR:        /* set my e-mail address */
  461. X        i++;
  462. X        if (argv[i] == NULL) {
  463. X            printf("%s: -myaddr needs argument\n",*argv);
  464. X            usage(0);
  465. X            exit(1);
  466. X            }
  467. X        strcpy(rc.myaddr,argv[i]);    /* copy in new address */
  468. X        break;
  469. X    case OPT_HELP:            /* print long help */
  470. X        usage(1);
  471. X        exit(0);
  472. X    case OPT_RSTART:        /* remote start */
  473. X        i++;
  474. X        if ( (argv[i] == NULL) || (argv[i+1] == NULL) ) {
  475. X            printf("%s: -remotestart needs two arguments\n",*argv);
  476. X            usage(0);
  477. X            exit(1);
  478. X            }
  479. X        remotestart(argv[i],argv[i+1]);
  480. X        i++;
  481. X        break;
  482. X    case OPT_COLOR:            /* set colors */
  483. X        if (argv[++i] == NULL) {
  484. X            printf("%s: -color option needs argument\n",*argv);
  485. X            usage(0);
  486. X            exit(1);
  487. X            }
  488. X        cr_mycolor = argv[i][0];    /* first char is my color */
  489. X        if (isupper(cr_mycolor))    /* convert to lower case */
  490. X            cr_mycolor = tolower(cr_mycolor);
  491. X        cr_opcolor = argv[i][1]; /* second char is opponent's color */
  492. X        if (isupper(cr_opcolor))    /* convert to lower case */
  493. X            cr_opcolor = tolower(cr_opcolor);
  494. X        if (strchr("rwb",cr_mycolor) == NULL) {
  495. X            printf("%s: invalid color: %c\n",*argv,cr_mycolor);
  496. X            usage(0);
  497. X            exit(1);
  498. X            }
  499. X        if (strchr("rwb",cr_opcolor) == NULL) {
  500. X            printf("%s: invalid color: %c\n",*argv,cr_opcolor);
  501. X            usage(0);
  502. X            exit(1);
  503. X            }
  504. X        if (cr_mycolor == cr_opcolor) {
  505. X            printf("%s: duplicate color: %c\n",*argv,cr_mycolor);
  506. X            usage(0);
  507. X            exit(1);
  508. X            }
  509. X        break;
  510. X    case OPT_DIRECTION:        /* set direction */
  511. X        if (argv[++i] == NULL) {
  512. X            printf("%s: -direction option needs argument\n",*argv);
  513. X            usage(0);
  514. X            exit(1);
  515. X            }
  516. X        c = argv[i][0];
  517. X        if (isupper(c))
  518. X            c = tolower(c);
  519. X        if (c == 'u')
  520. X            cr_mydir = 1;        /* I play up */
  521. X        else if (c == 'd')
  522. X            cr_mydir = -1;        /* I play down */
  523. X        else {
  524. X            printf("%s: invalid direction: %s\n",*argv,argv[i]);
  525. X            usage(0);
  526. X            exit(1);
  527. X            }
  528. X        break;
  529. X    case OPT_BCAST:                /* broadcast a message */
  530. X        if (argv[++i] == NULL) {
  531. X            printf("%s: -broadcast option needs argument\n",*argv);
  532. X            usage(0);
  533. X            exit(1);
  534. X            }
  535. X        sprintf(subj,"LDB Broadcast Message from %s",rc.myname);
  536. X        for (g = ghead; g != NULL; g = g->next)
  537. X            TSendFile(g->opaddr,argv[i],subj);
  538. X        break;
  539. X    case OPT_CONTROL:            /* control my games */
  540. X        control();
  541. X        exit(0);
  542. X    default:
  543. X        fprintf(stderr,
  544. X           "Sorry, the %s option is not implemented yet.\n",
  545. X            options[j].name);
  546. X        exit(1);
  547. X        }
  548. X    }
  549. Xif ( (Pflag == 0) && (Rflag == 0) ) {    /* user gave both -play and -read */
  550. X    Pflag = 1;            /* turn both back on */
  551. X    Rflag = 1;
  552. X    }
  553. Xwhile (i < argc)        /* if files given on command line, read them */
  554. X    readmail(argv[i++]);
  555. Xif (Rflag)            /* if we are supposed to read default file */
  556. X    readmail(rc.mfile);    /* do that too */
  557. Xi = 0;
  558. Xfor (g = ghead; g != NULL; g = g->next)        /* does any game need */
  559. X    if (g->state >= OPSTATES)        /* our input? */
  560. X        i++;
  561. Xif ( (i == 0) || (Pflag == 0) ) {        /* if not, exit */
  562. X    writegames(rc.gfile,rc.gbackup);    /* save games */
  563. X    exit(0);
  564. X    }
  565. XTInitialize();                    /* fire up the transport */
  566. XFeInitialize();                    /* fire up the front end */
  567. XFeDrawScreen();                /* draw the screen outline */
  568. Xfor (g = ghead, done = 0; (g != NULL) && (done >= 0); g = g->next)
  569. X    while ( (done = process(g)) > 0);    /* process game til done */
  570. XFeFinishSession();                /* close down the front end */
  571. XTFinishSession();                /* close down the transport */
  572. Xwritegames(rc.gfile,rc.gbackup);        /* save the games in a file */
  573. Xexit(0);
  574. X}
  575. X
  576. X
  577. X/*----------------------------------------------------------------------
  578. X *    ldbsignal -- signal handler
  579. X *
  580. X * This function is called when the user hits the interrupt character.
  581. X * It is currently a very simple function; it saves the games in the
  582. X * INTGFILE file, closes down the front end and the transport, and exits.
  583. X *----------------------------------------------------------------------
  584. X */
  585. X
  586. Xldbsignal()
  587. X{
  588. X
  589. Xwritegames(INTGFILE,NULL);
  590. XFeFinishSession();    /* let front-end close down gracefully */
  591. XTFinishSession();    /* let transport close down gracefully */
  592. Xfprintf(stderr,"WARNING: games saved in %s\n",INTGFILE);
  593. Xexit(1);
  594. X}
  595. X
  596. X
  597. X/*----------------------------------------------------------------------
  598. X *    usage -- print command line options.
  599. X *
  600. X * This function prints a help message.  This can be either in the
  601. X * short or long format.  The short format merely lists all options
  602. X * in a very dense format.  The long format prints each option on
  603. X * a separate line, along with a short explanation of its purpose.
  604. X *----------------------------------------------------------------------
  605. X */
  606. X
  607. Xusage(help)
  608. Xint help;        /* 0 = short message, 1 = long message */
  609. X{
  610. Xstruct opt *o;
  611. Xint l;
  612. X
  613. Xprintf("options:\n");
  614. Xif (help) {        /* print out the whole shootin' match */
  615. X    for (o = options; o->name != NULL; o++)
  616. X        printf("\t-%s%s:%s\n",o->name,o->args,o->help);
  617. X    printf("\nLdb version %d.%02d by Perry R. Ross.  Mail comments\n",
  618. X        VERSION,PATCHLEVEL);
  619. X    printf("or suggestions to \"%s\".\n",AUTHOR_EMAIL);
  620. X    }
  621. Xelse {
  622. X    l = 0;
  623. X    printf("\t");
  624. X    for (o = options; o->name != NULL; o++) {
  625. X        if ( (l += (strlen(o->name)+strlen(o->args)+3)) > 55) {
  626. X            printf("\n\t");
  627. X            l = 0;
  628. X            }
  629. X        printf("[-%s%s] ",o->name,o->args);
  630. X        }
  631. X    }
  632. Xprintf("\n\n");
  633. X}
  634. X
  635. X
  636. X/*----------------------------------------------------------------------
  637. X *    remotestart -- start a game between two other people
  638. X *
  639. X * This function tells a user to start a game with another user.
  640. X * Neither user needs to be the one running remotestart; although
  641. X * this would work, -start is a more efficient way to do that.
  642. X * Remotestart could be used to start games between opponents in
  643. X * a tournament, or to set up a pickup game facility, where people
  644. X * wanting to play would mail to a central machine, which would
  645. X * pair players by some criteria (such as ability) and start a
  646. X * game between them.
  647. X *----------------------------------------------------------------------
  648. X */
  649. X
  650. Xremotestart(u1,u2)
  651. Xchar *u1, *u2;
  652. X{
  653. Xstruct packet p;
  654. Xchar colors[4];
  655. X
  656. Xp.version = LDB_VER;        /* fill in a packet */
  657. Xp.gameid = "REMOTESTART";    /* give it a phony gameid */
  658. Xp.opcode = RSTART;        /* remote start opcode */
  659. Xp.name = NULL;            /* we don't need to send a name */
  660. Xp.addr = u2;            /* put opponent's address in packet */
  661. Xp.comment = NULL;        /* don't have a comment */
  662. Xp.comment2 = NULL;
  663. Xp.seq = 1;            /* start with sequence number 1 */
  664. Xclearmvs(p.mvs);        /* no moves to send */
  665. Xsprintf(colors,"%c%c",cr_mycolor,cr_opcolor);
  666. Xp.colors = colors;
  667. Xp.dir = (cr_mydir > 0) ? "up" : "down";
  668. XTSendPacket(&p,u1);        /* send the remote start command to u1 */
  669. X}
  670. END_OF_FILE
  671. if test 10795 -ne `wc -c <'main.c'`; then
  672.     echo shar: \"'main.c'\" unpacked with wrong size!
  673. fi
  674. chmod +x 'main.c'
  675. # end of 'main.c'
  676. fi
  677. if test -f 'misc.c' -a "${1}" != "-c" ; then 
  678.   echo shar: Will not clobber existing file \"'misc.c'\"
  679. else
  680. echo shar: Extracting \"'misc.c'\" \(6988 characters\)
  681. sed "s/^X//" >'misc.c' <<'END_OF_FILE'
  682. X/*    misc.c        8/8/91
  683. X *
  684. X * Copyright 1991  Perry R. Ross
  685. X *
  686. X * Permission to use, copy, modify, and distribute this software and its
  687. X * documentation without fee is hereby granted, subject to the restrictions
  688. X * detailed in the README file, which is included here by reference.
  689. X * Any other use requires written permission from the author.  This software
  690. X * is distributed "as is" without any warranty, including any implied
  691. X * warranties of merchantability or fitness for a particular purpose.
  692. X * The author shall not be liable for any damages resulting from the
  693. X * use of this software.  By using this software, the user agrees
  694. X * to these terms.
  695. X */
  696. X
  697. X#include "ldb.h"
  698. X
  699. X
  700. X/*----------------------------------------------------------------------
  701. X *    rolldice -- roll two dice
  702. X *
  703. X * This function calls Rolldie twice and fills in the game structure
  704. X * with the resulting values.  If the two calls to Rolldie return the
  705. X * same number, the mvs field is filled in so that the user has 4 rolls
  706. X * to use, otherwise the rolls are stored in the first two elements
  707. X * of the mvs field and the last two are marked unused.
  708. X *----------------------------------------------------------------------
  709. X */
  710. X
  711. Xrolldice(g)
  712. Xstruct game *g;
  713. X{
  714. X
  715. Xclearmvs(g->mvs);            /* clear old stuff */
  716. Xg->mvs[0].roll = Rolldie();             /* roll the dice */
  717. Xg->mvs[1].roll = Rolldie();
  718. Xif (g->mvs[0].roll == g->mvs[1].roll) {    /* hot damn, we got doubles */
  719. X    g->mvs[2].roll = g->mvs[0].roll;    /* copy roll into two */
  720. X    g->mvs[3].roll = g->mvs[0].roll;    /* more moves */
  721. X    }
  722. Xlegalmoves(g);            /* calculate the # of moves & hi roll */
  723. X}
  724. X
  725. X
  726. X
  727. X/*----------------------------------------------------------------------
  728. X *    sendpkt -- send a packet to the opponent
  729. X *
  730. X * This function fills in the fields of a packet and passes that
  731. X * packet to the transport using TSendPacket.  It also stores the
  732. X * opcode sent in the lastop field of the game, so the packet
  733. X * can be regenerated if necessary.
  734. X *----------------------------------------------------------------------
  735. X */
  736. X
  737. Xsendpkt(g,op)
  738. Xstruct game *g;
  739. Xchar op;
  740. X{
  741. Xstatic char colors[4], adbl[10];
  742. Xint i;
  743. X
  744. Xif (FeIsActive)
  745. X    FeMessage("Sending...");
  746. XP.version = LDB_VER;            /* these fields go in all packets */
  747. XP.gameid = g->gameid;
  748. XP.opcode = op;
  749. XP.seq = g->seq;
  750. XP.comment = g->mycmt;
  751. XP.comment2 = g->mycmt2;
  752. Xif ( (g->flags & F_SENTNAME) == 0) {    /* if I haven't already sent my name */
  753. X    P.name = rc.myname;        /* send it */
  754. X    g->flags |= F_SENTNAME;        /* set flag */
  755. X    }
  756. Xelse
  757. X    P.name = NULL;
  758. XP.addr = NULL;                /* these fields only used by START */
  759. XP.colors = NULL;
  760. XP.dir = NULL;
  761. XP.autodbl = NULL;            /* used by START and TIE */
  762. Xclearmvs(P.mvs);
  763. Xswitch (op) {                /* now do operation-specific stuff */
  764. Xcase START:
  765. X    P.addr = rc.myaddr;        /* send opponent my email address */
  766. X    P.mvs[0].roll = g->mvs[0].roll;    /* send initial die roll */
  767. X    sprintf(colors,"%c%c",g->mycolor,g->opcolor);
  768. X    P.colors = colors;
  769. X    P.dir = (g->mydir > 0) ? "down" : "up";
  770. X    sprintf(adbl,"%d",rc.autodouble);
  771. X    P.autodbl = adbl;
  772. X    break;
  773. Xcase USTART:
  774. X    P.mvs[0].roll = g->mvs[0].roll;    /* send both initial dice */
  775. X    P.mvs[1].roll = g->mvs[1].roll;
  776. X    break;
  777. Xcase RESTART:                /* retry initial roll */
  778. X    P.mvs[0].roll = g->mvs[0].roll;    /* send new roll */
  779. X    break;
  780. Xcase TIE:
  781. X    if (g->adcnt > 0) {        /* send current autodouble count */
  782. X        sprintf(adbl,"%d",g->adcnt);
  783. X        P.autodbl = adbl;
  784. X        }
  785. X    break;
  786. Xcase MOVE:
  787. X    for (i = 0; i < 4; i++)
  788. X        P.mvs[i] = g->mvs[i];
  789. X    break;
  790. X    }
  791. Xg->lastop = op;                /* save last op for resend */
  792. XTSendPacket(&P,g->opaddr);        /* send the packet */
  793. Xif (FeIsActive)                /* clear "Sending..." from mesg line */
  794. X    FeMessage(NULL);
  795. X}
  796. X
  797. X
  798. X
  799. X/*----------------------------------------------------------------------
  800. X *    str2mv -- decode move string to struct mv
  801. X *
  802. X * This function takes a string representation of a move, decodes it,
  803. X * and places the information into a mv structure.  This format is:
  804. X *
  805. X *    roll/move
  806. X *
  807. X * where roll is the die value used in the move, and is a single
  808. X * digit in [1..6], and move is one of the following:
  809. X *
  810. X *    a 1 or 2 digit number in [1..24]
  811. X *        This designates the point the move originates from.
  812. X *        This number is stored in the "pt" field of the move
  813. X *        structure without modification.
  814. X *    the string "BAR"
  815. X *        This means the piece is coming off the bar.
  816. X *        Zero is stored in the "pt" field of the move structure,
  817. X *        regardless of whether the player's bar point is 0 or 25.
  818. X *        Apply() and FeDrawMove understand this and convert 0 to
  819. X *        the appropriate bar point before using it.
  820. X *    the string "UNUSED"
  821. X *        This means the roll is unused.  -1 is stored in the
  822. X *        "pt" field of the mv structure.
  823. X *----------------------------------------------------------------------
  824. X */
  825. X
  826. Xstr2mv(s,m)
  827. Xchar *s;
  828. Xstruct mv *m;
  829. X{
  830. Xchar *p, *strchr();
  831. X
  832. Xif ( (p = strchr(s,'/')) == NULL) {
  833. X    fprintf(stderr,"ERROR: malformed move: %s\n",s);
  834. X    return;
  835. X    }
  836. Xif ( ( (m->roll = atoi(s)) < 0) || (m->roll > 6) ) {
  837. X    fprintf(stderr,"ERROR: invalid roll: %d\n",m->roll);
  838. X    return;
  839. X    }
  840. Xp++;
  841. Xif ( (m->roll == 0) || (*p == 'U') || (*p == 'u') )
  842. X    m->pt = -1;        /* this roll is unused */
  843. Xelse if ( (*p == 'B') || (*p == 'b') )
  844. X    m->pt = 0;        /* move from bar */
  845. Xelse if ( ( (m->pt = atoi(p)) < 0) || (m->pt > 25) ) {
  846. X    fprintf(stderr,"ERROR: invalid point: %d\n",m->pt);
  847. X    return;
  848. X    }
  849. X}
  850. X
  851. X
  852. X/*----------------------------------------------------------------------
  853. X *    mv2str -- encode move string from struct mv
  854. X *
  855. X * This function forms a string representation of a move based on
  856. X * the information in a mv structure.  This format is:
  857. X *
  858. X *    roll/move
  859. X *
  860. X * where roll is the die value stored in mv->roll, and move is:
  861. X *
  862. X *    mv->pt if mv->pt is in [1..24]
  863. X *    the string "BAR", if mv->pt is 0 or 25
  864. X *    the string "UNUSED", if mv->pt is < 0
  865. X *----------------------------------------------------------------------
  866. X */
  867. X
  868. Xmv2str(m,s)
  869. Xstruct mv *m;
  870. Xchar *s;
  871. X{
  872. X
  873. Xif (m->roll <= 0) {        /* non-existant roll */
  874. X    strcpy(s,"0/0");    /* should be skipped by nvwrite */
  875. X    return;            /* so we should never get here */
  876. X    }
  877. Xif (m->pt < 0)
  878. X    sprintf(s,"%d/UNUSED",m->roll);
  879. Xelse if ( (m->pt == DOWNBAR) || (m->pt == UPBAR) )
  880. X    sprintf(s,"%d/BAR",m->roll);
  881. Xelse
  882. X    sprintf(s,"%d/%d",m->roll,m->pt);
  883. X}
  884. X
  885. X
  886. X/*----------------------------------------------------------------------
  887. X *    clearmvs -- mark all entries in a mv array empty
  888. X *
  889. X * This function marks all elements of a mv array as being unused.
  890. X *----------------------------------------------------------------------
  891. X */
  892. X
  893. X
  894. Xclearmvs(m)
  895. Xstruct mv *m;
  896. X{
  897. Xint i;
  898. X
  899. Xfor (i = 0; i < 4; i++) {
  900. X    m[i].roll = -1;
  901. X    m[i].pt = -1;
  902. X    }
  903. X}
  904. X
  905. X
  906. X
  907. X/*----------------------------------------------------------------------
  908. X *    colorname -- convert color character to color name
  909. X *
  910. X * This function expands a color character to the full color name.
  911. X * Legal colors are: r (Red), w (White), and b (Black).
  912. X *----------------------------------------------------------------------
  913. X */
  914. X
  915. Xchar *colorname(c)
  916. Xchar c;
  917. X{
  918. X
  919. Xswitch (c) {
  920. Xcase 'r':
  921. X    return("Red");
  922. Xcase 'w':
  923. X    return("White");
  924. Xcase 'b':
  925. X    return("Black");
  926. Xdefault:
  927. X    return("*BAD COLOR*");
  928. X    }
  929. X}
  930. END_OF_FILE
  931. if test 6988 -ne `wc -c <'misc.c'`; then
  932.     echo shar: \"'misc.c'\" unpacked with wrong size!
  933. fi
  934. chmod +x 'misc.c'
  935. # end of 'misc.c'
  936. fi
  937. if test -f 'r_xrand.c' -a "${1}" != "-c" ; then 
  938.   echo shar: Will not clobber existing file \"'r_xrand.c'\"
  939. else
  940. echo shar: Extracting \"'r_xrand.c'\" \(8623 characters\)
  941. sed "s/^X//" >'r_xrand.c' <<'END_OF_FILE'
  942. X/*    r_xrand.c
  943. X */
  944. X
  945. X#include "ldb.h"
  946. X#include <math.h>
  947. X
  948. X/*======================================================================
  949. X * This file contains the random number generator.  It is accessed by
  950. X * calling RandomInit with a 32-bit seed, then calling Rolldie() to
  951. X * generate integers in the range [1-6].  This particular implementation
  952. X * was taken from xrand in volume 2 of comp.sources.misc.  It was
  953. X * written by Andreas Nowatzyk, then of Carnegie-Mellon University, and
  954. X * is reproduced here essentially unchanged (although I omitted
  955. X * all routines but the ones needed for integers in [1-6]).
  956. X * It is used by permission of the author, whose original copyright
  957. X * and permission-to-use appears below.
  958. X *======================================================================
  959. X */
  960. X
  961. X
  962. X
  963. X/*----------------------------------------------------------------------
  964. X *    Rolldie -- return a random number between 1 and 6
  965. X *----------------------------------------------------------------------
  966. X */
  967. X
  968. XRolldie()
  969. X{
  970. X
  971. Xreturn(rnd_ri(6)+1);
  972. X}
  973. X
  974. X
  975. X
  976. X/*----------------------------------------------------------------------
  977. X *    RandomInit -- initialize the random number generator
  978. X *
  979. X * This function should be called once, before Rolldie is called.
  980. X * The seed may be any more or less random number; the time seems
  981. X * to be conventional.
  982. X *----------------------------------------------------------------------
  983. X */
  984. X
  985. XRandomInit(seed)
  986. Xlong seed;
  987. X{
  988. X
  989. Xrnd_init(seed);
  990. X}
  991. X
  992. X
  993. X
  994. X/*----------------------------------------------------------------------
  995. X *From:    EMF780::WINS%"Andreas.Nowatzyk@eng.sun.com" 20-NOV-1991 17:50:38.73
  996. X *To:    ROSS
  997. X *CC:    
  998. X *Subj:    Re:  xrand
  999. X *
  1000. X *Return-Path: <Andreas.Nowatzyk@eng.sun.com>
  1001. X *Received: from everest.den.mmc.com by emf780.den.mmc.com with SMTP ; 
  1002. X *          Wed, 20 Nov 91 16:50:29 MDT
  1003. X *Received: from Sun.COM by everest.den.mmc.com (4.1/1.34.a)
  1004. X *    id AA27426; Wed, 20 Nov 91 17:52:10 MST
  1005. X *Received: from Eng.Sun.COM (zigzag-bb.Corp.Sun.COM) by Sun.COM (4.1/SMI-4.1)
  1006. X *    id AA07190; Wed, 20 Nov 91 16:50:53 PST
  1007. X *Received: from bovic.Eng.Sun.COM by Eng.Sun.COM (4.1/SMI-4.1)
  1008. X *    id AA21474; Wed, 20 Nov 91 16:49:44 PST
  1009. X *Received: by bovic.Eng.Sun.COM (4.1/SMI-4.1)
  1010. X *    id AA02462; Wed, 20 Nov 91 16:49:16 PST
  1011. X *Date: Wed, 20 Nov 91 16:49:16 PST
  1012. X *From: Andreas.Nowatzyk@eng.sun.com (Andreas G. Nowatzyk)
  1013. X *Message-Id: <9111210049.AA02462@bovic.Eng.Sun.COM>
  1014. X *To: ross@emf780.den.mmc.com
  1015. X *Subject: Re:  xrand
  1016. X *
  1017. X *I have no objection to distributing xrand, provided that this is not done
  1018. X *for profit and that the source is credited.
  1019. X *
  1020. X *  --  Andreas
  1021. X *
  1022. X *PS: There was a bug is some version of xrand.c: The costant for the most
  1023. X *    positive integer (0x7fffffff) had an 'f' missing in two places. Its should
  1024. X *    have used a #define MAX_INT with apropriate value instead of hardwiring
  1025. X *    an hex-constant.
  1026. X *----------------------------------------------------------------------
  1027. X */
  1028. X
  1029. X#define MAX_INT 0x7fffffff
  1030. X
  1031. X/* Random number generators:
  1032. X *
  1033. X *  rnd_init (unsigned seed) 
  1034. X *            : initializes the generator
  1035. X *
  1036. X *  rnd_i ()        : returns positive integers [0,0x7fffffff]
  1037. X *  rnd_ri (long n)    : returns positive integers [0,n-1]
  1038. X *
  1039. X *  Algorithm M as describes in Knuth's "Art of Computer Programming", Vol 2. 1969
  1040. X *  is used with a linear congruential generator (to get a good uniform
  1041. X *  distribution) that is permuted with a Fibonacci additive congruential
  1042. X *  generator to get good independence.
  1043. X *
  1044. X *  Bit, byte, and word distributions were extensively tested and pass
  1045. X *  Chi-squared test near perfect scores (>7E8 numbers tested, Uniformity
  1046. X *  assumption holds with probability > 0.999)
  1047. X *
  1048. X *  Run-up tests for on 7E8 numbers confirm independence with
  1049. X *  probability > 0.97.
  1050. X *
  1051. X *  Plotting random points in 2d reveals no apparent structure.
  1052. X *
  1053. X *  Autocorrelation on sequences of 5E5 numbers (A(i) = SUM X(n)*X(n-i), i=1..512)
  1054. X *  results in no obvious structure (A(i) ~ const).
  1055. X *
  1056. X *  On a SUN 3/60, rnd_u() takes about 19.4 usec per call, which is about 44%
  1057. X *  slower than Berkeley's random() (13.5 usec/call).
  1058. X *
  1059. X *  Except for speed and memory requirements, this generator outperforms
  1060. X *  random() for all tests. (random() scored rather low on uniformity tests,
  1061. X *  while independence test differences were less dramatic).
  1062. X *
  1063. X *  Thanks to M.Mauldin, H.Walker, J.Saxe and M.Molloy for inspiration & help.
  1064. X *
  1065. X *  (c) Copyright 1988 by A. Nowatzyk
  1066. X *
  1067. X */
  1068. X
  1069. X/* LC-parameter selection follows recommendations in 
  1070. X * "Handbook of Mathematical Functions" by Abramowitz & Stegun 10th, edi.
  1071. X */
  1072. X#define LC_A 66049            /* = 251^2, ~= sqrt(2^32)            */
  1073. X#define LC_C 3907864577            /* result of a long trial & error series    */
  1074. X
  1075. X#define Xrnd(x) (x * LC_A + LC_C)   /* the LC polynomial            */
  1076. X            
  1077. Xstatic unsigned long Fib[55];        /* will use X(n) = X(n-55) - X(n-24)    */
  1078. Xstatic int Fib_ind;            /* current index in circular buffer        */
  1079. Xstatic unsigned long Xrnd_var;        /* LCA - recurrence variable        */
  1080. Xstatic unsigned long auxtab[256];   /* temporal permutation table        */
  1081. Xstatic unsigned long prmtab[64] = { /* spatial permutation table        */
  1082. X    0xffffffff, 0x00000000,  0x00000000,  0x00000000,  /* 3210 */
  1083. X    0x0000ffff, 0x00ff0000,  0x00000000,  0xff000000,  /* 2310 */
  1084. X    0xff0000ff, 0x0000ff00,  0x00000000,  0x00ff0000,  /* 3120 */
  1085. X    0x00ff00ff, 0x00000000,  0xff00ff00,  0x00000000,  /* 1230 */
  1086. X
  1087. X    0xffff0000, 0x000000ff,  0x00000000,  0x0000ff00,  /* 3201 */
  1088. X    0x00000000, 0x00ff00ff,  0x00000000,  0xff00ff00,  /* 2301 */
  1089. X    0xff000000, 0x00000000,  0x000000ff,  0x00ffff00,  /* 3102 */
  1090. X    0x00000000, 0x00000000,  0x00000000,  0xffffffff,  /* 2103 */
  1091. X
  1092. X    0xff00ff00, 0x00000000,  0x00ff00ff,  0x00000000,  /* 3012 */
  1093. X    0x0000ff00, 0x00000000,  0x00ff0000,  0xff0000ff,  /* 2013 */
  1094. X    0x00000000, 0x00000000,  0xffffffff,  0x00000000,  /* 1032 */
  1095. X    0x00000000, 0x0000ff00,  0xffff0000,  0x000000ff,  /* 1023 */
  1096. X
  1097. X    0x00000000, 0xffffffff,  0x00000000,  0x00000000,  /* 0321 */
  1098. X    0x00ffff00, 0xff000000,  0x00000000,  0x000000ff,  /* 0213 */
  1099. X    0x00000000, 0xff000000,  0x0000ffff,  0x00ff0000,  /* 0132 */
  1100. X    0x00000000, 0xff00ff00,  0x00000000,  0x00ff00ff   /* 0123 */
  1101. X};
  1102. X
  1103. Xunion hack {                /* used to access doubles as unsigneds    */
  1104. X    double d;
  1105. X    unsigned long u[2];
  1106. X};
  1107. X
  1108. Xstatic union hack man;            /* mantissa bit vector            */
  1109. X
  1110. Xrnd_init (seed)                /* modified: seed 0-31 use precomputed stuff */
  1111. X    unsigned seed;
  1112. X{
  1113. X    register unsigned long u;
  1114. X    register int i;
  1115. X    double x, y;
  1116. X    union hack t;
  1117. X
  1118. X    static unsigned seed_tab[32] = {
  1119. X        0xbdcc47e5, 0x54aea45d, 0xec0df859, 0xda84637b,
  1120. X        0xc8c6cb4f, 0x35574b01, 0x28260b7d, 0x0d07fdbf,
  1121. X        0x9faaeeb0, 0x613dd169, 0x5ce2d818, 0x85b9e706,
  1122. X        0xab2469db, 0xda02b0dc, 0x45c60d6e, 0xffe49d10,
  1123. X        0x7224fea3, 0xf9684fc9, 0xfc7ee074, 0x326ce92a,
  1124. X        0x366d13b5, 0x17aaa731, 0xeb83a675, 0x7781cb32,
  1125. X        0x4ec7c92d, 0x7f187521, 0x2cf346b4, 0xad13310f,
  1126. X        0xb89cff2b, 0x12164de1, 0xa865168d, 0x32b56cdf  };
  1127. X
  1128. X    if (seed < 32)
  1129. X    u = seed_tab[seed];
  1130. X    else
  1131. X    u = seed ^ seed_tab[seed & 31];
  1132. X
  1133. X    for (i = 55; i--;)            /* set up Fibonacci additive congruential    */
  1134. X    Fib[i] = u = Xrnd(u);
  1135. X
  1136. X    for (i = 256; i--;)
  1137. X    auxtab[i] = u = Xrnd(u);
  1138. X
  1139. X    Fib_ind = u % 55;            /* select a starting point            */
  1140. X
  1141. X    Xrnd_var = u;
  1142. X
  1143. X    if (sizeof(x) != 2 * sizeof(unsigned long)) {
  1144. X    x = 0.0;
  1145. X    y = 1.0;
  1146. X    y /= x;                /*** intentional divide by 0: rnd_01d will
  1147. X                     not work because a double doesn't fit
  1148. X                     in 2 unsigned longs on your machine! ***/
  1149. X    };
  1150. X
  1151. X    x = 1.0;
  1152. X    y = 0.5;
  1153. X    do {                /* find largest fp-number < 2.0        */
  1154. X    t.d = x;
  1155. X    x += y;
  1156. X    y *= 0.5;
  1157. X    } while (x != t.d && x < 2.0);
  1158. X
  1159. X    man.d = 1.0;
  1160. X    man.u[0] ^= t.u[0];
  1161. X    man.u[1] ^= t.u[1];            /* man is now 1 for each mantissa bit    */
  1162. X}
  1163. X
  1164. Xlong rnd_i ()
  1165. X/*
  1166. X * returns a positive, uniformly distributed random number in [0,0x7fffffff]
  1167. X */
  1168. X{ 
  1169. X    register unsigned long i, j, *t = Fib;
  1170. X
  1171. X    i = Fib_ind;
  1172. X    j = t[i];                    /* = X(n-55) */
  1173. X    j -= (i >= 24) ? t[i - 24] : t[i + 21]; /* = X(n-24) */
  1174. X    t[i] = j;
  1175. X    if (++i >= 55) i = 0;
  1176. X    Fib_ind = i;
  1177. X
  1178. X    t = &auxtab[(j >> 24) & 0xff];
  1179. X    i = *t;
  1180. X    Xrnd_var = *t = Xrnd(Xrnd_var);
  1181. X    t = &prmtab[j & 0x3c];
  1182. X
  1183. X    j =  *t++ & i;
  1184. X    j |= *t++ & ((i << 24) | ((i >>  8) & 0x00ffffff));
  1185. X    j |= *t++ & ((i << 16) | ((i >> 16) & 0x0000ffff));
  1186. X    j |= *t   & ((i <<  8) | ((i >> 24) & 0x000000ff));
  1187. X    
  1188. X    return j & MAX_INT;
  1189. X}
  1190. X
  1191. X
  1192. Xlong rnd_ri (rng)
  1193. X    long rng;
  1194. X/*
  1195. X * randint: Return a random integer in a given Range [0..rng-1]
  1196. X *          Note:  0 < rng
  1197. X */
  1198. X{
  1199. X    register unsigned long  r, a;
  1200. X
  1201. X    do {
  1202. X    r = rnd_i();
  1203. X    a = (r / rng) + 1;
  1204. X    a *= rng;
  1205. X    } while (a >= MAX_INT);
  1206. X    
  1207. X    a--;
  1208. X    return a - r;
  1209. X}
  1210. END_OF_FILE
  1211. if test 8623 -ne `wc -c <'r_xrand.c'`; then
  1212.     echo shar: \"'r_xrand.c'\" unpacked with wrong size!
  1213. fi
  1214. # end of 'r_xrand.c'
  1215. fi
  1216. if test -f 'vars.c' -a "${1}" != "-c" ; then 
  1217.   echo shar: Will not clobber existing file \"'vars.c'\"
  1218. else
  1219. echo shar: Extracting \"'vars.c'\" \(7664 characters\)
  1220. sed "s/^X//" >'vars.c' <<'END_OF_FILE'
  1221. X/*    vars.c        8/4/91
  1222. X *
  1223. X * Copyright 1991  Perry R. Ross
  1224. X *
  1225. X * Permission to use, copy, modify, and distribute this software and its
  1226. X * documentation without fee is hereby granted, subject to the restrictions
  1227. X * detailed in the README file, which is included here by reference.
  1228. X * Any other use requires written permission from the author.  This software
  1229. X * is distributed "as is" without any warranty, including any implied
  1230. X * warranties of merchantability or fitness for a particular purpose.
  1231. X * The author shall not be liable for any damages resulting from the
  1232. X * use of this software.  By using this software, the user agrees
  1233. X * to these terms.
  1234. X */
  1235. X
  1236. X#include "ldb.h"
  1237. X
  1238. X/*======================================================================
  1239. X * This file contains the definition for all global variables, as well
  1240. X * as the static initialization values for those that need it.
  1241. X *======================================================================
  1242. X */
  1243. X
  1244. Xint Pflag;            /* should I process local input? */
  1245. Xint Rflag;            /* should I look for mail? */
  1246. Xstruct game *ghead;        /* head of linked list of games */
  1247. Xstruct game *gtail;        /* tail of linked list of games */
  1248. Xstruct legal *lhead;        /* head of list of legal moves */
  1249. Xstruct legal *ltail;        /* tail of list of legal moves */
  1250. Xstruct packet P;        /* last packet read */
  1251. Xchar cr_mycolor;        /* my color when game is created */
  1252. Xchar cr_opcolor;        /* opponent's color for new games */
  1253. Xchar cr_mydir;            /* my direction for new games */
  1254. Xchar blk76[] =            /* 76 blanks */
  1255. X"                                                                            ";
  1256. X
  1257. Xchar FeIsActive = 0;        /* has the front-end been initialized? */
  1258. X
  1259. Xchar *states[] = {        /* description of the states */
  1260. X    "Waiting for opponent to start game",
  1261. X    "Waiting for opponent to move",
  1262. X    "Waiting for opponent to accept double",
  1263. X    "Your turn (you haven't rolled yet)",
  1264. X    "Your move (you have rolled)",
  1265. X    "Waiting for you to accept double",
  1266. X    "Game over"
  1267. X    };
  1268. X
  1269. Xstruct opt options[] = {
  1270. X    "read",        OPT_READ,    "",
  1271. X    "\t\t\tRead incoming mail but do not play",
  1272. X    "play",        OPT_PLAY,    "",
  1273. X    "\t\t\tPlay any waiting games but do not read mail",
  1274. X    "color",    OPT_COLOR,    " xx",
  1275. X    "\t\tSet colors for new game [r, w, and b]",
  1276. X    "direction",    OPT_DIRECTION,    " dir",
  1277. X    "\t\tSet direction for new game [up or down]",
  1278. X    "myaddr",    OPT_MYADDR,    " addr",
  1279. X    "\t\tSet local e-mail address",
  1280. X    "start",    OPT_START,    " user",
  1281. X    "\t\tStart a game with another user",
  1282. X    "remotestart",    OPT_RSTART,    " u1 u2",
  1283. X    "\tStart a game between u1 and u2",
  1284. X    "broadcast",    OPT_BCAST,    " file",
  1285. X    "\tSend a mail message to all opponents",
  1286. X    "control",    OPT_CONTROL,    "",
  1287. X    "\t\tPerform control functions on games",
  1288. X    "help",        OPT_HELP,    "",
  1289. X    "\t\t\tPrint this message",
  1290. X    NULL,        -1,        NULL,        NULL
  1291. X    };
  1292. X
  1293. Xchar *opcodes[] = {
  1294. X        "START", "USTART", "TIE",  "MOVE", "OFFERDOUBLE", "ACCEPTDOUBLE",
  1295. X    "DECLINEDOUBLE", "CONCEDE", "REMOTESTART", "RESTART",
  1296. X    NULL
  1297. X        };
  1298. X
  1299. Xchar *bdlabels[] = {
  1300. X    "Board Before Opponent's Move",
  1301. X    "Board After Opponent's Move",
  1302. X    "Current Board"
  1303. X    };
  1304. X
  1305. Xstruct namevalue nv_rcfile[] = {
  1306. X    "myname",    FT_STRING,    Offset(struct ldbrc *,myname),
  1307. X    "myaddr",    FT_STRING,    Offset(struct ldbrc *,myaddr),
  1308. X    "gamefile",    FT_STRING,    Offset(struct ldbrc *,gfile),
  1309. X    "backupfile",    FT_STRING,    Offset(struct ldbrc *,gbackup),
  1310. X    "mailfile",    FT_STRING,    Offset(struct ldbrc *,mfile),
  1311. X    "sendcmd",    FT_STRING,    Offset(struct ldbrc *,sendcmd),
  1312. X    "tempfile",    FT_STRING,    Offset(struct ldbrc *,tempfile),
  1313. X    "colors",    FT_STRING,    Offset(struct ldbrc *,defclrs),
  1314. X    "direction",    FT_STRING,    Offset(struct ldbrc *,defdir),
  1315. X    "initialboard",    FT_STRING,    Offset(struct ldbrc *,initboard),
  1316. X    "autoroll",    FT_STRING,    Offset(struct ldbrc *,autoroll),
  1317. X    "automove",    FT_STRING,    Offset(struct ldbrc *,automove),
  1318. X    "autodouble",    FT_INT,        Offset(struct ldbrc *,autodouble),
  1319. X    "supercmd",    FT_STRING,    Offset(struct ldbrc *,supercmd),
  1320. X    "superkey",    FT_CHAR,    Offset(struct ldbrc *,superkey),
  1321. X    "checkpoint",    FT_STRING,    Offset(struct ldbrc *,chkpt),
  1322. X    NULL,        0,        -1
  1323. X    };
  1324. X
  1325. Xstruct namevalue nv_gfile[] = {        /* extracts into global var G */
  1326. X    "gameid",    FT_STRING,    Offset(struct game *,gameid),
  1327. X    "opaddr",    FT_STRING,    Offset(struct game *,opaddr),
  1328. X    "opname",    FT_STRING,    Offset(struct game *,opname),
  1329. X    "mycolor",    FT_CHAR,    Offset(struct game *,mycolor),
  1330. X    "opcolor",    FT_CHAR,    Offset(struct game *,opcolor),
  1331. X    "mydir",    FT_CHAR,    Offset(struct game *,mydir),
  1332. X    "opdir",    FT_CHAR,    Offset(struct game *,opdir),
  1333. X    "gameval",    FT_INT,        Offset(struct game *,gameval),
  1334. X    "flags",    FT_INT,        Offset(struct game *,flags),
  1335. X    "state",    FT_CHAR,    Offset(struct game *,state),
  1336. X    "term",        FT_CHAR,    Offset(struct game *,term),
  1337. X    "seq",        FT_INT,        Offset(struct game *,seq),
  1338. X    "lastop",    FT_STRLKUP,    Offset(struct game *,lastop),
  1339. X    "mycmt",    FT_STRING,    Offset(struct game *,mycmt),
  1340. X    "mycmt2",    FT_STRING,    Offset(struct game *,mycmt2),
  1341. X    "opcmt",    FT_STRING,    Offset(struct game *,opcmt),
  1342. X    "opcmt2",    FT_STRING,    Offset(struct game *,opcmt2),
  1343. X    "dispmsg",    FT_STRING,    Offset(struct game *,dispmsg),
  1344. X    "opmvs0",    FT_MOVE,    Offset(struct game *,opmvs[0]),
  1345. X    "opmvs1",    FT_MOVE,    Offset(struct game *,opmvs[1]),
  1346. X    "opmvs2",    FT_MOVE,    Offset(struct game *,opmvs[2]),
  1347. X    "opmvs3",    FT_MOVE,    Offset(struct game *,opmvs[3]),
  1348. X    "blot0",    FT_CHAR,    Offset(struct game *,blot[0]),
  1349. X    "blot1",    FT_CHAR,    Offset(struct game *,blot[1]),
  1350. X    "blot2",    FT_CHAR,    Offset(struct game *,blot[2]),
  1351. X    "blot3",    FT_CHAR,    Offset(struct game *,blot[3]),
  1352. X    "mvs0",        FT_MOVE,    Offset(struct game *,mvs[0]),
  1353. X    "mvs1",        FT_MOVE,    Offset(struct game *,mvs[1]),
  1354. X    "mvs2",        FT_MOVE,    Offset(struct game *,mvs[2]),
  1355. X    "mvs3",        FT_MOVE,    Offset(struct game *,mvs[3]),
  1356. X    "maxused",    FT_INT,        Offset(struct game *,maxused),
  1357. X    "hiused",    FT_INT,        Offset(struct game *,hiused),
  1358. X    "adcnt",    FT_INT,        Offset(struct game *,adcnt),
  1359. X    "admax",    FT_INT,        Offset(struct game *,admax),
  1360. X    "opbd",        FT_BOARD,    Offset(struct game *,opbd[0]),
  1361. X    "mybd",        FT_BOARD,    Offset(struct game *,mybd[0]),
  1362. X    "board",    FT_BOARD,    Offset(struct game *,board[0]),
  1363. X    "curbd",    FT_CHAR,    Offset(struct game *,curbd),
  1364. X    "end",        FT_END,        -1,
  1365. X    NULL,        0,        -1
  1366. X    };
  1367. X
  1368. Xstruct namevalue nv_packet[] = {
  1369. X    "version",    FT_INT,        Offset(struct packet *,version),
  1370. X    "timestamp",    FT_TIME,    Offset(struct packet *,timestamp),
  1371. X    "gameid",    FT_STRING,    Offset(struct packet *,gameid),
  1372. X    "opcode",    FT_STRLKUP,    Offset(struct packet *,opcode),
  1373. X    "move0",    FT_MOVE,    Offset(struct packet *,mvs[0]),
  1374. X    "move1",    FT_MOVE,    Offset(struct packet *,mvs[1]),
  1375. X    "move2",    FT_MOVE,    Offset(struct packet *,mvs[2]),
  1376. X    "move3",    FT_MOVE,    Offset(struct packet *,mvs[3]),
  1377. X    "name",        FT_STRING,    Offset(struct packet *,name),
  1378. X    "addr",        FT_STRING,    Offset(struct packet *,addr),
  1379. X    "comment",    FT_STRING,    Offset(struct packet *,comment),
  1380. X    "comment2",    FT_STRING,    Offset(struct packet *,comment2),
  1381. X    "seq",        FT_INT,        Offset(struct packet *,seq),
  1382. X    "colors",    FT_STRING,    Offset(struct packet *,colors),
  1383. X    "direction",    FT_STRING,    Offset(struct packet *,dir),
  1384. X    "autodouble",    FT_STRING,    Offset(struct packet *,autodbl),
  1385. X    "end",        FT_END,        -1,
  1386. X    NULL,        0,        -1
  1387. X    };
  1388. X
  1389. Xint (*func[OPSTATES][NOP])() = { /*
  1390. XSTART  USTART  TIE    MOVE    OFRDBL ACPTDBL DECDBL CONCEDE RSTART  RESTART*/
  1391. Xstart, istart, tie,     opmove, smerr, smerr,  smerr, opconc, smerr,  restart,
  1392. Xsmerr, smerr,  smerr,   opmove, opofr, smerr,  smerr, opconc, smerr,  smerr,
  1393. Xsmerr, smerr,  smerr,   smerr,  smerr, opacpt, opdec, opconc, smerr,  smerr
  1394. X    };
  1395. X
  1396. Xchar *rejmsg[] = {            /* explanation of reject codes */
  1397. X    "Move Accepted.",        /* no error */
  1398. X    "Move does not contain a legal roll.",    /* bad roll */
  1399. X    "Cannot remove pieces before filling inner table.",
  1400. X    "There is no piece at the specified location.",
  1401. X    "The destination of this move is occupied.",
  1402. X    "Attempt to move while pieces are on the bar.",
  1403. X    "Attempt to move wrong color.",
  1404. X    "That piece must be borne off by an exact roll."
  1405. X    };
  1406. END_OF_FILE
  1407. if test 7664 -ne `wc -c <'vars.c'`; then
  1408.     echo shar: \"'vars.c'\" unpacked with wrong size!
  1409. fi
  1410. chmod +x 'vars.c'
  1411. # end of 'vars.c'
  1412. fi
  1413. echo shar: End of archive 2 \(of 5\).
  1414. cp /dev/null ark2isdone
  1415. MISSING=""
  1416. for I in 1 2 3 4 5 ; do
  1417.     if test ! -f ark${I}isdone ; then
  1418.     MISSING="${MISSING} ${I}"
  1419.     fi
  1420. done
  1421. if test "${MISSING}" = "" ; then
  1422.     echo You have unpacked all 5 archives.
  1423.     rm -f ark[1-9]isdone
  1424. else
  1425.     echo You still need to unpack the following archives:
  1426.     echo "        " ${MISSING}
  1427. fi
  1428. ##  End of shell archive.
  1429. exit 0
  1430.  
  1431.  
  1432. exit 0 # Just in case...
  1433.