home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1994 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1994.iso
/
compsrcs
/
games
/
vmsnet
/
ldb
/
part11
< prev
next >
Wrap
Internet Message Format
|
1993-04-07
|
49KB
Path: uunet!zaphod.mps.ohio-state.edu!usc!news.service.uci.edu!unogate!mvb.saic.com!dayton.saic.com!dayvd.dayton.saic.com!ake
From: ake@dayvd.dayton.saic.com (Earle Ake)
Newsgroups: vmsnet.sources.games
Subject: ldb - Long Distance Backgammon [11/16]
Date: 8 Apr 93 11:00:49 EST
Organization: Science Applications Intl Corp - Dayton, OH
Lines: 1317
Message-ID: <1993Apr8.110049.1@dayvd.dayton.saic.com>
NNTP-Posting-Host: dayvd.dayton.saic.com
Xref: uunet vmsnet.sources.games:672
-+-+-+-+-+-+-+-+ START OF PART 11 -+-+-+-+-+-+-+-+
X`09j`20=`20optlookup(`26argv`5Bi`5D`5B1`5D);
X`09if`20(j`20==`20-2)`20`7B
X`09`09printf("%s:`5Ctambiguous`20option:`20%s`5Cn`5Cn",*argv,argv`5Bi`5D);
X`09`09usage(0);`09`09/*`20print`20short`20help`20*/
X`09`09ldbexit(STAT_ABORT);
X`09`09`7D
X`09if`20(j`20<`200)`20`7B
X`09`09printf("%s:`5Ctunrecognized`20option:`20%s`5Cn`5Cn",*argv,argv`5Bi`5D);
X`09`09usage(0);`09`09/*`20print`20short`20help`20*/
X`09`09ldbexit(STAT_ABORT);
X`09`09`7D
X`09switch`20(options`5Bj`5D.index)`20`7B
X`09case`20OPT_START:`09`09`09/*`20start`20a`20game`20*/
X`09`09i++;
X`09`09if`20(argv`5Bi`5D`20==`20NULL)`20`7B
X`09`09`09printf("%s:`20-start`20needs`20argument`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09if`20(start_addr`20!=`20NULL)`20`7B
X`09`09`09printf("%s:`20only`20one`20-start`20allowed.`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09start_addr`20=`20argv`5Bi`5D;
X`09`09break;
X`09case`20OPT_RSTART:`09`09/*`20remote`20start`20*/
X`09`09i++;
X`09`09if`20(`20(argv`5Bi`5D`20==`20NULL)`20`7C`7C`20(argv`5Bi+1`5D`20==`20NULL
V)`20)`20`7B
X`09`09`09printf("%s:`20-remotestart`20needs`20two`20arguments`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09if`20(rst1`20!=`20NULL)`20`7B
X`09`09`09printf("%s:`20only`20one`20-remotestart`20allowed.`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09rst1`20=`20argv`5Bi`5D;
X`09`09rst2`20=`20argv`5Bi+1`5D;
X`09`09i++;
X`09`09break;
X`09case`20OPT_READ:
X`09`09Pflag`20=`200;`09`09/*`20just`20read,`20no`20processing`20*/
X`09`09break;
X`09case`20OPT_PLAY:
X`09`09Rflag`20=`200;`09`09/*`20just`20process,`20no`20read`20*/
X`09`09break;
X`09case`20OPT_MYADDR:`09`09/*`20set`20my`20e-mail`20address`20*/
X`09`09i++;
X`09`09if`20(argv`5Bi`5D`20==`20NULL)`20`7B
X`09`09`09printf("%s:`20-myaddr`20needs`20argument`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09strcpy(rc.myaddr,argv`5Bi`5D);`09/*`20copy`20in`20new`20address`20*/
X`09`09break;
X`09case`20OPT_HELP:`09`09`09/*`20print`20long`20help`20*/
X`09`09usage(1);
X`09`09ldbexit(STAT_NORM);
X`09case`20OPT_NOTIFY:
X`09`09i++;
X`09`09if`20(argv`5Bi`5D`20==`20NULL)`20`7B
X`09`09`09printf("%s:`20-notify`20needs`20argument`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09notify`20=`20argv`5Bi`5D;
X`09`09break;
X`09case`20OPT_COLOR:`09`09`09/*`20set`20colors`20*/
X`09`09if`20(argv`5B++i`5D`20==`20NULL)`20`7B
X`09`09`09printf("%s:`20-color`20option`20needs`20argument`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09cr_mycolor`20=`20argv`5Bi`5D`5B0`5D;`09/*`20first`20char`20is`20my`20col
Vor`20*/
X`09`09cr_opcolor`20=`20argv`5Bi`5D`5B1`5D;`20/*`20second`20char`20is`20opponen
Vt's`20color`20*/
X`09`09if`20(`20(!`20isprint(cr_mycolor))`20`7C`7C`20(cr_mycolor`20==`20'`20')
V`20)`20`7B
X`09`09`09printf("%s:`20invalid`20color:`20%d`5Cn",*argv,cr_mycolor);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09if`20(`20(!`20isprint(cr_opcolor))`20`7C`7C`20(cr_opcolor`20==`20'`20')
V`20)`20`7B
X`09`09`09printf("%s:`20invalid`20color:`20%d`5Cn",*argv,cr_opcolor);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09c`20=`20cr_mycolor;
X`09`09if`20(isupper(c))
X`09`09`09c`20=`20tolower(c);
X`09`09c2`20=`20cr_opcolor;
X`09`09if`20(isupper(c2))
X`09`09`09c2`20=`20tolower(c2);
X`09`09if`20(c`20==`20c2)`20`7B
X`09`09`09printf("%s:`20duplicate`20color:`20%c`5Cn",*argv,cr_mycolor);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09break;
X`09case`20OPT_DIRECTION:`09`09/*`20set`20direction`20*/
X`09`09if`20(argv`5B++i`5D`20==`20NULL)`20`7B
X`09`09`09printf("%s:`20-direction`20option`20needs`20argument`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09c`20=`20argv`5Bi`5D`5B0`5D;
X`09`09if`20(isupper(c))
X`09`09`09c`20=`20tolower(c);
X`09`09if`20(c`20==`20'u')
X`09`09`09cr_mydir`20=`201;`09`09/*`20I`20play`20up`20*/
X`09`09else`20if`20(c`20==`20'd')
X`09`09`09cr_mydir`20=`20-1;`09`09/*`20I`20play`20down`20*/
X`09`09else`20`7B
X`09`09`09printf("%s:`20invalid`20direction:`20%s`5Cn",*argv,argv`5Bi`5D);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09break;
X`09case`20OPT_JACOBY:
X`09`09flags`20`7C=`20F_JACOBY;
X`09`09break;
X`09case`20OPT_CRAWFORD:
X`09`09flags`20`7C=`20F_CRAWFORD;
X`09`09break;
X`09case`20OPT_EUROPE:
X`09`09flags`20`7C=`20F_EUROPE;
X`09`09break;
X`09case`20OPT_PERM:
X`09`09flags`20`7C=`20F_PERM;
X`09`09break;
X`09case`20OPT_MATCH:
X`09`09if`20(argv`5B++i`5D`20==`20NULL)`20`7B
X`09`09`09printf("%s:`20-match`20option`20needs`20argument`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09if`20(!`20isdigit(*argv`5Bi`5D))`20`7B
X`09`09`09printf("%s:`20-match`20needs`20numeric`20argument`5Cn",*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09match`20=`20atoi(argv`5Bi`5D);
X`09`09break;
X`09case`20OPT_SCORE:
X`09`09if`20(start_addr`20!=`20NULL)
X`09`09`09printf("warning:`20-start`20not`20processed.`5Cn");
X`09`09if`20(rst1`20!=`20NULL)
X`09`09`09printf("warning:`20-remotestart`20not`20processed.`5Cn");
X`09`09printscore();
X`09`09ldbexit(STAT_NORM);
X`09case`20OPT_BCAST:`09`09`09`09/*`20broadcast`20a`20message`20*/
X`09`09if`20(argv`5B++i`5D`20==`20NULL)`20`7B`09/*`20no`20arg,`20read`20stdin
V`20*/
X`09`09`09if`20(`20(fp`20=`20fopen(rc.tempfile,"w"))`20==`20NULL)`20`7B
X`09`09`09`09printf("%s:`20can't`20write`20temp`20file`20%s`5Cn",
X`09`09`09`09`09*argv,rc.tempfile);
X`09`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`09`7D
X`09`09`09while`20(fgets(subj,sizeof(subj),stdin)`20!=`20NULL)
X`09`09`09`09fputs(subj,fp);
X`09`09`09fclose(fp);
X`09`09`09bcfile`20=`20rc.tempfile;
X`09`09`09`7D
X`09`09else
X`09`09`09bcfile`20=`20argv`5Bi`5D;`09/*`20just`20read`20named`20file`20*/
X`09`09sprintf(subj,"LDB`20Broadcast`20Message`20from`20%s",rc.myname);
X`09`09for`20(p`20=`20phead;`20p`20!=`20NULL;`20p`20=`20p->next)`09`7B`20/*`20f
Vor`20all`20people`20*/
X`09`09`09if`20(p->equiv`20!=`20NULL)`09/*`20it's`20an`20equiv`20record`20*/
X`09`09`09`09continue;`09/*`20skip`20it`20*/
X`09`09`09for`20(g`20=`20ghead;`20g`20!=`20NULL;`20g`20=`20g->next)`09/*`20cur
V`20opp?`20*/
X`09`09`09`09if`20(strcmp(g->opaddr,p->addr)`20==`200)
X`09`09`09`09`09break;
X`09`09`09if`20(g`20==`20NULL)`09/*`20not`20a`20current`20opponent`20*/
X`09`09`09`09continue;`09/*`20skip`20it`20*/
X`09`09`09TSendFile(p->addr,bcfile,subj);`20/*`20send`20msg`20*/
X`09`09`09`7D
X`09`09break;
X`09case`20OPT_CONTROL:`09`09`09/*`20control`20my`20games`20*/
X`09`09control();
X`09`09if`20(start_addr`20!=`20NULL)
X`09`09`09printf("warning:`20-start`20not`20processed.`5Cn");
X`09`09if`20(rst1`20!=`20NULL)
X`09`09`09printf("warning:`20-remotestart`20not`20processed.`5Cn");
X`09`09ldbexit(STAT_NORM);
X`09case`20OPT_RECONS:`09`09`09/*`20reconstruct`20a`20game`20*/
X`09`09if`20(argv`5B++i`5D`20==`20NULL)`20`7B
X`09`09`09printf("%s:`20-reconstruct`20option`20needs`20argument`5Cn",
X`09`09`09`09*argv);
X`09`09`09usage(0);
X`09`09`09ldbexit(STAT_ABORT);
X`09`09`09`7D
X`09`09recons(argv`5Bi`5D);
X`09`09if`20(start_addr`20!=`20NULL)
X`09`09`09printf("warning:`20-start`20not`20processed.`5Cn");
X`09`09if`20(rst1`20!=`20NULL)
X`09`09`09printf("warning:`20-remotestart`20not`20processed.`5Cn");
X`09`09ldbexit(STAT_NORM);
X`09default:
X`09`09fprintf(stderr,
X`09`09`20`20`20"Sorry,`20the`20%s`20option`20is`20not`20implemented`20yet.`5Cn
V",
X`09`09`09options`5Bj`5D.name);
X`09`09ldbexit(STAT_ABORT);
X`09`09`7D
X`09`7D
X
Xif`20(start_addr`20!=`20NULL)
X`09startgame(start_addr,cr_mydir,cr_mycolor,cr_opcolor,flags,match,0);
Xif`20(rst1`20!=`20NULL)
X`09remotestart(rst1,rst2,flags,match);
X
Xif`20(`20(Pflag`20==`200)`20`26`26`20(Rflag`20==`200)`20)`20`7B`09/*`20user
V`20gave`20both`20-play`20and`20-read`20*/
X`09Pflag`20=`201;`09`09`09/*`20turn`20both`20back`20on`20*/
X`09Rflag`20=`201;
X`09`7D
Xwhile`20(i`20<`20argc)`09`09/*`20if`20files`20given`20on`20command`20line,`20r
Vead`20them`20*/
X`09readmail(argv`5Bi++`5D);
Xif`20(Rflag)`09`09`09/*`20if`20we`20are`20supposed`20to`20read`20default`20fil
Ve`20*/
X`09readmail(rc.mfile);`09/*`20do`20that`20too`20*/
Xi`20=`200;
Xfor`20(g`20=`20ghead;`20g`20!=`20NULL;`20g`20=`20g->next)`09`7B`20/*`20does
V`20any`20game`20need`20our`20input?`20*/
X`09check_timeout(g);`09/*`20check`20for`20access`20timeouts`20*/
X`09if`20(`20(g->state`20>=`20OPSTATES)`20`26`26
X`09`20`20`20`20`20!`20(`20(g->state`20==`20ST_GAMEOVER)`20`26`26`20(g->flags
V`20`26`20F_DISPLAYED)`20)`20)
X`09`09i++;
X`09`7D
Xif`20(`20(i`20==`200)`20`7C`7C`20(Pflag`20==`200)`20)`20`7B`09`09/*`20if`20not
V,`20exit`20*/
X`09writegames(rc.gfile,rc.gbackup,rc.pfile);`09/*`20save`20games`20*/
X`09ldbexit(STAT_NORM);
X`09`7D
XTInitialize();`09`09`09`09`09/*`20fire`20up`20the`20transport`20*/
XFeInitialize();`09`09`09`09`09/*`20fire`20up`20the`20front`20end`20*/
XFeDrawScreen();`09`09`09`09/*`20draw`20the`20screen`20outline`20*/
Xfor`20(g`20=`20ghead,`20done`20=`200;`20(g`20!=`20NULL)`20`26`26`20(done`20>=
V`200);`20g`20=`20g->next)
X`09while`20(`20(done`20=`20process(g))`20>`200);`09/*`20process`20game`20til
V`20done`20*/
XFeFinishSession();`09`09`09`09/*`20close`20down`20the`20front`20end`20*/
XTFinishSession();`09`09`09`09/*`20close`20down`20the`20transport`20*/
Xwritegames(rc.gfile,rc.gbackup,rc.pfile);`09/*`20save`20the`20games`20in`20a
V`20file`20*/
Xldbexit(STAT_NORM);
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09ldbsignal`20--`20signal`20handler
X`20*
X`20*`20This`20function`20is`20called`20when`20the`20user`20hits`20the`20interr
Vupt`20character.
X`20*`20It`20is`20currently`20a`20very`20simple`20function;`20it`20saves`20the
V`20games`20in`20the
X`20*`20INTGFILE`20file,`20closes`20down`20the`20front`20end`20and`20the`20tran
Vsport,`20and`20exits.
X`20*----------------------------------------------------------------------
X`20*/
X
Xldbsignal()
X`7B
X
Xwritegames(INTGFILE,NULL,INTPFILE);
XFeFinishSession();`09/*`20let`20front-end`20close`20down`20gracefully`20*/
XTFinishSession();`09/*`20let`20transport`20close`20down`20gracefully`20*/
Xfprintf(stderr,"WARNING:`20games`20saved`20in`20%s`20and`20%s`5Cn",INTGFILE,IN
VTPFILE);
Xldbexit(STAT_ABORT);
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09usage`20--`20print`20command`20line`20options.
X`20*
X`20*`20This`20function`20prints`20a`20help`20message.`20`20This`20can`20be`20e
Vither`20in`20the
X`20*`20short`20or`20long`20format.`20`20The`20short`20format`20merely`20lists
V`20all`20options
X`20*`20in`20a`20very`20dense`20format.`20`20The`20long`20format`20prints`20eac
Vh`20option`20on
X`20*`20a`20separate`20line,`20along`20with`20a`20short`20explanation`20of`20it
Vs`20purpose.
X`20*----------------------------------------------------------------------
X`20*/
X
Xusage(help)
Xint`20help;`09`09/*`200`20=`20short`20message,`201`20=`20long`20message`20*/
X`7B
Xstruct`20opt`20*o;
Xint`20l;
X
Xprintf("options:`5Cn");
Xif`20(help)`20`7B`09`09/*`20print`20out`20the`20whole`20shootin'`20match`20*/
X`09for`20(o`20=`20options;`20o->name`20!=`20NULL;`20o++)
X`09`09printf("`5Ct-%s%s%s`5Cn",o->name,o->args,o->help);
X#if`20PATCHLEVEL`20==`200
X`09printf("`5CnLdb`20version`20%d.%d`20by`20Perry`20R.`20Ross.`20`20Mail`20com
Vments`5Cn",
X`09`09VERSION,REVISION);
X#else
X`09printf(
X`09"`5CnLdb`20version`20%d.%d`20(patch`20%d)`20by`20Perry`20R.`20Ross.`20`20Ma
Vil`5Cncomments",
X`09VERSION,REVISION,PATCHLEVEL);
X#endif
X`09printf("or`20suggestions`20to`20`5C"%s`5C".`5Cn",AUTHOR_EMAIL);
X`09`7D
Xelse`20`7B
X`09l`20=`200;
X`09printf("`5Ct");
X`09for`20(o`20=`20options;`20o->name`20!=`20NULL;`20o++)`20`7B
X`09`09if`20(`20(l`20+=`20(strlen(o->name)+strlen(o->args)+3))`20>`2055)`20`7B
X`09`09`09printf("`5Cn`5Ct");
X`09`09`09l`20=`200;
X`09`09`09`7D
X`09`09printf("`5B-%s%s`5D`20",o->name,o->args);
X`09`09`7D
X`09printf("`5Cn`5Cn");
X`09`7D
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09remotestart`20--`20start`20a`20game`20between`20two`20other`20people
X`20*
X`20*`20This`20function`20tells`20a`20user`20to`20start`20a`20game`20with`20ano
Vther`20user.
X`20*`20Neither`20user`20needs`20to`20be`20the`20one`20running`20remotestart;
V`20although
X`20*`20this`20would`20work,`20-start`20is`20a`20more`20efficient`20way`20to
V`20do`20that.
X`20*`20Remotestart`20could`20be`20used`20to`20start`20games`20between`20oppone
Vnts`20in
X`20*`20a`20tournament,`20or`20to`20set`20up`20a`20pickup`20game`20facility,
V`20where`20people
X`20*`20wanting`20to`20play`20would`20mail`20to`20a`20central`20machine,`20whic
Vh`20would
X`20*`20pair`20players`20by`20some`20criteria`20(such`20as`20ability)`20and`20s
Vtart`20a
X`20*`20game`20between`20them.
X`20*----------------------------------------------------------------------
X`20*/
X
Xremotestart(u1,u2,flags,match)
Xchar`20*u1,`20*u2;
Xint`20flags;
Xint`20match;
X`7B
Xstruct`20packet`20p;
Xchar`20colors`5B4`5D;
Xchar`20mbuf`5B8`5D;
X
Xp.version`20=`20LDB_VER;`09`09/*`20fill`20in`20a`20packet`20*/
Xp.timestamp`20=`20time(`20(long`20*)0);`09/*`20give`20it`20a`20timestamp`20*/
Xp.gameid`20=`20"REMOTESTART";`09/*`20give`20it`20a`20phony`20gameid`20*/
Xp.opcode`20=`20RSTART;`09`09/*`20remote`20start`20opcode`20*/
Xp.name`20=`20NULL;`09`09`09/*`20we`20don't`20need`20to`20send`20a`20name`20*/
Xp.addr`20=`20u2;`09`09`09/*`20put`20opponent's`20address`20in`20packet`20*/
Xp.comment`20=`20NULL;`09`09/*`20don't`20have`20a`20comment`20*/
Xp.comment2`20=`20NULL;
Xp.seq`20=`201;`09`09`09/*`20start`20with`20sequence`20number`201`20*/
Xp.notify`20=`20notify;`09`09/*`20send`20notify`20address`20if`20any`20*/
Xclearmvs(p.mvs);`09`09/*`20no`20moves`20to`20send`20*/
Xsprintf(colors,"%c%c",cr_mycolor,cr_opcolor);
Xp.colors`20=`20colors;
Xp.dir`20=`20(cr_mydir`20>`200)`20?`20"up"`20:`20"down";
Xp.autodbl`20=`20NULL;
Xp.jacoby`20=`20(flags`20`26`20F_JACOBY)`20?`20"yes"`20:`20NULL;`09`09/*`20jaco
Vby`20rule?`20*/
Xp.crawford`20=`20(flags`20`26`20F_CRAWFORD)`20?`20"yes"`20:`20NULL;`09/*`20cra
Vwford`20rule?`20*/
Xp.european`20=`20(flags`20`26`20F_EUROPE)`20?`20"yes"`20:`20NULL;`09`09/*`20eu
Vropean`20scoring?`20*/
Xp.perm`20=`20(flags`20`26`20F_PERM)`20?`20"yes"`20:`20NULL;`09`09/*`20perm`20g
Vame?`20*/
Xif`20(match`20>`200)`20`7B`09`09/*`20match`20play`20*/
X`09sprintf(mbuf,"%d",match);`09/*`20make`20it`20a`20string`20*/
X`09p.match`20=`20mbuf;`09`09`09/*`20and`20put`20it`20in`20the`20packet`20*/
X`09`7D
Xelse
X`09p.match`20=`20NULL;`09`09`09/*`20not`20a`20match,`20omit`20this`20field`20*
V/
Xp.gameptr`20=`20NULL;`09`09/*`20just`20in`20case`20*/
XTSendPacket(`26p,u1);`09`09/*`20send`20the`20remote`20start`20command`20to`20u
V1`20*/
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09optlookup`20--`20find`20command`20line`20option`20in`20options`20table
X`20*
X`20*`20This`20function`20looks`20up`20a`20command`20line`20switch`20in`20the
V`20options`20table,
X`20*`20returning`20the`20index`20into`20options`5B`5D.`20`20It`20returns`20-1
V`20if`20the`20option
X`20*`20was`20not`20found,`20and`20-2`20if`20the`20option`20was`20ambiguous.
V`20`20Options`20may`20be
X`20*`20abbreviated`20to`20the`20shortest`20unique`20substring`20of`20the`20opt
Vion.
X`20*----------------------------------------------------------------------
X`20*/
X
Xoptlookup(optstr)
Xchar`20*optstr;
X`7B
Xint`20i,`20j,`20l,`20n;
X
Xn`20=`200;
Xif`20(`20(l`20=`20strlen(optstr))`20==`200)`09`09`09/*`20empty`20option`20stri
Vng`20*/
X`09return(-1);`09`09`09`09/*`20that's`20no`20good`20*/
Xfor`20(i`20=`200;`20options`5Bi`5D.name`20!=`20NULL;`20i++)`09/*`20look`20for
V`20arg`20*/
X`09if`20(strncmp(options`5Bi`5D.name,optstr,l)`20==`200)`20`7B`09/*`20found
V`20it`20*/
X`09`09j`20=`20i;`09`09`09`09/*`20remember`20index`20*/
X`09`09n++;`09`09`09`09/*`20count`20how`20many`20*/
X`09`09`7D
Xif`20(n`20==`200)`09`09`09`09`09/*`20didn't`20find`20it`20*/
X`09return(-1);`09`09`09`09/*`20return`20error`20*/
Xif`20(n`20>`201)`09`09`09`09`09/*`20found`20more`20than`201`20match`20*/
X`09return(-2);`09`09`09`09/*`20return`20error`20*/
Xreturn(j);`09`09`09`09`09/*`20return`20the`20index`20*/
X`7D
$ call unpack MAIN.C;1 1400802312 ""
$!
$ create 'f'
X/*`09misc.c`09`098/8/91
X`20*
X`20*`20Copyright`201991`20`20Perry`20R.`20Ross
X`20*
X`20*`20Permission`20to`20use,`20copy,`20modify,`20and`20distribute`20this`20so
Vftware`20and`20its
X`20*`20documentation`20without`20fee`20is`20hereby`20granted,`20subject`20to
V`20the`20restrictions
X`20*`20detailed`20in`20the`20README`20file,`20which`20is`20included`20here`20b
Vy`20reference.
X`20*`20Any`20other`20use`20requires`20written`20permission`20from`20the`20auth
Vor.`20`20This`20software
X`20*`20is`20distributed`20"as`20is"`20without`20any`20warranty,`20including
V`20any`20implied
X`20*`20warranties`20of`20merchantability`20or`20fitness`20for`20a`20particular
V`20purpose.
X`20*`20The`20author`20shall`20not`20be`20liable`20for`20any`20damages`20result
Ving`20from`20the
X`20*`20use`20of`20this`20software.`20`20By`20using`20this`20software,`20the
V`20user`20agrees
X`20*`20to`20these`20terms.
X`20*/
X
X#include`20"ldb.h"
X
X
X/*----------------------------------------------------------------------
X`20*`09rolldice`20--`20roll`20two`20dice
X`20*
X`20*`20This`20function`20calls`20Rolldie`20twice`20and`20fills`20in`20the`20ga
Vme`20structure
X`20*`20with`20the`20resulting`20values.`20`20If`20the`20two`20calls`20to`20Rol
Vldie`20return`20the
X`20*`20same`20number,`20the`20mvs`20field`20is`20filled`20in`20so`20that`20the
V`20user`20has`204`20rolls
X`20*`20to`20use,`20otherwise`20the`20rolls`20are`20stored`20in`20the`20first
V`20two`20elements
X`20*`20of`20the`20mvs`20field`20and`20the`20last`20two`20are`20marked`20unused
V.
X`20*----------------------------------------------------------------------
X`20*/
X
Xrolldice(g)
Xstruct`20game`20*g;
X`7B
X
Xclearmvs(g->mvs);`09`09`09/*`20clear`20old`20stuff`20*/
Xg->mvs`5B0`5D.roll`20=`20Rolldie();`20`20`20`20`20`20`20`20`20`20`20`20`20/*
V`20roll`20the`20dice`20*/
Xg->mvs`5B1`5D.roll`20=`20Rolldie();
Xg->rolls`5Bg->mvs`5B0`5D.roll`20-`201`5D++;`09`09/*`20keep`20count`20of`20what
V`20rolls`20we`20got`20*/
Xg->rolls`5Bg->mvs`5B1`5D.roll`20-`201`5D++;
Xif`20(g->mvs`5B0`5D.roll`20==`20g->mvs`5B1`5D.roll)`20`7B`09/*`20hot`20damn,
V`20we`20got`20doubles`20*/
X`09g->mvs`5B2`5D.roll`20=`20g->mvs`5B0`5D.roll;`09/*`20copy`20roll`20into`20tw
Vo`20*/
X`09g->mvs`5B3`5D.roll`20=`20g->mvs`5B0`5D.roll;`09/*`20more`20moves`20*/
X`09g->doubles`5Bg->mvs`5B1`5D.roll`20-`201`5D++;`09/*`20keep`20track`20of`20do
Vubles`20*/
X`09`7D
Xlegalmoves(g);`09`09`09/*`20calculate`20the`20#`20of`20moves`20`26`20hi`20roll
V`20*/
X`7D
X
X
X
X/*----------------------------------------------------------------------
X`20*`09sendpkt`20--`20send`20a`20packet`20to`20the`20opponent
X`20*
X`20*`20This`20function`20fills`20in`20the`20fields`20of`20a`20packet`20and`20p
Vasses`20that
X`20*`20packet`20to`20the`20transport`20using`20TSendPacket.`20`20It`20also`20s
Vtores`20the
X`20*`20opcode`20sent`20in`20the`20lastop`20field`20of`20the`20game,`20so`20the
V`20packet
X`20*`20can`20be`20regenerated`20if`20necessary.`20`20Sendpkt`20returns`201`20i
Vf`20the
X`20*`20packet`20was`20sent,`20and`200`20if`20an`20error`20occurred.
X`20*----------------------------------------------------------------------
X`20*/
X
Xsendpkt(g,op)
Xstruct`20game`20*g;
Xchar`20op;
X`7B
Xstatic`20char`20colors`5B4`5D,`20adbl`5B10`5D,`20mch`5B10`5D;
Xchar`20cmt`5B60`5D,`20cmt2`5B60`5D,`20*sendaddr;
Xint`20i,`20status;
X
Xif`20(FeIsActive)
X`09FeMessage("Sending...");
Xsendaddr`20=`20g->opaddr;`09`09/*`20this`20is`20overridden`20for`20NOTIFY`20*/
V
Xif`20(`20(op`20!=`20RESEND)`20`26`26`20(op`20!=`20NOTIFY)`20)
X`09g->lastop`20=`20op;`09`09`09/*`20save`20last`20op`20for`20resend`20*/
Xfor`20(i`20=`200;`20i`20<`204;`20i++)
X`09g->blot`5Bi`5D`20=`200;`09`09`09/*`20clear`20blots`20hit`20*/
Xif`20(*rc.chkpt`20==`20'y')`20`7B
X`09writegames(rc.gfile,rc.gbackup,rc.pfile);
X`09rc.gbackup`20=`20NULL;`09/*`20only`20backup`20old`20file`20once`20*/
X`09`7D
XP.version`20=`20LDB_VER;`09`09`09/*`20these`20fields`20go`20in`20all`20packets
V`20*/
XP.gameid`20=`20g->gameid;
XP.opcode`20=`20op;
XP.seq`20=`20g->seq;
XP.jacoby`20=`20NULL;
XP.crawford`20=`20NULL;
XP.european`20=`20NULL;
XP.perm`20=`20NULL;
XP.match`20=`20NULL;
Xif`20(g->opver`20>`20100)`20`7B`09/*`20versions`20after`201.0`20rot13`20commen
Vts`20*/
X`09if`20(g->mycmt`20!=`20NULL)`20`7B
X`09`09strncpy(cmt,g->mycmt,sizeof(cmt));`09/*`20make`20copy`20*/
X`09`09cmt`5Bsizeof(cmt)-1`5D`20=`20'`5C0';`09`09/*`20null`20term`20*/
X`09`09P.comment`20=`20cmt;`09`09`09/*`20save`20pointer`20*/
X`09`09rotate(P.comment);`09`09`09/*`20rot13`20the`20copy`20*/
X`09`09`7D
X`09else
X`09`09P.comment`20=`20NULL;
X`09if`20(g->mycmt2`20!=`20NULL)`20`7B
X`09`09strncpy(cmt2,g->mycmt2,sizeof(cmt2));`09/*`20make`20copy`20*/
X`09`09cmt2`5Bsizeof(cmt2)-1`5D`20=`20'`5C0';`09`09/*`20null`20term`20*/
X`09`09P.comment2`20=`20cmt2;`09`09`09/*`20save`20pointer`20*/
X`09`09rotate(P.comment2);`09`09`09/*`20rot13`20the`20copy`20*/
X`09`09`7D
X`09else
X`09`09P.comment2`20=`20NULL;
X`09`7D
Xelse`20`7B`09`09`09`09/*`20version`201.0`20sends`20comments`20as`20cleartext
V`20*/
X`09P.comment`20=`20g->mycmt;
X`09P.comment2`20=`20g->mycmt2;
X`09`7D
Xif`20(g->flags`20`26`20F_SENTNAME)`20`7B
X`09P.name`20=`20NULL;
X`09P.notify`20=`20NULL;
X`09`7D
Xelse`20`7B
X`09P.name`20=`20rc.myname;
X`09P.notify`20=`20g->notify;
X`09g->flags`20`7C=`20F_SENTNAME;
X`09`7D
XP.addr`20=`20NULL;`09`09`09`09/*`20these`20fields`20only`20used`20by`20START
V`20*/
XP.colors`20=`20NULL;
XP.dir`20=`20NULL;
XP.autodbl`20=`20NULL;`09`09`09/*`20used`20by`20START`20and`20TIE`20*/
XP.timestamp`20=`20time((long`20*)`200);`09`09/*`20attach`20timestamp`20*/
Xif`20(g->lastacc`20<`20P.timestamp)`09`09/*`20update`20last`20access`20time
V`20*/
X`09g->lastacc`20=`20P.timestamp;`09/*`20but`20don't`20let`20time`20go`20backwa
Vrds`20*/
Xclearmvs(P.mvs);
Xswitch`20(op)`20`7B`09`09`09`09/*`20now`20do`20operation-specific`20stuff`20*/
V
Xcase`20START:
X`09P.addr`20=`20g->myaddr;`09`09/*`20send`20opponent`20my`20email`20address
V`20*/
X`09P.mvs`5B0`5D.roll`20=`20g->mvs`5B0`5D.roll;`09/*`20send`20initial`20die`20r
Voll`20*/
X`09sprintf(colors,"%c%c",g->mycolor,g->opcolor);
X`09P.colors`20=`20colors;
X`09P.dir`20=`20(g->mydir`20>`200)`20?`20"down"`20:`20"up";
X`09sprintf(adbl,"%d",rc.autodouble);
X`09P.autodbl`20=`20adbl;
X`09if`20(g->flags`20`26`20F_JACOBY)`09/*`20enable`20jacoby`20*/
X`09`09P.jacoby`20=`20"yes";
X`09if`20(g->flags`20`26`20F_CRAWFORD)`09/*`20enable`20crawford`20*/
X`09`09P.crawford`20=`20"yes";
X`09if`20(g->flags`20`26`20F_EUROPE)`09/*`20enable`20european`20rule`20*/
X`09`09P.european`20=`20"yes";
X`09if`20(g->flags`20`26`20F_PERM)`09`09/*`20game`20is`20permanent`20*/
X`09`09P.perm`20=`20"yes";
X`09if`20(g->mtotal`20>`200)`20`7B`09`09/*`20enable`20match`20play`20*/
X`09`09sprintf(mch,"%d",g->mtotal);
X`09`09P.match`20=`20mch;
X`09`09`7D
X`09break;
Xcase`20USTART:
X`09P.mvs`5B0`5D.roll`20=`20g->mvs`5B0`5D.roll;`09/*`20send`20both`20initial
V`20dice`20*/
X`09P.mvs`5B1`5D.roll`20=`20g->mvs`5B1`5D.roll;
X`09break;
Xcase`20MSTART:
Xcase`20RESTART:`09`09`09`09/*`20retry`20initial`20roll`20*/
X`09P.mvs`5B0`5D.roll`20=`20g->mvs`5B0`5D.roll;`09/*`20send`20new`20roll`20*/
X`09break;
Xcase`20TIE:
X`09if`20(g->adcnt`20>`200)`20`7B`09`09/*`20send`20current`20autodouble`20count
V`20*/
X`09`09sprintf(adbl,"%d",g->adcnt);
X`09`09P.autodbl`20=`20adbl;
X`09`09`7D
X`09break;
Xcase`20MOVE:
X`09for`20(i`20=`200;`20i`20<`204;`20i++)
X`09`09P.mvs`5Bi`5D`20=`20g->mvs`5Bi`5D;
X`09break;
Xcase`20NOTIFY:
X`09P.addr`20=`20g->myaddr;
X`09P.seq`20=`200;`09`09`09/*`20no`20sequences`20for`20notify`20packets`20*/
X`09P.notify`20=`20NULL;
X`09P.name`20=`20rc.myname;
X`09i`20=`20gvalue(g,`26status);
X`09sprintf(cmt,"%d`20%d`20%d",g->term,status,i);
X`09P.comment`20=`20cmt;`09/*`20send`20term`20code,`20game`20val,`20`26`20bg
V`20flag`20*/
X`09P.comment2`20=`20g->opaddr;`09/*`20send`20opponent`20address`20*/
X`09if`20(`20(sendaddr`20=`20g->notify)`20==`20NULL)
X`09`09return;`09`09/*`20shouldn't`20happen`20*/
X`09`7D
Xstatus`20=`20TSendPacket(`26P,sendaddr);`09`09/*`20send`20the`20packet`20*/
Xif`20(FeIsActive)`09`09`09`09/*`20clear`20"Sending..."`20from`20mesg`20line
V`20*/
X`09FeMessage(NULL);
Xreturn(status);
X`7D
X
X
X
X/*----------------------------------------------------------------------
X`20*`09resendpkt`20--`20resend`20the`20last`20packet
X`20*
X`20*`20This`20function`20takes`20a`20game`20structure`20and`20causes`20the`20l
Vast`20packet`20sent
X`20*`20in`20that`20game`20to`20be`20resent.
X`20*
X`20*`20The`20F_SENTNAME`20flag`20is`20cleared`20before`20resending,`20causing
V`20our`20personal
X`20*`20name`20to`20be`20resent.`20`20This`20is`20because`20the`20packet`20bein
Vg`20resent`20might`20have
X`20*`20been`20the`20one`20that`20sent`20the`20personal`20name`20(and`20set`20t
Vhe`20F_SENTNAME`20flag),
X`20*`20and`20since`20the`20F_SENTNAME`20flag`20is`20now`20set,`20the`20persona
Vl`20name`20would`20not
X`20*`20be`20included`20in`20the`20resent`20packet.
X`20*----------------------------------------------------------------------
X`20*/
X
Xresendpkt(g)
Xstruct`20game`20*g;
X`7B
X
Xg->flags`20`26=`20`7EF_SENTNAME;
Xsendpkt(g,g->lastop);
X`7D
X
X
X
X/*----------------------------------------------------------------------
X`20*`09str2mv`20--`20decode`20move`20string`20to`20struct`20mv
X`20*
X`20*`20This`20function`20takes`20a`20string`20representation`20of`20a`20move,
V`20decodes`20it,
X`20*`20and`20places`20the`20information`20into`20a`20mv`20structure.`20`20This
V`20format`20is:
X`20*
X`20*`09roll/move
X`20*
X`20*`20where`20roll`20is`20the`20die`20value`20used`20in`20the`20move,`20and
V`20is`20a`20single
X`20*`20digit`20in`20`5B1..6`5D,`20and`20move`20is`20one`20of`20the`20following
V:
X`20*
X`20*`09a`201`20or`202`20digit`20number`20in`20`5B1..24`5D
X`20*`09`09This`20designates`20the`20point`20the`20move`20originates`20from.
X`20*`09`09This`20number`20is`20stored`20in`20the`20"pt"`20field`20of`20the`20m
Vove
X`20*`09`09structure`20without`20modification.
X`20*`09the`20string`20"BAR"
X`20*`09`09This`20means`20the`20piece`20is`20coming`20off`20the`20bar.
X`20*`09`09Zero`20is`20stored`20in`20the`20"pt"`20field`20of`20the`20move`20str
Vucture,
X`20*`09`09regardless`20of`20whether`20the`20player's`20bar`20point`20is`200
V`20or`2025.
X`20*`09`09Apply()`20and`20FeDrawMove`20understand`20this`20and`20convert`200
V`20to
X`20*`09`09the`20appropriate`20bar`20point`20before`20using`20it.
X`20*`09the`20string`20"UNUSED"
X`20*`09`09This`20means`20the`20roll`20is`20unused.`20`20-1`20is`20stored`20in
V`20the
X`20*`09`09"pt"`20field`20of`20the`20mv`20structure.
X`20*----------------------------------------------------------------------
X`20*/
X
Xstr2mv(s,m)
Xchar`20*s;
Xstruct`20mv`20*m;
X`7B
Xchar`20*p,`20*strchr();
X
Xif`20(`20(p`20=`20strchr(s,'/'))`20==`20NULL)`20`7B
X`09message("ERROR:`20malformed`20move:`20%s`5Cn",s);
X`09return;
X`09`7D
Xif`20(`20(`20(m->roll`20=`20atoi(s))`20<`200)`20`7C`7C`20(m->roll`20>`206)`20)
V`20`7B
X`09message("ERROR:`20invalid`20roll:`20%d`5Cn",m->roll);
X`09return;
X`09`7D
Xp++;
Xif`20(`20(m->roll`20==`200)`20`7C`7C`20(*p`20==`20'U')`20`7C`7C`20(*p`20==`20'
Vu')`20)
X`09m->pt`20=`20-1;`09`09/*`20this`20roll`20is`20unused`20*/
Xelse`20if`20(`20(*p`20==`20'B')`20`7C`7C`20(*p`20==`20'b')`20)
X`09m->pt`20=`200;`09`09/*`20move`20from`20bar`20*/
Xelse`20if`20(`20(`20(m->pt`20=`20atoi(p))`20<`200)`20`7C`7C`20(m->pt`20>`2025)
V`20)`20`7B
X`09message("ERROR:`20invalid`20point:`20%d`5Cn",m->pt);
X`09return;
X`09`7D
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09mv2str`20--`20encode`20move`20string`20from`20struct`20mv
X`20*
X`20*`20This`20function`20forms`20a`20string`20representation`20of`20a`20move
V`20based`20on
X`20*`20the`20information`20in`20a`20mv`20structure.`20`20This`20format`20is:
X`20*
X`20*`09roll/move
X`20*
X`20*`20where`20roll`20is`20the`20die`20value`20stored`20in`20mv->roll,`20and
V`20move`20is:
X`20*
X`20*`09mv->pt`20if`20mv->pt`20is`20in`20`5B1..24`5D
X`20*`09the`20string`20"BAR",`20if`20mv->pt`20is`200`20or`2025
X`20*`09the`20string`20"UNUSED",`20if`20mv->pt`20is`20<`200
X`20*----------------------------------------------------------------------
X`20*/
X
Xmv2str(m,s)
Xstruct`20mv`20*m;
Xchar`20*s;
X`7B
X
Xif`20(m->roll`20<=`200)`20`7B`09`09/*`20non-existant`20roll`20*/
X`09strcpy(s,"0/0");`09/*`20should`20be`20skipped`20by`20nvwrite`20*/
X`09return;`09`09`09/*`20so`20we`20should`20never`20get`20here`20*/
X`09`7D
Xif`20(m->pt`20<`200)
X`09sprintf(s,"%d/UNUSED",m->roll);
Xelse`20if`20(`20(m->pt`20==`20DOWNBAR)`20`7C`7C`20(m->pt`20==`20UPBAR)`20)
X`09sprintf(s,"%d/BAR",m->roll);
Xelse
X`09sprintf(s,"%d/%d",m->roll,m->pt);
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09clearmvs`20--`20mark`20all`20entries`20in`20a`20mv`20array`20empty
X`20*
X`20*`20This`20function`20marks`20all`20elements`20of`20a`20mv`20array`20as`20b
Veing`20unused.
X`20*----------------------------------------------------------------------
X`20*/
X
X
Xclearmvs(m)
Xstruct`20mv`20*m;
X`7B
Xint`20i;
X
Xfor`20(i`20=`200;`20i`20<`204;`20i++)`20`7B
X`09m`5Bi`5D.roll`20=`20-1;
X`09m`5Bi`5D.pt`20=`20-1;
X`09`7D
X`7D
X
X
X
X/*----------------------------------------------------------------------
X`20*`09canmove`20--`20see`20if`20a`20roll`20is`20usable`20in`20a`20range`20of
V`20points
X`20*
X`20*`20This`20function`20trys`20to`20use`20a`20roll`20over`20a`20range`20of
V`20points.`20`20If`20it
X`20*`20finds`20a`20point`20where`20a`20roll`20could`20be`20used,`20it`20return
Vs`201,`20otherwise
X`20*`20it`20returns`200.`20`20The`20board`20is`20not`20changed.
X`20*----------------------------------------------------------------------
X`20*/
X
Xcanmove(g,r,p1,p2)
Xstruct`20game`20*g;`09`09/*`20the`20game`20structure`20*/
Xint`20r;`09`09`09/*`20which`20element`20of`20g->mvs`20*/
Xint`20p1,`20p2;`09`09/*`20the`20range`20of`20points`20to`20try`20*/
X`7B
Xint`20i,`20op;
X
Xif`20(p1`20>`20p2)`20`7B
X`09i`20=`20p1;
X`09p1`20=`20p2;
X`09p2`20=`20i;
X`09`7D
Xop`20=`20g->mvs`5Br`5D.pt;`09`09/*`20so`20we`20can`20restore`20it`20*/
Xfor`20(i`20=`20p1;`20i`20<=`20p2;`20i++)`20`7B
X`09g->mvs`5Br`5D.pt`20=`20i;`09`09/*`20try`20from`20this`20point`20*/
X`09if`20(apply(g,WHO_ME,r,A_CHKONLY,NULL)`20>=`200)`20`7B
X`09`09g->mvs`5Br`5D.pt`20=`20op;
X`09`09return(1);
X`09`09`7D
X`09`7D
Xg->mvs`5Br`5D.pt`20=`20op;
Xreturn(0);
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09rotate`20--`20rot13`20a`20buffer
X`20*
X`20*`20This`20function`20performs`20the`20popular`20"rot13"`20conversion`20to
V`20a`20buffer.
X`20*`20The`20buffer`20is`20modified`20in`20place.`20`20This`20conversion`20mak
Ves`20a
X`20*`20string`20unreadable`20by`20adding`2013`20to`20letters`20in`20`5BA-Ma-m
V`5D`20and`20subtracting
X`20*`2013`20from`20letters`20in`20`5BN-Zn-z`5D.`20`20All`20other`20characters
V`20are`20unchanged.
X`20*`20Applying`20the`20rot13`20transformation`20again`20returns`20the`20buffe
Vr`20to`20normal.
X`20*----------------------------------------------------------------------
X`20*/
X
Xrotate(buf)
Xchar`20*buf;
X`7B
Xregister`20char`20*s;
X
Xfor`20(s`20=`20buf;`20*s;`20s++)`20`7B
X`09if`20(!`20isalpha(*s))
X`09`09continue;
X`09if`20(`20((*s`20>=`20'A')`20`26`26`20(*s`20<=`20'M'))`20`7C`7C`20((*s`20>=
V`20'a')`20`26`26`20(*s`20<=`20'm'))`20)
X`09`09*s`20+=`20(char)`2013;
X`09else
X`09`09*s`20-=`20(char)`2013;
X`09`7D
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09message`20--`20print`20a`20message`20in`20proper`20way
X`20*
X`20*`20This`20function`20checks`20to`20see`20if`20the`20front`20end`20is`20act
Vive.`20`20If
X`20*`20so,`20it`20calls`20FeMessage,`20otherwise`20it`20prints`20on`20stderr
V`20and
X`20*`20sets`20the`20FeWaitInit`20flag`20so`20that`20when`20FeInitialize`20is
V`20called,
X`20*`20it`20will`20wait`20for`20return`20to`20be`20pressed`20before`20clearing
V`20the`20screen.
X`20*----------------------------------------------------------------------
X`20*/
X
Xmessage(s,a1,a2,a3)
Xchar`20*s;
Xint`20a1,`20a2,`20a3;
X`7B
Xchar`20buf`5B80`5D;
X
Xif`20(FeIsActive)`20`7B
X`09sprintf(buf,`20s,`20a1,`20a2,`20a3);
X`09FeMessage(buf);
X`09`7D
Xelse`20`7B
X`09fprintf(stderr,s,a1,a2,a3);
X`09FeWaitInit++;
X`09if`20(FeWaitInit`20>`2022)`20`7B
X`09`09fprintf(stderr,"Press`20<return>`20to`20continue...");
X`09`09fgets(buf,sizeof(buf),stdin);
X`09`09FeWaitInit`20=`200;
X`09`09`7D
X`09`7D
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09fatal`20--`20terminate`20program`20with`20error`20message
X`20*
X`20*`20This`20function`20prints`20a`20message`20to`20stderr`20and`20exits.
X`20*----------------------------------------------------------------------
X`20*/
X
Xfatal(msg)
Xchar`20*msg;
X`7B
X
XFeFinishSession();
XTFinishSession();
Xfprintf(stderr,"%s`5Cn",msg);
Xldbexit(STAT_ABORT);
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09ldbexit`20--`20terminate`20program`20in`20an`20orderly`20fashion
X`20*
X`20*`20This`20function`20can`20be`20called`20at`20any`20time,`20and`20ensures
V`20that`20the
X`20*`20front`20end`20and`20the`20transport`20are`20closed`20down`20cleanly`20b
Vefore
X`20*`20exiting.
X`20*----------------------------------------------------------------------
X`20*/
X
Xldbexit(code)
Xint`20code;
X`7B
X
XFeFinishSession();
XTFinishSession();
Xrelease_lock(rc.lockfile);
Xfflush(stdout);
Xfflush(stderr);
Xexit(code);
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09pipcount`20--`20calculate`20a`20pip`20count`20for`20both`20players
X`20*
X`20*`20This`20function`20takes`20a`20board`20and`20a`20pointer`20to`20a`20game
V`20structure
X`20*`20and`20calculates`20a`20pip`20count`20for`20both`20players.`20`20These
V`20are`20returned
X`20*`20in`20*mp`20and`20*op.
X`20*----------------------------------------------------------------------
X`20*/
X
Xpipcount(b,g,mp,op)
Xboard`20b;`09`09`09/*`20the`20board`20*/
Xstruct`20game`20*g;`09`09`09/*`20the`20game`20*/
Xint`20*mp;`09`09`09/*`20where`20to`20store`20my`20pip`20count`20*/
Xint`20*op;`09`09`09/*`20where`20to`20store`20opponent's`20pip`20count`20*/
X`7B
Xint`20direction`5B2`5D;
Xint`20player;`09`09`09/*`20me`20=`200;`20op`20=`201`20*/
Xint`20PIP`5B2`5D;`09`09`09/*`20mypip`20=`200;`20oppip`20=`201`20*/
Xint`20i;`09`09`09`09/*`20counter`20*/
X
XPIP`5BWHO_ME`5D`20=`200;`09`09`09/*`20initialize`20my`20PIP`20count`20*/
XPIP`5BWHO_OPP`5D`20=`200;`09`09`09/*`20initialize`20op`20PIP`20count`20*/
Xdirection`5BWHO_ME`5D`20=`20g->mydir;`09`09/*`20my`20direction`20of`20travel
V`20*/
Xdirection`5BWHO_OPP`5D`20=`20g->opdir;`09`09/*`20op`20direction`20of`20travel
V`20*/
X
Xfor`20(i`20=`200;`20i`20<=`20DOWNBAR;`20i++)`20`7B`09/*`20for`20each`20point
V`20on`20the`20board`20*/
X
X`09if`20(b`5Bi`5D.qty`20>`200)`20`7B
X`09`09player`20=`20(b`5Bi`5D.color`20==`20g->mycolor)`20?`20WHO_ME`20:`20WHO_O
VPP;
X`09`09if`20((i`20==`20UPBAR)`20`7C`7C`20(i`20==`20DOWNBAR))
X`09`09`09PIP`5Bplayer`5D`20+=`20b`5Bi`5D.qty`20*`2025;
X`09`09else`20`7B
X`09`09`09if`20(direction`5Bplayer`5D`20==`201)
X`09`09`09`09PIP`5Bplayer`5D`20+=`20b`5Bi`5D.qty`20*`20(25`20-`20i);
X`09`09`09else
X`09`09`09`09PIP`5Bplayer`5D`20+=`20b`5Bi`5D.qty`20*`20i;
X`09`09`09`7D
X`09`09`7D
X`09`7D
X*mp`20=`20PIP`5BWHO_ME`5D;`09`09/*`20return`20my`20pip`20count`20*/
X*op`20=`20PIP`5BWHO_OPP`5D;`09`09/*`20return`20opponent's`20pip`20count`20*/
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09gvalue`20--`20calculate`20the`20game`20value
X`20*
X`20*`20This`20function`20takes`20a`20completed`20game`20and`20calculates`20its
V`20value,
X`20*`20taking`20into`20account`20gammons,`20backgammons,`20and`20the`20Jacoby
V`20and
X`20*`20European`20rules.`20`20These`20are:
X`20*`09-`20Gammon`20(when`20the`20loser`20does`20not`20bear`20off`20any`20piec
Ves)
X`20*`09`20`20counts`20as`20double`20the`20game`20value`20shown`20on`20the`20cu
Vbe.
X`20*`09-`20Backgammon`20(when`20the`20loser`20does`20not`20bear`20off`20any
V`20pieces
X`20*`09`20`20and`20has`20pieces`20in`20the`20winner's`20home`20board)`20counts
V`20as
X`20*`09`20`20triple`20the`20game`20value`20shown`20on`20the`20cube.
X`20*`09-`20Jacoby`20rule`20(if`20enabled)`20states`20that`20Gammons`20and`20Ba
Vckgammons
X`20*`09`20`20count`20as`20single`20games`20if`20neither`20player`20doubled`20d
Vuring`20the`20game.
X`20*`09-`20European`20rule`20(if`20enabled)`20states`20the`20Backgammons`20cou
Vnt`20double,
X`20*`09`20`20not`20triple,`20the`20game`20value`20shown`20on`20the`20cube.
X`20*`20The`20game`20value`20is`20returned`20in`20*vp;`20the`20return`20value
V`20is`201`20for`20a`20gammon,
X`20*`202`20for`20a`20backgammon,`20and`200`20for`20neither.
X`20*
X`20*`20If`20the`20game`20was`20conceded,`20gvalue()`20scores`20a`20gammon`20if
V`20the`20loser`20has
X`20*`20not`20borne`20off`20any`20pieces,`20and`20a`20backgammon`20if`20the`20l
Voser`20has`20any`20pieces
X`20*`20in`20the`20winners`20inner`20table.`20`20This`20prevents`20players`20fr
Vom`20conceding`20to
X`20*`20avoid`20a`20gammon/backgammon.
X`20*----------------------------------------------------------------------
X`20*/
X
Xgvalue(g,vp)
Xstruct`20game`20*g;
Xint`20*vp;
X`7B
Xint`20bf;
Xint`20p1,`20p2;
X
Xbf`20=`200;`09`09`09`09/*`20init`20to`20no`20gammon/backgammon`20*/
X*vp`20=`20g->gameval;`09`09/*`20init`20to`20game`20value`20on`20cube`20*/
Xif`20(`20(g->term`20==`20T_ILOSE)`20`7C`7C`20(g->term`20==`20T_ICONCEDE)`20)
V`20`7B
X`09if`20(g->board`5BOFFPT(g->mydir)`5D.qty`20==`200)`20`7B
X`09`09p1`20=`20(g->opdir`20>`200)`20?`2019`20:`200;/*`20check`20op's`20inner
V`20tbl*/
X`09`09p2`20=`20(g->opdir`20>`200)`20?`2025`20:`206;`09/*`20for`20my`20pieces
V`20*/
X`09`09if`20(addpcs(g->board,g->mycolor,p1,p2)`20>`200)
X`09`09`09bf`20=`202;`09`09`09/*`20flag`20a`20backgammon`20*/
X`09`09else
X`09`09`09bf`20=`201;`09`09`09/*`20flag`20a`20gammon`20*/
X`09`09`7D
X`09`7D
Xelse`20if`20(`20(g->term`20==`20T_IWIN)`20`7C`7C`20(g->term`20==`20T_OPCONCEDE
V)`20)`20`7B
X`09if`20(g->board`5BOFFPT(g->opdir)`5D.qty`20==`200)`20`7B
X`09`09p1`20=`20(g->mydir`20>`200)`20?`2019`20:`200;`09/*`20check`20my`20inner
V`20tbl*/
X`09`09p2`20=`20(g->mydir`20>`200)`20?`2025`20:`206;`09/*`20for`20op's`20pieces
V`20*/
X`09`09if`20(addpcs(g->board,g->opcolor,p1,p2)`20>`200)
X`09`09`09bf`20=`202;`09`09`09/*`20flag`20a`20backgammon`20*/
X`09`09else
X`09`09`09bf`20=`201;`09`09`09/*`20flag`20a`20gammon`20*/
X`09`09`7D
X`09`7D
Xif`20(`20(g->flags`20`26`20F_JACOBY)`20`26`26`20(g->gameval`20==`20(1`20<<`20g
V->adcnt))`20)
X`09return(bf);`09/*`20jacoby`20enabled`20`26`20no`20doubles,`20don't`20mult
V`20game`20val`20*/
Xif`20(`20(g->flags`20`26`20F_EUROPE)`20`26`26`20(bf`20==`202)`20)`20`7B
X`09*vp`20*=`202;`09/*`20european`20rule`20enabled,`20bg`20=`202`20multiplier
V`20*/
X`09return(bf);
X`09`7D
Xif`20(bf`20==`202)
X`09*vp`20*=`203;`09/*`20backgammon`20=`203`20multiplier`20*/
Xelse`20if`20(bf`20==`201)
X`09*vp`20*=`202;`09/*`20gammon`20=`202`20multipler`20*/
Xreturn(bf);`09`09/*`20return`20gammon/backgammon/neither`20flag`20*/
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09iscontact`20--`20determine`20if`20contact`20is`20possible`20for`20a`20g
Vame
X`20*
X`20*`20This`20function`20returns`201`20if`20it`20is`20possible`20for`20any`20p
Viece`20to`20hit
X`20*`20any`20other`20piece,`200`20if`20both`20players`20have`20moved`20past
V`20each`20other
X`20*`20and`20the`20game`20is`20a`20race.
X`20*----------------------------------------------------------------------
X`20*/
X
Xiscontact(g)
Xstruct`20game`20*g;
X`7B
Xint`20dc,`20dn,`20i;
X
Xif`20(g->mydir`20>`200)`09`09/*`20which`20color`20is`20down-bound?`20*/
X`09dc`20=`20g->opcolor;
Xelse
X`09dc`20=`20g->mycolor;
Xdn`20=`20g->board`5BDOWNOFF`5D.qty;`09`09/*`20start`20with`20#`20pcs`20borne
V`20off`20*/
Xfor`20(i`20=`200;`20(i`20<=`2024)`20`26`26`20(dn`20<`2015);`20i++)`20`7B
X`09if`20(g->board`5Bi`5D.qty`20==`200)
X`09`09continue;
X`09if`20(g->board`5Bi`5D.color`20!=`20dc)`09/*`20found`20some`20upbound`20piec
Ves`20*/
X`09`09return(1);`09`09/*`20that`20are`20in`20hitting`20range`20*/
X`09dn`20+=`20g->board`5Bi`5D.qty;`09`09/*`20keep`20count`20of`20down`20pcs`20f
Vound`20*/
X`09`7D
Xif`20(dn`20>=`2015)`09`09`09`09/*`20found`20all`20down`20pcs`20*/
X`09return(0);`09`09`09/*`20no`20more`20contact`20for`20this`20game`20*/
Xreturn(1);
X`7D
X
X
X/*----------------------------------------------------------------------
X`20*`09crawford_check`20--`20is`20this`20the`20crawford`20rule`20game`20for
V`20a`20match?
X`20*
X`20*`20This`20function`20sets`20the`20F_CRGAME`20and`20F_CRDONE`20flags`20for
V`20a`20match.
X`20*`20F_CRGAME`20is`20set`20if`20this`20is`20the`20crawford`20rule`20game`20f
Vor`20the`20match.
X`20*`20F_CRDONE`20is`20set`20after`20the`20crawford`20rule`20game`20has`20been
V`20played.
X`20*
X`20*`20F_CRGAME`20is`20set`20if:
X`20*`09F_CRAWFORD`20is`20set`09AND
X`20*`09F_CRDONE`20is`20not`20set`09AND
X`20*`09a`20player`20is`20within`20one`20point`20of`20winning`20the`20match.
X`20*`20otherwise`20F_CRGAME`20is`20cleared.
X`20*
X`20*`20F_CRDONE`20is`20set`20if:
X`20*`09F_CRAWFORD`20is`20set`09AND
X`20*`09F_CRGAME`20was`20set`20(before`20the`20above)
X`20*`20otherwise`20F_CRDONE`20is`20not`20changed.
X`20*----------------------------------------------------------------------
X`20*/
X
Xcrawford_check(g)
Xstruct`20game`20*g;
X`7B
Xint`20old_crgame;
X
Xold_crgame`20=`20g->flags`20`26`20F_CRGAME;`09`09/*`20save`20F_CRGAME`20*/
Xif`20(`20((g->flags`20`26`20(F_CRAWFORD`7CF_CRDONE))`20==`20F_CRAWFORD)`20`26
V`26
X`20`20`20`20`20(`20(g->mcurrent`5BWHO_ME`5D`20==`20g->mtotal-1)`20`7C`7C
X`20`20`20`20`20`20`20(g->mcurrent`5BWHO_OPP`5D`20==`20g->mtotal-1)`20)`20)
X`09g->flags`20`7C=`20F_CRGAME;`09`09/*`20this`20is`20the`20crawford`20rule`20g
Vame`20*/
Xelse
X`09g->flags`20`26=`20`7EF_CRGAME;`09`09/*`20not`20the`20crawford`20game,`20cle
Var`20flag`20*/
Xif`20(`20(g->flags`20`26`20F_CRAWFORD)`20`26`26`20old_crgame)
X`09g->flags`20`7C=`20F_CRDONE;`09`09/*`20crawford`20rule`20game`20is`20over
V`20*/
X`7D
$ call unpack MISC.C;1 138558963 ""
$!
$ create 'f'
X/*`09move.c`09`098/5/91
X`20*
X`20*`20Copyright`201991`20`20Perry`20R.`20Ross
X`20*
X`20*`20Permission`20to`20use,`20copy,`20modify,`20and`20distribute`20this`20so
Vftware`20and`20its
X`20*`20documentation`20without`20fee`20is`20hereby`20granted,`20subject`20to
V`20the`20restrictions
X`20*`20detailed`20in`20the`20README`20file,`20which`20is`20included`20here`20b
Vy`20reference.
X`20*`20Any`20other`20use`20requires`20written`20permission`20from`20the`20auth
Vor.`20`20This`20software
X`20*`20is`20distributed`20"as`20is"`20without`20any`20warranty,`20including
V`20any`20implied
X`20*`20warranties`20of`20merchantability`20or`20fitness`20for`20a`20particular
V`20purpose.
X`20*`20The`20author`20shall`20not`20be`20liable`20for`20any`20damages`20result
Ving`20from`20the
X`20*`20use`20of`20this`20software.`20`20By`20using`20this`20software,`20the
V`20user`20agrees
X`20*`20to`20these`20terms.
X`20*/
X
X#include`20"ldb.h"
X
X/*-----------------------------------------------------------------------
X`20*`09apply`20--`20apply`20a`20move`20to`20a`20board
X`20*
X`20*`20Apply`20applies`20a`20move`20to`20a`20board,`20detecting`20the`20follow
Ving`20errors:
X`20*`09RJ_NOROLL`09The`20mv`20struct`20did`20not`20contain`20a`20valid`20roll.
V
X`20*`09RJ_ONBAR`09The`20move`20attempted`20to`20move`20from`20a`20point`20othe
Vr`20than
X`20*`09`09`09the`20bar`20when`20pieces`20are`20on`20the`20bar.
X`20*`09RJ_NOOFF`09The`20move`20attempted`20to`20move`20pieces`20off`20before
V`20all
X`20*`09`09`09pieces`20are`20in`20the`20inner`20table.
X`20*`09RJ_NOPIECE`09The`20move`20attempted`20to`20take`20a`20piece`20from`20an
V`20empty`20point.
X`20*`09RJ_NOTYOURS`09The`20move`20attempted`20to`20move`20the`20opponent's`20p
Viece.
X`20*`09RJ_OCC`09`09The`20move`20attempted`20to`20move`20to`20an`20occupied`20p
Voint.
X`20*`09RJ_EXACT`09The`20move`20attempted`20to`20bear`20off`20a`20piece`20with
V`20a
X`20*`09`09`09larger`20roll`20than`20necessary`20when`20that`20piece`20was
X`20*`09`09`09not`20the`20outermost`20piece.
X`20*`20If`20the`20move`20was`20legal,`20apply`20returns:
X`20*`09MVOK`09`09if`20no`20blot`20was`20hit,`20or
X`20*`09point`20number`09where`20the`20blot`20was`20before`20it`20was`20hit.
X`20*`20Note`20that`20blot`20numbers`20are`20in`20the`20range`20`5B1-24`5D,`20M
VVOK`20is`200,`20and
X`20*`20the`20reject`20codes`20are`20negative.`20`20When`20the`20move`20is`20re
Vjected,
X`20*`20the`20board`20is`20unchanged.`20`20When`20a`20blot`20is`20hit,`20it`20i
Vs`20moved`20to`20the
X`20*`20appropriate`20bar`20point`20automatically.
X`20*
X`20*`20If`20A_REDRAW`20is`20set`20in`20flags,`20apply`20redraws`20the`20releva
Vnt`20portions`20of
X`20*`20the`20screen`20to`20reflect`20the`20move.`20`20If`20A_CHKONLY`20is`20se
Vt`20in`20flags,`20the
X`20*`20move`20is`20checked`20but`20the`20board`20is`20not`20modified.
X`20*-----------------------------------------------------------------------
X`20*/
X
Xapply(g,who,mn,flags,dest)
Xstruct`20game`20*g;`09`09`09/*`20game`20structure`20*/
Xint`20who;`09`09`09/*`20WHO_OPP`20=`20opponent,`20WHO_ME`20=`20me`20*/
Xint`20mn;`09`09`09`09/*`20which`20element`20of`20mv`20array`20*/
Xint`20flags;`09`09`09/*`20A_*`20*/
Xint`20*dest;`09`09`09/*`20where`20to`20store`20destination`20point`20*/
X`7B
Xint`20i,`20j,`20blot;
Xint`20op,`20np;
Xint`20dir;
Xchar`20clr;
Xstruct`20mv`20*m;
Xregister`20struct`20point`20*b`20=`20g->board;
X
Xdir`20=`20(who`20==`20WHO_ME)`20?`20g->mydir`20:`20g->opdir;
Xclr`20=`20(who`20==`20WHO_ME)`20?`20g->mycolor`20:`20g->opcolor;
Xblot`20=`20MVOK;`09`09`09/*`20no`20blot`20hit`20yet`20*/
Xm`20=`20(who`20==`20WHO_ME)`20?`20`26g->mvs`5Bmn`5D`20:`20`26g->opmvs`5Bmn`5D;
V
Xif`20(m->roll`20<=`200)`09`09/*`20sanity`20check`20*/
X`09return(RJ_NOROLL);`09/*`20reject`20move`20*/
Xop`20=`20m->pt;`09`09/*`20starting`20point`20number`20*/
Xif`20(op`20<`200)`09`09/*`20this`20roll`20is`20unused`20*/
X`09return(MVOK);`09/*`20and`20that's`20ok`20*/
Xif`20(`20(op`20==`200)`20`7C`7C`20(op`20==`2025)`20)`09/*`20moving`20off`20bar
V`20*/
X`09op`20=`20BARPT(dir);`09/*`20use`20correct`20bar`20point`20*/
Xelse`20`7B`09`09`09/*`20not`20moving`20off`20bar`20*/
X`09j`20=`20BARPT(dir);`09/*`20make`20sure`20no`20pieces`20still`20on`20bar`20*
V/
X`09if`20(b`5Bj`5D.qty`20>`200)
X`09`09return(RJ_ONBAR);`09/*`20can't`20move,`20pieces`20on`20bar`20*/
X`09`7D
Xnp`20=`20op`20+`20m->roll*dir;`09/*`20move`20piece`20correct`20number`20of`20p
Vts`20*/
Xif`20(`20(np`20<=`200)`20`7C`7C`20(np`20>=`2025)`20)`20`7B
X`09i`20=`20(dir`20>`200)`20?`2019`20:`201;
X`09j`20=`20(dir`20>`200)`20?`2024`20:`206;
X`09if`20(addpcs(b,clr,i,j)+b`5BOFFPT(dir)`5D.qty`20<`2015)`20/*`20all`20pcs
V`20not`20*/
X`09`09return(RJ_NOOFF);`09/*`20in`20inner`20table,`20can't`20move`20off`20*/
X`09if`20(`20(np`20!=`200)`20`26`26`20(np`20!=`2025)`20)`20`7B/*`20using`20bigg
Ver`20roll`20than`20needed`20*/
X`09`09i`20=`20(dir`20>`200)`20?`2019`20`20`20:`20op+1;`20/*`20check`20for`20pc
Vs`20on`20higher`20pts`20*/
X`09`09j`20=`20(dir`20>`200)`20?`20op-1`20:`206;
X`09`09if`20(addpcs(b,clr,i,j)`20>`200)`09/*`20there`20are`20some`20*/
X`09`09`09return(RJ_EXACT);`09/*`20must`20use`20roll`20on`20them`20*/
X`09`09`7D
X`09np`20=`20OFFPT(dir);`09/*`20this`20piece`20is`20moving`20off`20*/
X`09`7D
Xif`20(b`5Bop`5D.qty`20<=`200)`09`09/*`20no`20piece`20here`20to`20move`20*/
X`09return(RJ_NOPIECE);
Xif`20(b`5Bop`5D.color`20!=`20clr)`09/*`20trying`20to`20move`20opponent's`20pie
Vces?`20*/
X`09return(RJ_NOTYOURS);
Xif`20(b`5Bnp`5D.qty`20==`200)`09`09/*`20moving`20to`20an`20empty`20point`20*/
X`09b`5Bnp`5D.color`20=`20b`5Bop`5D.color;`09/*`20copy`20color`20*/
Xif`20(b`5Bnp`5D.color`20!=`20b`5Bop`5D.color)`20`7B`09/*`20moving`20to`20occup
Vied`20pt`20*/
X`09if`20(b`5Bnp`5D.qty`20==`201)`20`7B`09`09/*`20whacked`20a`20blot`20*/
X`09`09blot`20=`20np;`09`09/*`20save`20point`20number`20for`20return`20*/
X`09`09if`20(`20(flags`20`26`20A_CHKONLY)`20==`200)`20`7B
+-+-+-+-+-+-+-+- END OF PART 11 +-+-+-+-+-+-+-+-