home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Source Code 1994 March
/
Source_Code_CD-ROM_Walnut_Creek_March_1994.iso
/
compsrcs
/
games
/
vmsnet
/
maxewr2
/
part04
< prev
next >
Wrap
Internet Message Format
|
1993-07-13
|
97KB
Path: uunet!noc.near.net!howland.reston.ans.net!usc!elroy.jpl.nasa.gov!ames!koriel!lll-winken.llnl.gov!fnnews.fnal.gov!fnnews!SNYDER
From: SNYDER@d0sb10.fnal.gov
Newsgroups: vmsnet.sources.games
Subject: Mazewar for VMS (4/5) (repost)
Date: 14 Jul 1993 06:04:05 GMT
Organization: SUNY Stony Brook High Energy Physics
Lines: 3000
Message-ID: <SNYDER.93Jul14000405@d0sb10.fnal.gov>
NNTP-Posting-Host: d0sb10.fnal.gov
Xref: uunet vmsnet.sources.games:754
-+-+-+-+-+-+-+-+ START OF PART 4 -+-+-+-+-+-+-+-+
XX`6009`6009`6009XORToken(ratLoc->ratId);
XX`6009`6009if`6020((oldVisible`6020!=`6020ratLook->visible)`6020`607C`607C
XX`6009`6009`6020`6020`6020`6020(ratInfo->score`6020!=`6020ratLoc->score))`6020
V`607B
XX`6009`6009`6009ratInfo->score`6020=`6020ratLoc->score;
XX`6009`6009`6009UpdateScoreCard(ratLoc->ratId);
XX`6009`6009`607D
XX`6009`6009ratHealth`605BratLoc->ratId`605D.rcvd`6020=`6020TRUE;
XX`6009`6009break;
XX
XX`6009case`6020RAT_KILL:`6009`6009`6009/*`6020someone`6020shot`6020at`6020me
V`6020*/
XX`6009`6009if`6020(!M.invincible)`6020`607B
XX`6009`6009`6009ratKill`6020=`6020(RatKill)`6020`6026pack->body;
XX`6009`6009`6009holdBreath(ratKill);
XX`6009`6009`607D
XX`6009`6009break;
XX
XX`6009case`6020RAT_DEAD:`6009`6009`6009/*`6020I`6020hit`6020someone`6020*/
XX`6009`6009ratDead`6020=`6020(RatDead)`6020`6026pack->body;
XX`6009`6009if`6020(ratDead->killedBy`6020==`6020M.myRatId)`6020`607B
XX`6009`6009`6009FlashTop();`6009/*`6020got`6020him!`6020*/
XX`6009`6009`6009M.score`6020+=`602010;`6009/*`602010`6020points`6020for`6020a
V`6020kill`6020*/
XX`6009`6009`6009M.score`6020+=`60201;`6009/*`6020make`6020up`6020for`6020shot
V`6020cost`6020*/
XX`6009`6009`6009M.ratcb.rats`605BM.myRatId`605D.score`6020=`6020M.score;
XX`6009`6009`6009UpdateScoreCard(M.myRatId);
XX`6009`6009`6009sendLocToAll();
XX`6009`6009`607D
XX`6009`6009break;
XX
XX`6009case`6020RAT_STATUS:`6009`6009/*`6020new`6020info`6020about`6020everyone
V`6020*/
XX`6009`6009status`6020=`6020(RatStatus)`6020`6026pack->body;
XX`6009`6009if`6020(bcmp(`6026status->rats`605BM.myRatId`605D.addr,`6020`6026M.
VmyAddr,
XX`6009`6009`6009`6020`6020sizeof(M.myAddr))`6020!=`60200)
XX`6009`6009`6009break;`6009`6009/*`6020not`6020for`6020me,`6020from`6020anothe
Vr`6020game`6020*/
XX`6009`6009`6009`6009`6009/*`6020perhaps`6020left`6020over`6020from`6020findDu
Vke()`6020*/
XX
XX`6009`6009/*`6020Have`6020a`6020new`6020table,`6020turn`6020off`6020any`6020v
Visible`6020opponents
XV`6020*/
XX
XX`6009`6009for`6020(ratId`6020=`60200;`6020ratId`6020<`6020MAXRATS;`6020ratId+
V+)
XX`6009`6009`6009if`6020(R2d2`605BratId`605D.visible`6020==`6020TRUE)
XX`6009`6009`6009`6009XORToken(ratId);
XX`6009`6009bcopy((char`6020*)status,`6020(char`6020*)`6026M.ratcb,`6020sizeof(
VRatCb));
XX`6009`6009if`6020(M.ratcb.dukeRat`6020==`6020M.myRatId)
XX`6009`6009`6009M.duke`6020=`6020TRUE;
XX`6009`6009for`6020(ratId`6020=`60200;`6020ratId`6020<`6020MAXRATS;`6020ratId+
V+)`6020`607B
XX`6009`6009`6009TokenVisible(ratId);
XX`6009`6009`6009if`6020(R2d2`605BratId`605D.visible`6020==`6020TRUE)
XX`6009`6009`6009`6009XORToken(ratId);
XX`6009`6009`607D
XX`6009`6009NewScoreCard();
XX`6009`6009ratInfo`6020=`6020`6026M.ratcb.rats`605BM.myRatId`605D;
XX`6009`6009if`6020((ratInfo->xLoc`6020!=`6020M.xloc)`6020`607C`607C
XX`6009`6009`6020`6020`6020`6020(ratInfo->yLoc`6020!=`6020M.yloc)`6020`607C`607
VC
XX`6009`6009`6020`6020`6020`6020(ratInfo->dir`6020`6020!=`6020M.dir))
XX`6009`6009`6009sendLocToAll();
XX`6009`6009
XX`6009`6009break;
XX
XX`6009case`6020RAT_NEW:`6009`6009`6009/*`6020new`6020player`6020*/
XX`6009`6009ratNew`6020=`6020(RatNew)`6020`6026pack->body;
XX`6009`6009if`6020(ratNew->pass`6020==`6020RAT_PASSWORD)`6020`607B
XX`6009`6009`6009if`6020(M.duke)`6020`607B
XX`6009`6009`6009`6009/*`6020
XX`6009`6009`6009`6009`6020*`6020need`6020to`6020check`6020for`6020duplicates
V`6020here;
XX`6009`6009`6009`6009`6020*`6020a`6020previous`6020reply`6020might`6020have
V`6020been
XX`6009`6009`6009`6009`6020*`6020lost.`6020Can't`6020let`6020the`6020same`6020g
Vuy`6020in`6020the
XX`6009`6009`6009`6009`6020*`6020game`6020twice.
XX`6009`6009`6009`6009`6020*/
XX
XX`6009`6009`6009`6009register`6020RatId`6009id;
XX
XX`6009`6009`6009`6009for`6020(id`6020=`60200;`6020id`6020<`6020MAXRATS;`6020id
V++)
XX`6009`6009`6009`6009`6009if`6020(M.ratcb.rats`605Bid`605D.playing`6020`6026
V`6026
XX`6009`6009`6009`6009`6009`6020`6020`6020`6020!bcmp(`6026M.ratcb.rats`605Bid
V`605D.addr,
XX`6009`6009`6009`6009`6009`6009`6020`6020`6026evp->eventSource,
XX`6009`6009`6009`6009`6009`6009`6020`6020sizeof`6020(Sockaddr)))`6020`607B
XX
XX`6009`6009`6009`6009`6009`6009/*`6020already`6020there`6020*/
XX`6009`6009`6009`6009`6009`6009sendStatus(evp->eventSource);
XX`6009`6009`6009`6009`6009`6009break;
XX`6009`6009`6009`6009`6009`607D
XX`6009`6009`6009`6009if`6020(id`6020>=`6020MAXRATS)`6020`607B`6009/*`6020fell
V`6020through`6020*/
XX`6009`6009`6009`6009`6009allocateNewRat(ratNew);
XX`6009`6009`6009`6009`6009sendAllStatus();
XX`6009`6009`6009`6009`607D
XX`6009`6009`6009`607D`6020else
XX`6009`6009`6009`6009sendStatus(evp->eventSource);
XX`6009`6009`607D
XX`6009`6009break;
XX
XX`6009case`6020RAT_GOING:`6009`6009`6020`6020`6020`6020`6020`6020`6020/*`6020p
Vlayer`6020leaving,`6020only
XV`6020rcvd`6020if`6020duke`6020*/
XX`6009`6009ratGone`6020=`6020(RatGone)`6020`6026pack->body;
XX`6009`6009ratLeft(ratGone->ratId);
XX`6009`6009break;
XX
XX`6009case`6020RAT_QUERY:`6009`6009`6009/*`6020are`6020you`6020alive?`6020*/
XX`6009`6009/*
XX`6009`6009`6020*`6020register`6020their`6020net`6020address,`6020in`6020case
V`6020they`6020got`6020a
XX`6009`6009`6020*`6020RAT_MOVE,`6020moved,`6020and`6020the`6020change`6020got
V`6020lost`6020somewhere.
XV
XX`6009`6009`6020*/
XX`6009`6009ratQuery`6020=`6020(RatQuery)`6020`6026pack->body;
XX`6009`6009M.ratcb.rats`605BratQuery->ratId`605D.addr`6020=`6020evp->eventSour
Vce;
XX
XX`6009`6009sendAlive();
XX`6009`6009break;
XX
XX`6009case`6020RAT_ALIVE:`6009`6009`6009/*`6020I`6020am`6020alive`6020*/
XX`6009`6009ratAlive`6020=`6020(RatAlive)`6020`6026pack->body;
XX`6009`6009ratHealth`605BratAlive->ratId`605D.rcvd`6020=`6020TRUE;
XX`6009`6009break;
XX
XX`6009case`6020RAT_SURVEY:`6009`6009/*`6020who's`6020out`6020there?`6020*/
XX`6009`6009ratNew`6020=`6020(RatNew)`6020`6026pack->body;
XX`6009`6009if`6020(ratNew->pass`6020==`6020RAT_PASSWORD)
XX`6009`6009`6009sendStatus(evp->eventSource);
XX`6009`6009break;
XX
XX`6009case`6020RAT_MOVE:`6009`6009`6009/*`6020move`6020to`6020M.mazePort`6020*
V/
XX`6009`6009ratMove`6020=`6020(RatMove)`6020`6026pack->body;
XX`6009`6009if`6020(ratMove->ratId`6020!=`6020M.ratcb.dukeRat)
XX`6009`6009`6009MWError("bogus`6020RAT_MOVE");
XX#ifdef`6020VMS
XX`6009`6009socket_close(M.theSocket);
XX#else
XX`6009`6009close(M.theSocket);
XX#endif
XX
XX`6009`6009/*`6020
XX`6009`6009`6020*`6020If`6020the`6020socket`6020being`6020closed`6020is`6020on
V`6020this`6020machine,
XX`6009`6009`6020*`6020leave`6020some`6020time`6020for`6020the`6020socket`6020t
Vo`6020close`6020down`6020be
XVfore
XX`6009`6009`6020*`6020I`6020try`6020to`6020grab`6020it.
XX`6009`6009`6020*/
XX
XX`6009`6009if`6020(bcmp((char`6020*)`6020`6026evp->eventSource.sin_addr,
XX`6009`6009`6009`6020`6020(char`6020*)`6020`6026M.myAddr.sin_addr,
XX`6009`6009`6009`6020`6020sizeof(M.myAddr.sin_addr))`6020==`60200)
XX`6009`6009`6009sleep(1);
XX
XX`6009`6009/*`6020grab`6020the`6020socket`6020*/
XX
XX`6009`6009newSocket`6020=`6020socket(AF_INET,`6020SOCK_DGRAM,`60200);
XX`6009`6009if`6020(newSocket`6020<`60200)
XX`6009`6009`6009MWError("RAT_MOVE`6020lost`6020socket");
XX#ifdef`6020VMS
XX`6009`6009M.theSocket`6020=`6020newSocket;
XX#else
XX`6009`6009if`6020(dup2(newSocket,`6020M.theSocket)`6020<`60200)
XX`6009`6009`6009MWError("RAT_MOVE`6020dup2`6020failed");
XX#endif
XX`6009`6009`607B
XX`6009`6009`6020`6020int`6020opt`6020=`60201;
XX`6009`6009`6020`6020if`6020(setsockopt(M.theSocket,`6020SOL_SOCKET,`6020SO_RE
VUSEADDR,
XX`6009`6009`6009`6009`6020`6026opt,`6020sizeof`6020(opt))`6020<`60200)
XX`6009`6009`6020`6020`6020`6020MWError("RAT_MOVE`6020can't`6020reuse`6020addre
Vsses");
XX`6009`6009`607D
XX`6009`6009M.myAddr.sin_port`6020=`6020M.mazePort;
XX`6009`6009nullAddr`6020=`6020M.myAddr;`6009/*`6020see`6020netInit()`6020*/
XX`6009`6009bzero((char`6020*)`6020`6026nullAddr.sin_addr,`6020sizeof(nullAddr.
Vsin_addr));
XX`6009`6009if`6020(bind(M.theSocket,`6020`6026nullAddr,`6020sizeof(nullAddr))
V`6020<`60200)
XX`6009`6009`6009MWError("RAT_MOVE`6020can't`6020bind");
XX#ifdef`6020VMS
XX`6009`6009arm_net_input`6020(M.theSocket);
XX#endif
XX`6009`6009M.ratcb.rats`605BM.myRatId`605D.addr`6020=`6020M.myAddr;
XX`6009`6009sendAllStatus();
XX`6009`6009break;
XX
XX`6009default:
XX`6009`6009sprintf(buf,`6020"readRats`6020bad`6020packet`6020type`60200x%x",
V`6020pack->type);
XX`6009`6009MWError(buf);
XX`6009`607D
XX`607D
XX
XX/*`6020
XX`6020*`6020In`6020order`6020to`6020reduce`6020the`6020network`6020traffic,
V`6020only`6020send`6020out
XV`6020the`6020location`6020change`6020if
XX`6020*`6020there's`6020no`6020keyboard`6020input`6020pending.
XX`6020*/
XX
XXSendLocation()
XX`607B
XX`6009Boolean`6009`6009KBEventPending();
XX`6009if`6020(!KBEventPending())
XX`6009`6009if`6020(sendLocation)`6020`607B
XX`6009`6009`6009sendLocToAll();
XX`6009`6009`6009sendLocation`6020=`6020FALSE;
XX`6009`6009`607D
XX`607D
XX
XX/*`6020
XX`6020*`6020Let`6020everyone`6020know`6020I've`6020moved.
XX`6020*/
XX
XXsendLocToAll()
XX`607B
XX`6009RatPacket`6009pack;
XX`6009RatLocation`6009ratloc;
XX`6009RatId`6009`6009i;
XX`6009RatInfo`6009`6009ratInfo`6020=`6020`6026M.ratcb.rats`605BM.myRatId`605D;
V
XX
XX`6009ratInfo->xLoc`6020=`6020M.xloc;`6009`6009/*`6020update`6020my`6020table,
V`6020too`6020*/
XX`6009ratInfo->yLoc`6020=`6020M.yloc;
XX`6009ratInfo->dir`6020`6020=`6020M.dir;
XX`6009ratInfo->score`6020=`6020M.score;
XX
XX`6009pack.type`6020=`6020RAT_LOCATION;
XX`6009ratloc`6020=`6020(RatLocation)`6020`6026pack.body;
XX`6009ratloc->ratId`6020=`6020M.myRatId;
XX`6009ratloc->xLoc`6020=`6020ratInfo->xLoc;
XX`6009ratloc->yLoc`6020=`6020ratInfo->yLoc;
XX`6009ratloc->dir`6020=`6020ratInfo->dir;
XX`6009ratloc->score`6020=`6020ratInfo->score;
XX`6009ConvertOutgoing(`6026pack);
XX`6009
XX`6009/*`6020
XX`6009`6020*`6020Would`6020really`6020like`6020this`6020to`6020be`6020asynchro
Vnous,`6020so`6020play
XV`6020could
XX`6009`6020*`6020continue`6020while`6020the`6020packets`6020are`6020being`6020
Vsent.`6020Of`6020course
XV,`6020then,
XX`6009`6020*`6020the`6020data`6020might`6020change`6020in`6020the`6020midst
V`6020of`6020all`6020this...
XX`6009`6020*/
XX
XX`6009for`6020(i`6020=`60200;`6020i`6020<`6020MAXRATS;`6020i++)
XX`6009`6009if`6020((i`6020!=`6020M.myRatId)`6020`6026`6026`6020(M.ratcb.rats
V`605Bi`605D.playing))
XX`6009`6009`6009if`6020(sendto(M.theSocket,`6020`6026pack,`6020sizeof(pack),
V`60200,
XX`6009`6009`6009`6009`6020`6020`6026M.ratcb.rats`605Bi`605D.addr,`6020sizeof(S
Vockaddr))`6020<`60200)
XX`6009`6009`6009`6009MWError("sendLocToAll");
XX`607D
XX
XXsendAllStatus()
XX`607B
XX`6009RatId`6009i;
XX
XX`6009for`6020(i`6020=`60200;`6020i`6020<`6020MAXRATS;`6020i++)
XX`6009`6009if`6020((i`6020!=`6020M.myRatId)`6020`6026`6026`6020(M.ratcb.rats
V`605Bi`605D.playing))
XX`6009`6009`6009sendStatus(M.ratcb.rats`605Bi`605D.addr);
XX`607D
XX
XX/*`6020
XX`6020*`6020Send`6020the`6020entire`6020status`6020data`6020to`6020a`6020rat.
XX`6020*/
XX
XXsendStatus(to)
XXSockaddr`6020to;
XX`607B
XX`6009RatPacket`6009pack;
XX
XX`6009pack.type`6020=`6020RAT_STATUS;
XX`6009pack.body`6020=`6020M.ratcb;
XX`6009ConvertOutgoing(`6026pack);
XX`6009if`6020(sendto(M.theSocket,`6020`6026pack,`6020sizeof(pack),`60200,`6020
V`6026to,`6020sizeof
XV(to))`6020<`60200)
XX`6009`6009MWError("sendStatus");
XX`607D
XX
XX/*`6020
XX`6020*`6020Tell`6020a`6020player`6020he's`6020being`6020shot`6020at.
XX`6020*/
XX
XXsendKill()
XX`607B
XX`6009RatPacket`6009pack;
XX`6009RatKill`6009`6009ratKill;
XX`6009RatId`6009`6009ixRatId;
XX
XX`6009for`6020(ixRatId`6020=`60200;`6020ixRatId`6020<`6020MAXRATS;`6020ixRatId
V++)`6020`607B
XX`6009`6009if`6020(ixRatId`6020==`6020M.myRatId)
XX`6009`6009`6009continue;
XX`6009`6009if`6020(R2d2`605BixRatId`605D.visible)`6020`607B
XX`6009`6009`6009pack.type`6020=`6020RAT_KILL;
XX`6009`6009`6009ratKill`6020=`6020(RatKill)`6020`6026pack.body;
XX`6009`6009`6009ratKill->ratId`6020=`6020M.myRatId;
XX`6009`6009`6009ratKill->xLoc`6020=`6020M.xloc;
XX`6009`6009`6009ratKill->yLoc`6020=`6020M.yloc;
XX`6009`6009`6009ratKill->dir`6020`6020=`6020M.dir;
XX`6009`6009`6009ConvertOutgoing(`6026pack);
XX`6009`6009`6009if`6020(sendto(M.theSocket,`6020`6026pack,`6020sizeof(pack),
V`60200,
XX`6009`6009`6009`6009`6020`6020`6020`6026M.ratcb.rats`605BixRatId`605D.addr,
XX`6009`6009`6009`6009`6020`6020`6020sizeof(M.ratcb.rats`605BixRatId`605D.addr)
V)`6020<`60200)
XX`6009`6009`6009`6009MWError("sendKill");
XX`6009`6009`607D
XX`6009`607D
XX`607D
XX
XX/*`6020
XX`6020*`6020Tell`6020a`6020shooter`6020he`6020hit`6020me.
XX`6020*/
XX
XXsendDead(killerRatId)
XXRatId`6009killerRatId;
XX`607B
XX`6009RatPacket`6009pack;
XX`6009RatDead`6009`6009ratDead;
XX
XX`6009pack.type`6020=`6020RAT_DEAD;
XX`6009ratDead`6020=`6020(RatDead)`6020`6026pack.body;
XX`6009ratDead->ratId`6020=`6020M.myRatId;
XX`6009ratDead->killedBy`6020=`6020killerRatId;
XX`6009ConvertOutgoing(`6026pack);
XX`6009if`6020(sendto(M.theSocket,`6020`6026pack,`6020sizeof(pack),`60200,
XX`6009`6009`6020`6020`6026M.ratcb.rats`605BkillerRatId`605D.addr,`6020sizeof(S
Vockaddr))`6020<`60200
XV)
XX`6009`6009MWError("sendDead");
XX`607D
XX
XX/*`6020
XX`6020*`6020Tell`6020the`6020duke`6020I'm`6020leaving.
XX`6020*/
XX
XXsendGoing()
XX`607B
XX`6009RatPacket`6009pack;
XX`6009RatGone`6009`6009ratGone;
XX
XX`6009pack.type`6020=`6020RAT_GOING;
XX`6009ratGone`6020=`6020(RatGone)`6020`6026pack.body;
XX`6009ratGone->ratId`6020=`6020M.myRatId;
XX`6009ConvertOutgoing(`6026pack);
XX`6009if`6020(sendto(M.theSocket,`6020`6026pack,`6020sizeof(pack),`60200,
XX`6009`6009`6020`6020`6026M.ratcb.rats`605BM.ratcb.dukeRat`605D.addr,`6020size
Vof(Sockaddr))`6020<
XV`60200)
XX`6009`6009MWError("sendGoing");
XX`607D
XX
XX/*`6020
XX`6020*`6020Ask`6020the`6020silent`6020types`6020if`6020they're`6020alive.
XX`6020*/
XX
XXsendQuery()
XX`607B
XX`6009RatPacket`6009pack;
XX`6009RatId`6009`6009ratId;
XX`6009RatQuery`6009ratQuery;
XX
XX`6009for`6020(ratId`6020=`60200;`6020ratId`6020<`6020MAXRATS;`6020ratId++)
XX`6009`6009if`6020(ratHealth`605BratId`605D.send)`6020`607B
XX`6009`6009`6009pack.type`6020=`6020RAT_QUERY;
XX`6009`6009`6009ratQuery`6020=`6020(RatQuery)`6020`6026pack.body;
XX`6009`6009`6009ratQuery->ratId`6020=`6020M.myRatId;
XX`6009`6009`6009ratHealth`605BratId`605D.send`6020=`6020FALSE;
XX`6009`6009`6009ConvertOutgoing(`6026pack);
XX`6009`6009`6009if`6020(sendto(M.theSocket,`6020`6026pack,`6020sizeof(pack),
V`60200,
XX`6009`6009`6009`6009`6020`6020`6026M.ratcb.rats`605BratId`605D.addr,
XX`6009`6009`6009`6009`6020`6020sizeof(Sockaddr))`6020<`60200)
XX`6009`6009`6009`6009MWError("sendQuery");
XX`6009`6009`607D
XX`607D
XX
XX/*`6020
XX`6020*`6020Register`6020someone`6020as`6020alive,`6020and`6020let`6020them
V`6020know`6020we`6020are,
XV`6020too.`6020
XX`6020*/
XX
XXsendAlive()
XX`607B
XX`6009RatPacket`6009pack;
XX`6009RatId`6009`6009ratId;
XX`6009RatAlive`6009ratAlive;
XX
XX`6009for`6020(ratId`6020=`60200;`6020ratId`6020<`6020MAXRATS;`6020ratId++)
V`6020`607B
XX`6009`6009if`6020((ratId`6020==`6020M.myRatId)`6020`607C`607C
XX`6009`6009`6020`6020`6020`6020!M.ratcb.rats`605BratId`605D.playing)
XX`6009`6009`6009continue;
XX`6009`6009pack.type`6020=`6020RAT_ALIVE;
XX`6009`6009ratAlive`6020=`6020(RatAlive)`6020`6026pack.body;
XX`6009`6009ratAlive->ratId`6020=`6020M.myRatId;
XX`6009`6009ConvertOutgoing(`6026pack);
XX`6009`6009if`6020(sendto(M.theSocket,`6020`6026pack,`6020sizeof(pack),`60200,
V
XX`6009`6009`6020`6020`6020`6020`6020`6020`6026M.ratcb.rats`605BratId`605D.addr
V,`6020sizeof(Sockaddr))
XV`6020<`60200)
XX`6009`6009`6009MWError("sendAlive");
XX`6009`607D
XX`607D
XX
XX/*`6020
XX`6020*`6020Let`6020a`6020new`6020player`6020in`6020the`6020game.
XX`6020*/
XX
XXallocateNewRat(ratNew)
XXRatNew`6009ratNew;
XX`607B
XX`6009RatId`6009ratId;
XX`6009RatInfo`6009ratInfo;
XX
XX`6009for`6020(ratId`6020=`60200;`6020ratId`6020<`6020MAXRATS;`6020ratId++)
V`6020`607B
XX`6009`6009ratInfo`6020=`6020`6026M.ratcb.rats`605BratId`605D;
XX`6009`6009if`6020(!ratInfo->playing)`6020`607B
XX`6009`6009`6009ratInfo->playing`6020=`6020TRUE;
XX`6009`6009`6009ratInfo->xLoc`6020=`6020ratNew->xLoc;
XX`6009`6009`6009ratInfo->yLoc`6020=`6020ratNew->yLoc;
XX`6009`6009`6009ratInfo->dir`6020`6020=`6020ratNew->dir;
XX`6009`6009`6009ratInfo->score`6020=`60200;
XX`6009`6009`6009ratInfo->addr`6020=`6020ratNew->addr;
XX`6009`6009`6009strncpy(ratInfo->name,`6020ratNew->name,`6020NAMESIZE);
XX`6009`6009`6009TokenVisible(ratId);
XX`6009`6009`6009UpdateScoreCard(ratId);
XX`6009`6009`6009if`6020(R2d2`605BratId`605D.visible`6020==`6020TRUE)
XX`6009`6009`6009`6009XORToken(ratId);
XX`6009`6009`6009AddNewPlayer(ratId,`6020ratNew->xLoc,`6020ratNew->yLoc,
XX`6009`6009`6009`6009`6009ratNew->dir);
XX`6009`6009`6009return;
XX`6009`6009`607D
XX`6009`607D
XX`607D
XX
XX/*`6020
XX`6020*`6020I`6020wanna`6020go`6020home!
XX`6020*/
XX
XXquit()
XX`607B
XX`6009RatId`6009ratId;
XX
XX`6009if`6020(!M.duke)
XX`6009`6009sendGoing();
XX`6009else`6020`607B`6009`6009`6009`6009/*`6020oh`6020oh,`6020I'm`6020the`6020
Vduke`6020rat`6020*/
XX`6009`6009M.ratcb.rats`605BM.myRatId`605D.playing`6020=`6020FALSE;
XX`6009`6009for`6020(ratId`6020=`60200;`6020ratId`6020<`6020MAXRATS;`6020ratId+
V+)
XX`6009`6009`6009if`6020(M.ratcb.rats`605BratId`605D.playing)`6020`607B
XX`6009`6009`6009`6009M.ratcb.dukeRat`6020=`6020ratId;
XX`6009`6009`6009`6009sendAllStatus();
XX`6009`6009`6009`6009break;
XX`6009`6009`6009`607D
XX`6009`6009moveSomeone(M.myRatId);
XX`6009`607D
XX`6009StopWindow();
XX`6009exit(0);
XX`607D
XX
XX/*`6020
XX`6020*`6020Clean`6020up`6020after`6020someone`6020who`6020has`6020left.`6020L
Vet`6020everyone`6020els
XVe`6020know,`6020too.
XX`6020*/
XX
XXratLeft(ratId)
XXRatId`6009ratId;
XX`607B
XX`6009if`6020(R2d2`605BratId`605D.visible`6020==`6020TRUE)
XX`6009`6009XORToken(ratId);
XX`6009R2d2`605BratId`605D.visible`6020=`6020FALSE;
XX`6009M.ratcb.rats`605BratId`605D.playing`6020=`6020FALSE;
XX`6009ExitPlayer(ratId);
XX`6009UpdateScoreCard(ratId);
XX`6009sendAllStatus();
XX`6009moveSomeone(ratId);
XX`607D
XX
XX/*`6020
XX`6020*`6020See`6020if`6020the`6020guy`6020leaving`6020has`6020vacated`6020the
V`6020reserved`6020port.
XV`6020If`6020so,`6020try`6020to
XX`6020*`6020find`6020someone`6020else`6020on`6020that`6020machine`6020and`6020
Vtell`6020him`6020to`6020m
XVove`6020there.
XX`6020*/
XX
XXmoveSomeone(ratId)
XXRatId`6009ratId;
XX`607B
XX`6009Sockaddr`6009hisAddr;
XX`6009RatId`6009`6009newRat;
XX`6009RatPacket`6009pack;
XX`6009RatMove`6009`6009ratMove;
XX
XX`6009hisAddr`6020=`6020M.ratcb.rats`605BratId`605D.addr;
XX`6009if`6020(hisAddr.sin_port`6020!=`6020M.mazePort)
XX`6009`6009return;
XX
XX`6009for`6020(newRat`6020=`60200;`6020newRat`6020<`6020MAXRATS;`6020newRat++)
V`6020`607B
XX`6009`6009if`6020(newRat`6020==`6020ratId)
XX`6009`6009`6009continue;
XX`6009`6009if`6020(M.ratcb.rats`605BnewRat`605D.playing`6020==`6020FALSE)
XX`6009`6009`6009continue;
XX`6009`6009if`6020(!bcmp(`6026M.ratcb.rats`605BnewRat`605D.addr.sin_addr,
XX`6009`6009`6009`6020`6020`6026hisAddr.sin_addr,`6020sizeof(hisAddr.sin_addr))
V)`6020`607B
XX`6009`6009`6009pack.type`6020=`6020RAT_MOVE;
XX`6009`6009`6009ratMove`6020=`6020(RatMove)`6020`6026pack.body;
XX`6009`6009`6009ratMove->ratId`6020=`6020M.ratcb.dukeRat;
XX`6009`6009`6009ConvertOutgoing(`6026pack);
XX`6009`6009`6009if`6020(sendto(M.theSocket,`6020`6026pack,`6020sizeof(pack),
V`60200,
XX`6009`6009`6009`6009`6020`6020`6026M.ratcb.rats`605BnewRat`605D.addr,
XX`6009`6009`6009`6009`6020`6020sizeof(Sockaddr))`6020<`60200)
XX`6009`6009`6009`6009MWError("moveSomeone");
XX
XX`6009`6009`6009/*`6020
XX`6009`6009`6009`6020*`6020If`6020I'm`6020the`6020one`6020leaving,`6020must
V`6020free`6020up`6020my`6020port
XV.
XX`6009`6009`6009`6020*/
XX
XX`6009`6009`6009if`6020(ratId`6020==`6020M.myRatId)
XX#ifdef`6020VMS
XX`6009`6009`6009`6009socket_close(M.theSocket);
XX#else
XX`6009`6009`6009`6009close(M.theSocket);
XX#endif
XX`6009`6009`6009break;
XX`6009`6009`607D
XX`6009`607D
XX`6009`6009
XX`607D
XX
XX/*`6020
XX`6020*`6020Make`6020sure`6020nobody`6020has`6020died`6020unnoticed.
XX`6020*/
XX
XXstatic`6020Boolean`6009`6009started`6020=`6020FALSE;
XXstruct`6020timeval`6009waitStart;
XXstatic`6020Boolean`6009`6009runDoctor`6020=`6020TRUE;
XX
XXstatic
XXratDoctor()
XX`607B
XX`6009RatId`6009ratId,`6020nextRatId();
XX`6009struct`6020timeval`6009now;
XX
XX`6009if`6020(!runDoctor)
XX`6009`6009return;
XX
XX`6009if`6020(started`6020==`6020FALSE)`6020`607B
XX`6009`6009gettimeofday(`6026waitStart,`6020NULL);
XX`6009`6009for`6020(ratId`6020=`60200;`6020ratId`6020<`6020MAXRATS;`6020ratId+
V+)`6020`607B
XX`6009`6009`6009ratHealth`605BratId`605D.count`6020=`60200;
XX`6009`6009`6009ratHealth`605BratId`605D.send`6020=`6020FALSE;
XX`6009`6009`6009ratHealth`605BratId`605D.rcvd`6020=`6020FALSE;
XX`6009`6009`607D
XX`6009`6009started`6020=`6020TRUE;
XX`6009`6009return;
XX`6009`607D`6020else`6020`607B
XX`6009`6009gettimeofday(`6026now,`6020NULL);
XX`6009`6009if`6020((now.tv_sec`6020-`6020waitStart.tv_sec)`6020<`60205)
XX`6009`6009`6009return;
XX`6009`6009for`6020(ratId`6020=`60200;`6020ratId`6020<`6020MAXRATS;`6020ratId+
V+)`6020`607B
XX`6009`6009`6009if`6020((!M.ratcb.rats`605BratId`605D.playing)`6020`607C`607C
XX`6009`6009`6009`6020`6020`6020`6020(ratId`6020==`6020M.myRatId))
XX`6009`6009`6009`6009continue;
XX`6009`6009`6009if`6020(ratHealth`605BratId`605D.rcvd)`6020`607B
XX`6009`6009`6009`6009ratHealth`605BratId`605D.count`6020=`60200;
XX`6009`6009`6009`6009ratHealth`605BratId`605D.rcvd`6020=`6020FALSE;
XX`6009`6009`6009`6009continue;
XX`6009`6009`6009`607D
XX`6009`6009`6009if`6020(++ratHealth`605BratId`605D.count`6020<`60205)`6020`607
VB
XX`6009`6009`6009`6009ratHealth`605BratId`605D.send`6020=`6020TRUE;
XX`6009`6009`6009`6009continue;
XX`6009`6009`6009`607D
XX`6009`6009`6009if`6020(M.duke`6020`607C`607C
XX`6009`6009`6009`6020`6020`6020`6020((M.ratcb.dukeRat`6020==`6020ratId)`6020
V`6026`6026
XX`6009`6009`6009`6020`6020`6020`6020`6020(nextRatId(ratId)`6020==`6020M.myRatI
Vd)))`6020`607B
XX`6009`6009`6009`6009M.duke`6020=`6020TRUE;
XX`6009`6009`6009`6009M.ratcb.dukeRat`6020=`6020M.myRatId;
XX`6009`6009`6009`6009ratLeft(ratId);
XX`6009`6009`6009`607D
XX`6009`6009`607D
XX`6009`6009sendQuery();
XX`6009`6009gettimeofday(`6026waitStart,`6020NULL);
XX`6009`607D
XX`6009
XX`607D
XX
XXRatId
XXnextRatId(ratId)
XXRatId`6009ratId;
XX`607B
XX`6009RatId`6009ixRatId;
XX
XX`6009for`6020(ixRatId`6020=`60200;`6020ixRatId`6020<`6020MAXRATS;`6020ixRatId
V++)
XX`6009`6009if`6020(M.ratcb.rats`605BixRatId`605D.playing`6020`6026`6026
XX`6009`6009`6020`6020`6020`6020(ixRatId`6020!=`6020ratId))
XX`6009`6009`6009return`6020ixRatId;
XX`6009return`6020ixRatId;
XX`607D
XX
XXNewPosition()
XX`607B
XX`6009register`6009rndCnt`6020=`60200;
XX
XX`6009M.xloc`6020=`6020M.yloc`6020=`60200;`6009`6009/*`6020start`6020on`6020oc
Vcupied`6020square`6020*/
XX`6009while`6020(mp`605BM.xloc`605D.y`605BM.yloc`605D)`6020`607B
XX`6009`6009M.xloc`6020=`6020random(MAZEXMAX);
XX`6009`6009M.yloc`6020=`6020random(MAZEYMAX);
XX`6009`6009if`6020(++rndCnt`6020==`6020100)`6020`607B
XX`6009`6009`6009rndCnt`6020=`60200;
XX`6009`6009`6009InitRandom();
XX`6009`6009`607D
XX`6009`607D
XX
XX`6009/*`6020prevent`6020a`6020blank`6020wall`6020at`6020first`6020glimpse`602
V0*/
XX
XX`6009if`6020(!M.maze`605BM.xloc+1`605D.y`605BM.yloc`605D)`6020M.dir`6020=`602
V0NORTH;
XX`6009if`6020(!M.maze`605BM.xloc-1`605D.y`605BM.yloc`605D)`6020M.dir`6020=`602
V0SOUTH;
XX`6009if`6020(!M.maze`605BM.xloc`605D.y`605BM.yloc+1`605D)`6020M.dir`6020=`602
V0EAST;
XX`6009if`6020(!M.maze`605BM.xloc`605D.y`605BM.yloc-1`605D)`6020M.dir`6020=`602
V0WEST;
XX
XX`6009return;
XX`607D
XX
XX/*`6020re-initialize`6020the`6020maze`6020randomization`6020vector`6020*/
XXInitRandom()
XX`607B
XX`6009struct`6020timeval`6009t;
XX`6009struct`6020timezone`6009tz;
XX`6009register`6020int`6009i;
XX
XX`6009gettimeofday(`6026t,`6020`6026tz);
XX`6009for`6020(i`6020=`60200;`6020i`6020<`6020VECTORSIZE;`6020i++)
XX`6009`6009M.randomVector`605Bi`605D`6020=`6020M.randomVector`605Bi`605D`6020+
V`6020t.tv_sec`6020`6026
XV`60200xffff;
XX`607D
XX
XXrandom(limit)
XXregister`6020int`6009limit;
XX`607B
XX`6009register`6020unsigned`6020int`6009ret;
XX
XX`6009ret`6020=`6020M.randomVector`605Bi1`605D`6020=`6020M.randomVector`605Bi1
V`605D`6020+`6020M.rando
XVmVector`605Bi2`605D;
XX`6009if`6020(++i1`6020>=`6020VECTORSIZE)
XX`6009`6009i1`6020=`60200;
XX`6009if`6020(++i2`6020>=`6020VECTORSIZE)
XX`6009`6009i2`6020=`60200;
XX`6009return`6020ret%limit;
XX`607D
XX
XXMWError(s)
XXchar`6020*s;
XX`607B
XX`6009StopWindow();
XX`6009fprintf(stderr,`6020"MazeWar:`6020%s`605Cn",`6020s);
XX`6009perror("MazeWar");
XX`6009exit(-1);
XX`607D
X$`20call`20unpack`20MAZEWAR.C;16`20908553038`20""
X$!
X$`20create`20'f'
XX
XX
XX
XXMAZEWAR(6)`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
V`6020`6020`6020`6020`6020`6020`6020`6020`6020
XV`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
V`6020`6020`6020`6020`6020`6020`6020`6020MAZEWAR(6
XV)
XX
XX
XXN`6008NA`6008AM`6008ME`6008E
XX`6020`6020`6020`6020`6020MazeWar`6020-`6020distributed`6020rats`6020in`6020a
V`6020maze
XX
XXS`6008SY`6008YN`6008NT`6008TA`6008AX`6008X
XX`6020`6020`6020`6020`6020/`6008/u`6008us`6008sr`6008r/`6008/g`6008ga`6008am
V`6008me`6008es`6008s/`6008/m`6008mw
XV`6008w`6020`605B`6020_`6008w_`6008i_`6008n_`6008d_`6008o_`6008w`6020_`6008s_
V`6008y_`6008s_`6008t_`6008e_`6008m
XV`6020_`6008o_`6008p_`6008t_`6008i_`6008o_`6008n_`6008s`6020`605D
XX
XXD`6008DE`6008ES`6008SC`6008CR`6008RI`6008IP`6008PT`6008TI`6008IO`6008ON`6008N
V
XX`6020`6020`6020`6020`6020This`6020`6020program`6020implements`6020the`6020age
V-old`6020game`6020of`6020Ma
XVzeWar.`6020`6020Maze-
XX`6020`6020`6020`6020`6020War`6020first`6020appeared`6020at`6020MIT`6020in`602
V0the`6020early`6020`60201970s
XV,`6020`6020using`6020`6020IMLAC
XX`6020`6020`6020`6020`6020displays`6020`6020and`6020`6020the`6020`6020ArpaNet
V`6020network.`6020`6020Legend
XV`6020has`6020it`6020that,`6020at
XX`6020`6020`6020`6020`6020one`6020point`6020during`6020that`6020period,`6020Ma
VzeWar`6020was`6020`6020bann
XVed`6020`6020by`6020`6020DARPA
XX`6020`6020`6020`6020`6020from`6020`6020the`6020ArpaNet`6020because`6020half
V`6020of`6020all`6020the`6020pac
XVkets`6020in`6020a`6020given
XX`6020`6020`6020`6020`6020month`6020were`6020MazeWar`6020packets`6020flying
V`6020between`6020Stanford
XV`6020and`6020`6020MIT.
XX
XX`6020`6020`6020`6020`6020MazeWar`6020`6020appeared`6020again`6020at`6020the
V`6020Xerox`6020Palo`6020Alto
XV`6020Research`6020Cen-
XX`6020`6020`6020`6020`6020ter`6020in`6020the`6020late`60201970's`6020on`6020th
Ve`6020Alto,`6020the`6020first
XV`6020personal`6020`6020com-
XX`6020`6020`6020`6020`6020puter.`6020`6020`6020This`6020`6020version`6020`6020
Vhas`6020subsequently`6020been
XV`6020ported`6020to`6020many
XX`6020`6020`6020`6020`6020personal`6020machines,`6020and`6020forms`6020the`602
V0basis`6020for`6020`6020thi
XVs`6020`6020Unix`6020`6020ver-
XX`6020`6020`6020`6020`6020sion.
XX
XX`6020`6020`6020`6020`6020_`6008M_`6008w`6020`6020attempts`6020`6020to`6020be
V`6020as`6020faithful`6020to`6020th
XVe`6020original`6020Alto`6020version
XX`6020`6020`6020`6020`6020as`6020possible.`6020`6020The`6020shape`6020and`6020
Vpictures`6020of`6020the`6020m
XVaze`6020are`6020`6020as`6020`6020in
XX`6020`6020`6020`6020`6020the`6020`6020original,`6020and`6020there`6020are`602
V0no`6020embellishments
XV`6020such`6020as`6020tele-
XX`6020`6020`6020`6020`6020port`6020traps`6020or`6020robot`6020amanuenses.
XX
XXP`6008PL`6008LA`6008AY`6008Y
XX`6020`6020`6020`6020`6020You,`6020the`6020player,`6020are`6020a`6020rat`6020i
Vn`6020a`6020maze,`6020and`6020t
XVhe`6020`6020objective`6020`6020is
XX`6020`6020`6020`6020`6020to`6020find`6020your`6020opponents`6020and`6020shoot
V`6020them`6020before`6020th
XVey`6020shoot`6020you.
XX
XX`6020`6020`6020`6020`6020Each`6020of`6020the`6020(up`6020to`6020eight)`6020pl
Vayers`6020in`6020a`6020game
XV`6020may`6020be`6020on`6020a`6020dif-
XX`6020`6020`6020`6020`6020ferent`6020`6020host.`6020`6020`6020Upon`6020`6020st
Vartup,`6020you`6020are`6020aske
XVd`6020for`6020the`6020name`6020by
XX`6020`6020`6020`6020`6020which`6020you`6020wish`6020to`6020be`6020known`6020f
Vor`6020the`6020duration`6020o
XVf`6020the`6020game,`6020and
XX`6020`6020`6020`6020`6020the`6020`6020name`6020of`6020the`6020`6060`6060Duke
V`6020host''.`6020`6020If`6020you
XV`6020type`6020a`6020bare`6020carriage
XX`6020`6020`6020`6020`6020return`6020to`6020this`6020query,`6020_`6008m_`6008w
V`6020will`6020find`6020a`6020ga
XVme`6020by`6020broadcasting`6020on
XX`6020`6020`6020`6020`6020the`6020`6020local`6020network,`6020and`6020join`602
V0any`6020game`6020it`6020find
XVs.`6020`6020If`6020you`6020wish
XX`6020`6020`6020`6020`6020to`6020join`6020a`6020specific`6020game,`6020or`6020
Va`6020game`6020on`6020`6020anot
XVher`6020`6020network,`6020`6020or
XX`6020`6020`6020`6020`6020your`6020`6020network`6020doesn't`6020support`6020br
Voadcasting,`6020type
XV`6020in`6020the`6020name
XX`6020`6020`6020`6020`6020of`6020one`6020of`6020the`6020hosts`6020involved`602
V0`6020in`6020`6020that`6020`6020g
XVame.`6020`6020`6020The`6020`6020program
XX`6020`6020`6020`6020`6020_`6008m_`6008a_`6008z_`6008e_`6008f_`6008i_`6008n_
V`6008d`6020`6020will`6020`6020aid`6020
XV`6020you`6020`6020in`6020finding`6020out`6020what`6020games`6020are`6020cur-
XX`6020`6020`6020`6020`6020rently`6020being`6020played.
XX
XX`6020`6020`6020`6020`6020Once`6020in`6020a`6020game,`6020you`6020are`6020`602
V0presented`6020`6020with`6020
XV`6020the`6020`6020game`6020`6020window.
XX`6020`6020`6020`6020`6020This`6020window`6020is`6020made`6020up`6020of`6020th
Vree`6020sections.`6020`6020Th
XVe`6020upper`6020section
XX`6020`6020`6020`6020`6020is`6020a`6020perspective`6020view`6020of`6020your
V`6020view`6020forward.`6020
XV`6020By`6020pressing`6020the
XX`6020`6020`6020`6020`6020left`6020`6020or`6020`6020right`6020`6020mouse`6020
V`6020buttons,`6020you`6020may
XV`6020peek`6020to`6020the`6020left`6020or
XX`6020`6020`6020`6020`6020right`6020around`6020corners.
XX
XX`6020`6020`6020`6020`6020The`6020middle`6020section`6020of`6020the`6020window
V`6020is`6020a`6020top`6020vie
XVw`6020of`6020the`6020`6020maze,
XX`6020`6020`6020`6020`6020showing`6020`6020your`6020current`6020position`6020a
Vnd`6020heading`6020in`6020t
XVhe`6020maze.`6020`6020You
XX`6020`6020`6020`6020`6020move`6020around`6020the`6020maze`6020by`6020using
V`6020the`6020following`6020key
XVs:
XX
XX`6020`6020`6020`6020`6020A`6020`6020`6020`6020`6020About`6020face;`6020flip
V`6020end-for-end
XX`6020`6020`6020`6020`6020S`6020`6020`6020`6020`6020Turn`602090`6020degrees
V`6020left
XX`6020`6020`6020`6020`6020D`6020`6020`6020`6020`6020Move`6020forward`6020one
V`6020cell
XX
XX
XX
XX`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
V`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
XV`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
V`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
XV`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`60201
XX
XX
XX
XX
XX
XXMAZEWAR(6)`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
V`6020`6020`6020`6020`6020`6020`6020`6020`6020
XV`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
V`6020`6020`6020`6020`6020`6020`6020`6020MAZEWAR(6
XV)
XX
XX
XX`6020`6020`6020`6020`6020F`6020`6020`6020`6020`6020Turn`602090`6020degrees
V`6020right
XX`6020`6020`6020`6020`6020<space>Move`6020backward`6020one`6020cell
XX`6020`6020`6020`6020`6020Q`6020`6020`6020`6020`6020Quit
XX
XX`6020`6020`6020`6020`6020For`6020left-handers,`6020there`6020are`6020equivale
Vnts`6020on`6020the`6020nu
XVmeric`6020`6020key-
XX`6020`6020`6020`6020`6020pad.`6020`6020On`6020the`6020DEC`6020LK201`6020keybo
Vard,`6020the`6020`60604',`6020
XV`60605',`6020`60606',`6020`6060,',`6020and
XX`6020`6020`6020`6020`6020right`6020cursor`6020arrow`6020keys`6020perform`6020
Vthe`6020equivalent`6020op
XVerations.
XX
XX`6020`6020`6020`6020`6020The`6020lower`6020section`6020of`6020the`6020window
V`6020shows`6020the`6020names
XV`6020`6020and`6020`6020scores
XX`6020`6020`6020`6020`6020of`6020`6020the`6020`6020other`6020`6020players`6020
Vin`6020the`6020game.`6020`6020Whe
XVn`6020you`6020sight`6020another
XX`6020`6020`6020`6020`6020rat,`6020that`6020rat's`6020score`6020line`6020is
V`6020highlighted.`6020`6020Sho
XVot`6020by`6020`6020press-
XX`6020`6020`6020`6020`6020ing`6020`6020the`6020`6020middle`6020`6020mouse`6020
V`6020button.`6020`6020`6020When
XV`6020you`6020are`6020shot`6020at,`6020the
XX`6020`6020`6020`6020`6020mouse`6020cursor`6020changes`6020from`6020a`6020rat
V`6020to`6020a`6020dead`6020rat
XV,`6020and`6020you`6020`6020have
XX`6020`6020`6020`6020`6020one`6020`6020second`6020to`6020move`6020out`6020of
V`6020the`6020way`6020of`6020the
XV`6020shot`6020or`6020shoot`6020back
XX`6020`6020`6020`6020`6020or`6020both.`6020`6020A`6020shot`6020costs`6020one
V`6020point;`6020`6020getting
XV`6020`6020hit`6020`6020costs`6020`6020five
XX`6020`6020`6020`6020`6020points;`6020`6020hitting`6020someone`6020adds`6020te
Vn`6020points.`6020`6020When
XV`6020you`6020are`6020hit,
XX`6020`6020`6020`6020`6020the`6020screen`6020flashes`6020and`6020you`6020are
V`6020transported`6020to`6020
XV`6020another`6020`6020sec-
XX`6020`6020`6020`6020`6020tion`6020of`6020the`6020maze.
XX
XX`6020`6020`6020`6020`6020If`6020your`6020window`6020system`6020supports`6020i
Vt,`6020when`6020you`6020ico
XVnify`6020the`6020game
XX`6020`6020`6020`6020`6020window,`6020it`6020will`6020let`6020you`6020know`602
V0when`6020someone`6020joins
XV`6020the`6020game`6020`6020or
XX`6020`6020`6020`6020`6020shoots`6020`6020at`6020`6020you`6020(by`6020flashing
V,`6020in`6020most`6020cases).
XV`6020`6020This`6020way,`6020you
XX`6020`6020`6020`6020`6020can`6020be`6020notified`6020whenever`6020someone`602
V0else`6020is`6020interest
XVed`6020in`6020wast-
XX`6020`6020`6020`6020`6020ing`6020some`6020time,`6020by`6020always`6020leaving
V`6020a`6020game`6020around.
XV
XX
XXS`6008SE`6008EE`6008E`6020A`6008AL`6008LS`6008SO`6008O
XX`6020`6020`6020`6020`6020mazefind(6)
XX
XXA`6008AU`6008UT`6008TH`6008HO`6008OR`6008R
XX`6020`6020`6020`6020`6020Christopher`6020A.`6020Kent
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX
XX`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
V`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
XV`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
V`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020
XV`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`6020`60202
X+-+-+-+-+-+-+-+-`20`20END`20`20OF`20PART`205`20+-+-+-+-+-+-+-+-
$ call unpack [.MAZEWAR]MAZEWAR.5;1 672902849 ""
$!
$ create 'f'
X.TH`20MAZEWAR`206
X.SH`20NAME
XMazeWar`20`5C-`20distributed`20rats`20in`20a`20maze
X.SH`20SYNTAX
X.B`20/usr/games/mw
X`5B
X.I`20
Xwindow`20system`20options
X`5D
X.SH`20DESCRIPTION
XThis`20program`20implements`20the`20age-old`20game`20of`20MazeWar.
XMazeWar`20first`20appeared`20at`20MIT`20in`20the`20early`201970s,`20using`20IM
VLAC`20displays`20and
Xthe`20ArpaNet`20network.
XLegend`20has`20it`20that,`20at`20one`20point`20during`20that`20period,`20MazeW
Var`20was`20banned
Xby`20DARPA`20from`20the`20ArpaNet`20because`20half`20of`20all`20the`20packets
V`20in`20a`20given
Xmonth`20were`20MazeWar`20packets`20flying`20between`20Stanford`20and`20MIT.
X.PP
XMazeWar`20appeared`20again`20at`20the`20Xerox`20Palo`20Alto`20Research`20Cente
Vr`20in`20the`20late
X1970's`20on`20the`20Alto,`20the`20first`20personal`20computer.
XThis`20version`20has`20subsequently`20been`20ported`20to`20many
Xpersonal`20machines,`20and`20forms`20the`20basis`20for`20this`20Unix`20version
V.
X.PP
X.I`20Mw
Xattempts`20to`20be`20as`20faithful`20to`20the`20original`20Alto`20version`20as
V`20possible.`20
XThe`20shape`20and`20pictures`20of`20the`20maze`20are`20as`20in`20the`20origina
Vl,`20and`20there`20are
Xno`20embellishments`20such`20as`20teleport`20traps`20or`20robot`20amanuenses.
X.SH`20PLAY
XYou,`20the`20player,`20are`20a`20rat`20in`20a`20maze,`20and`20the`20objective
V`20is`20to`20
Xfind`20your`20opponents`20and`20shoot`20them`20before`20they`20shoot`20you.
X.PP
XEach`20of`20the`20(up`20to`20eight)`20players`20in`20a`20game`20may`20be`20on
V`20a`20different`20host.`20
XUpon`20startup,`20you`20are`20asked`20for`20the`20name`20by`20which`20you`20wi
Vsh`20to`20be`20known`20for
Xthe`20duration`20of`20the`20game,`20and`20the`20name`20of`20the`20`60`60Duke
V`20host''.
XIf`20you`20type`20a`20bare`20carriage`20return`20to`20this`20query,`20
X.I`20mw
Xwill`20find`20a`20game`20by`20broadcasting`20on`20the`20local`20network,`20and
V`20join`20any`20game
Xit`20finds.`20
XIf`20you`20wish`20to`20join`20a`20specific`20game,`20or`20a`20game`20on`20anot
Vher`20network,`20or`20your
Xnetwork`20doesn't`20support`20broadcasting,
Xtype`20in`20the`20name`20of`20one`20of`20the`20hosts`20involved`20in`20that
V`20game.
XThe`20program
X.I`20mazefind
Xwill`20aid`20you`20in`20finding`20out`20what`20games`20are`20currently`20being
V`20played.
X.PP
XOnce`20in`20a`20game,`20you`20are`20presented`20with`20the`20game`20window.
XThis`20window`20is`20made`20up`20of`20three`20sections.
XThe`20upper`20section`20is`20a`20perspective`20view`20of`20your`20view`20forwa
Vrd.`20
XBy`20pressing
Xthe`20left`20or`20right`20mouse`20buttons,`20you`20may`20peek`20to`20the`20lef
Vt`20or`20right`20around
Xcorners.
X.PP
XThe`20middle`20section`20of`20the`20window`20is`20a`20top`20view`20of`20the
V`20maze,`20showing`20your
Xcurrent`20position`20and`20heading`20in`20the`20maze.`20
XYou`20move`20around`20the`20maze`20by`20using`20the`20following`20keys:
X.sp
X.ta`20.6i
X.nf
XA`09About`20face;`20flip`20end`5C-for`5C-end
XS`09Turn`2090`20degrees`20left
XD`09Move`20forward`20one`20cell
XF`09Turn`2090`20degrees`20right
X<space>`09Move`20backward`20one`20cell
XQ`09Quit
X.fi
X.sp
XFor`20left`5C-handers,`20there`20are`20equivalents`20on`20the`20numeric`20keyp
Vad.`20
XOn`20the`20DEC`20LK201`20keyboard,`20the`20`604',`20`605',`20`606',`20`60,',
V`20and`20right`20cursor`20arrow
Xkeys`20perform`20the`20equivalent`20operations.
X.PP
XThe`20lower`20section`20of`20the`20window`20shows`20the`20names`20and`20scores
V`20of`20the`20other
Xplayers`20in`20the`20game.
XWhen`20you`20sight`20another`20rat,`20that`20rat's`20score`20line`20is`20highl
Vighted.
XShoot`20by`20pressing`20the`20middle`20mouse`20button.
XWhen`20you`20are`20shot`20at,`20the`20mouse`20cursor`20changes`20from`20a`20ra
Vt`20to`20a`20dead`20rat,
Xand`20you`20have`20one`20second`20to`20move`20out`20of`20the`20way`20of`20the
V`20shot`20or`20shoot`20back
Xor`20both.
XA`20shot`20costs`20one`20point;`20getting`20hit`20costs`20five`20points;`20hit
Vting`20someone
Xadds`20ten`20points.
XWhen`20you`20are`20hit,`20the`20screen`20flashes`20and`20you`20are`20transport
Ved`20to`20another
Xsection`20of`20the`20maze.
X.PP
XIf`20your`20window`20system`20supports`20it,`20when`20you`20iconify`20the`20ga
Vme`20window,`20it
Xwill`20let`20you`20know`20when`20someone`20joins`20the`20game`20or`20shoots
V`20at`20you`20(by
Xflashing,`20in`20most`20cases).
XThis`20way,`20you`20can`20be`20notified`20whenever`20someone`20else`20is`20int
Verested`20in
Xwasting`20some`20time,`20by`20always`20leaving`20a`20game`20around.
X.SH`20"SEE`20ALSO"
Xmazefind(6)
X.SH`20AUTHOR
XChristopher`20A.`20Kent
$ call unpack [.MAZEWAR]MAZEWAR.6;1 33627330 ""
$!
$ create 'f'
X/*`20$Header:`20mazewar.c,v`201.13`2088/08/25`2009:57:53`20kent`20Exp`20$`20*/
V
X
X/*`20
X`20*`20mazewar.c`20-`20Rats`20in`20a`20maze
X`20*`20
X`20*`20Author:`09Christopher`20A.`20Kent
X`20*`20`09`09Western`20Research`20Laboratory
X`20*`20`09`09Digital`20Equipment`20Corporation
X`20*`20Date:`09Wed`20Sep`2024`201986
X`20*/
X
X/***********************************************************
XCopyright`201986`20by`20Digital`20Equipment`20Corporation,`20Maynard,`20Massac
Vhusetts,
X
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20All
V`20Rights`20Reserved
X
XPermission`20to`20use,`20copy,`20modify,`20and`20distribute`20this`20software
V`20and`20its`20
Xdocumentation`20for`20any`20purpose`20and`20without`20fee`20is`20hereby`20gran
Vted,`20
Xprovided`20that`20the`20above`20copyright`20notice`20appear`20in`20all`20copie
Vs`20and`20that
Xboth`20that`20copyright`20notice`20and`20this`20permission`20notice`20appear
V`20in`20
Xsupporting`20documentation,`20and`20that`20the`20names`20of`20Digital`20not
V`20be
Xused`20in`20advertising`20or`20publicity`20pertaining`20to`20disstribution`20o
Vf`20the
Xsoftware`20without`20specific,`20written`20prior`20permission.`20`20
X
XDIGITAL`20DISCLAIMS`20ALL`20WARRANTIES`20WITH`20REGARD`20TO`20THIS`20SOFTWARE,
V`20INCLUDING
XALL`20IMPLIED`20WARRANTIES`20OF`20MERCHANTABILITY`20AND`20FITNESS,`20IN`20NO
V`20EVENT`20SHALL
XDIGITAL`20BE`20LIABLE`20FOR`20ANY`20SPECIAL,`20INDIRECT`20OR`20CONSEQUENTIAL
V`20DAMAGES`20OR
XANY`20DAMAGES`20WHATSOEVER`20RESULTING`20FROM`20LOSS`20OF`20USE,`20DATA`20OR
V`20PROFITS,
XWHETHER`20IN`20AN`20ACTION`20OF`20CONTRACT,`20NEGLIGENCE`20OR`20OTHER`20TORTIO
VUS`20ACTION,
XARISING`20OUT`20OF`20OR`20IN`20CONNECTION`20WITH`20THE`20USE`20OR`20PERFORMANC
VE`20OF`20THIS
XSOFTWARE.
X
X******************************************************************/
X
X/*`20
X`20*`20This`20is`20an`20adaptation`20of`20the`20Mazewar`20program`20built`20at
V`20Xerox`20PARC`20in
X`20*`20Mesa`20for`20Altos`20by`20Jim`20Guyton`20and`20others`20in`20the`20late
V`201970s`20and`20beyond.
X`20*`20Unlike`20other`20programs`20that`20have`20appeared`20from`20time`20to
V`20time,`20this
X`20*`20one`20attempts`20to`20remain`20faithful`20to`20the`20original`20spirit
V`20of`20the`20game,
X`20*`20with`20no`20fancy`20additions`20(like`20seeing`20your`20opponents`20or
V`20teleport
X`20*`20traps).`20I`20hope`20you`20enjoy`20it.
X`20*/
X
X/*
X`20*`20vms`20port`207/93`20`20scott`20snyder`20<snyder@fnald0.fnal.gov>
X`20*`20$Log:`09mazewar.c,v`20$
X`20*`20Revision`201.13`20`2088/08/25`20`2009:57:53`20`20kent
X`20*`20Copyright.
X`20*`20
X`20*`20Revision`201.12`20`2088/02/11`20`2018:00:39`20`20kent
X`20*`20Changes`20so`20the`20value`20of`20M.theSocket`20doesn't`20change`20(thi
Vs`20makes`20the
X`20*`20window`20system`20code`20simpler).
X`20*`20
X`20*`20Revision`201.11`20`2088/02/11`20`2017:52:41`20`20kent
X`20*`20Move`20some`20code`20out`20of`20the`20play`20loop`20so`20it`20can`20be
V`20called`20by`20an`20"external"`20
X`20*`20play`20loop`20(such`20as`20is`20needed`20for`20the`20X11`20toolkit).
X`20*`20
X`20*`20Revision`201.10`20`2087/03/31`20`2015:47:34`20`20kent
X`20*`20Handle`20duplicated`20RAT_NEW`20packets`20while`20joining`20the`20game.
V`20If`20the`20
X`20*`20guy`20is`20already`20in`20the`20game,`20just`20send`20him`20a`20status
V`20packet;`20previously,
X`20*`20he'd`20get`20added`20to`20the`20game`20again!
X`20*`20
X`20*`20Revision`201.9`20`2087/03/31`20`2014:37:37`20`20kent
X`20*`20Portability`20considerations,`20especially`20byteswapping`20to/from`20t
Vhe`20net.
X`20*`20
X`20*`20Revision`201.8`20`2086/12/04`20`2017:44:53`20`20kent
X`20*`20Notify`20user`20also`20if`20shot;`20make`20sure`20non-dukes`20get`20not
Vified`20on`20game`20joins.
X`20*`20
X`20*`20Revision`201.7`20`2086/12/03`20`2018:13:10`20`20kent
X`20*`20Cleaned`20up`20the`20shot`20handling`20code`20a`20bit.`20Was`20waiting
V`20two`20seconds
X`20*`20instead`20of`20one,`20and`20would`20only`20handle`20one`20shot`20off
V`20the`20queue
X`20*`20every`20time`20around`20the`20loop,`20instead`20of`20all`20applicable.
X`20*`20
X`20*`20Also`20cleaned`20up`20a`20race`20in`20the`20port`20moving`20code`20for
V`20when`20the`20mover`20and
X`20*`20the`20quitter`20were`20on`20the`20same`20machine.
X`20*`20
X`20*`20Revision`201.6`20`2086/12/03`20`2013:31:10`20`20kent
X`20*`20
X`20*`20
X`20*`20Revision`201.5`20`2086/12/03`20`2010:15:03`20`20kent
X`20*`20Only`20send`20location`20when`20moving,`20not`20every`20time`20screen
V`20needs`20updating.
X`20*`20
X`20*`20Revision`201.4`20`2086/12/03`20`2010:00:19`20`20kent
X`20*`20Changes`20to`20allow`20multiple`20players`20per`20machine.
X`20*`20
X`20*`20Revision`201.3`20`2086/12/01`20`2023:44:42`20`20kent
X`20*`20Housecleaning`20and`20documentation`20pass.
X`20*`20
X`20*`20Revision`201.2`20`2086/12/01`20`2014:47:04`20`20kent
X`20*`20Changes`20for`20a`20realistic`20implementation`20of`20shooting.
X`20*`20
X`20*`20Revision`201.1`20`2086/11/26`20`2016:57:53`20`20kent
X`20*`20Initial`20revision
X`20*`20
X`20*/
X
X#ifndef`09lint
Xstatic`20char`20rcs_ident`5B`5D`20=`20"$Header:`20mazewar.c,v`201.13`2088/08/2
V5`2009:57:53`20kent`20Exp`20$";
X#endif
X
X#include`20<sys/types.h>
X#include`20<sys/socket.h>
X#include`20<sys/time.h>
X
X#include`20<netinet/in.h>
X
X#include`20<signal.h>
X#include`20<stdio.h>
X#ifdef`20VMS
X#include`20<string.h>
X#else
X#include`20<strings.h>
X#endif
X
X#include`20"mazewar.h"
X
Xstatic`20int`09`09i1`20=`200;`09`09/*`20random`20number`20hackery`20*/
Xstatic`20int`09`09i2`20=`2024;
X
Xstatic`20Boolean`09`09updateView;`09/*`20true`20if`20update`20needed`20*/
Xstatic`20Boolean`09`09sendLocation;`09/*`20true`20if`20must`20send`20out`20loc
Vation`20*/
X
Xstatic`20MazeTypePtr`09mp`20=`20M.maze;`09/*`20easy`20access`20to`20Maze`20*/
X
Xstatic`20RatHealth`09ratHealth;`09/*`20keep`20track`20of`20other`20players`20*
V/
X
Xstatic`20ratDoctor`20();
X
Xmain(argc,`20argv)
Xchar`20**argv;
X`7B
X`09int`09quit();
X
X`09signal(SIGHUP,`20quit);
X`09signal(SIGINT,`20quit);
X`09signal(SIGTERM,`20quit);
X`09MazeInit(argc,`20argv);
X`09play();
X`7D
X
Xplay()
X`7B
X`09MWEvent`09`09event;
X`09RatPacket`09incoming;
X`09Boolean`09`09KBEventPending();
X
X`09event.eventDetail`20=`20`26incoming;
X
X`09while`20(1)`20`7B
X`09`09NextEvent(`26event);
X`09`09if`20(!M.peeking)
X`09`09`09switch(event.eventType)`20`7B
X`09`09`09case`20EVENT_A:
X`09`09`09`09aboutFace();
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_S:
X`09`09`09`09leftTurn();
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_D:
X`09`09`09`09forward();
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_F:
X`09`09`09`09rightTurn();
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_BAR:
X`09`09`09`09backward();
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_I:
X`09`09`09`09makeInvincible(TRUE);
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_K:
X`09`09`09`09makeInvincible(FALSE);
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_O:
X`09`09`09`09makeOmniscient(TRUE);
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_L:
X`09`09`09`09makeOmniscient(FALSE);
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_LEFT_D:
X`09`09`09`09peekLeft();
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_MIDDLE_D:
X`09`09`09`09shoot();
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_RIGHT_D:
X`09`09`09`09peekRight();
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_NETWORK:
X`09`09`09`09readRats(`26event);
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_INT:
X`09`09`09`09quit();
X`09`09`09`09break;
X
X`09`09`09`7D
X`09`09else
X`09`09`09switch`20(event.eventType)`20`7B
X`09`09`09case`20EVENT_RIGHT_U:
X`09`09`09case`20EVENT_LEFT_U:
X`09`09`09`09peekStop();
X`09`09`09`09break;
X
X`09`09`09case`20EVENT_NETWORK:
X`09`09`09`09readRats(`26event);
X`09`09`09`09break;
X`09`09`09`7D
X`09`09`09
X`09`09ratDoctor();`09`09/*`20clean`20house`20*/
X
X`09`09DoRatKillQ();
X`09`09
X`09`09DoViewUpdate();
X`09`09
X`09`09SendLocation();
X`09`7D
X`7D
X
Xstatic`09Direction`09_aboutFace`5BNDIRECTION`5D`20=`7BSOUTH,`20NORTH,`20WEST,
V`20EAST`7D;
Xstatic`09Direction`09_leftTurn`5BNDIRECTION`5D`20=`09`7BWEST,`20EAST,`20NORTH,
V`20SOUTH`7D;
Xstatic`09Direction`09_rightTurn`5BNDIRECTION`5D`20=`7BEAST,`20WEST,`20SOUTH,
V`20NORTH`7D;
X
XaboutFace()
X`7B
X`09M.dir`20=`20_aboutFace`5BM.dir`5D;
X`09updateView`20=`20TRUE;
X`09sendLocation`20=`20TRUE;
X`7D
X
XleftTurn()
X`7B
X`09M.dir`20=`20_leftTurn`5BM.dir`5D;
X`09updateView`20=`20TRUE;
X`09sendLocation`20=`20TRUE;
X`7D
X
XrightTurn()
X`7B
X`09M.dir`20=`20_rightTurn`5BM.dir`5D;
X`09updateView`20=`20TRUE;
X`09sendLocation`20=`20TRUE;
X`7D
X
X/*`20remember`20...`20"North"`20is`20to`20the`20right`20...`20positive`20X`20m
Votion`20*/
X
Xforward()
X`7B
X`09register`20int`09tx`20=`20M.xloc;
X`09register`20int`09ty`20=`20M.yloc;
X
X`09switch(M.dir)`20`7B
X`09case`20NORTH:`09if`20(!mp`5Btx+1`5D.y`5Bty`5D)`09tx++;`20break;
X`09case`20SOUTH:`09if`20(!mp`5Btx-1`5D.y`5Bty`5D)`09tx--;`20break;
X`09case`20EAST:`09if`20(!mp`5Btx`5D.y`5Bty+1`5D)`09ty++;`20break;
X`09case`20WEST:`09if`20(!mp`5Btx`5D.y`5Bty-1`5D)`09ty--;`20break;
X`09default:
X`09`09MWError("bad`20direction`20in`20Forward");
X`09`7D
X`09if`20((M.xloc`20!=`20tx)`20`7C`7C`20(M.yloc`20!=`20ty))`20`7B
X`09`09M.xloc`20=`20tx;`20M.yloc`20=`20ty;
X`09`09updateView`20=`20TRUE;
X`09`09sendLocation`20=`20TRUE;
X`09`7D
X`7D
X
Xbackward()
X`7B
X`09register`20int`09tx`20=`20M.xloc;
X`09register`20int`09ty`20=`20M.yloc;
X
X`09switch(M.dir)`20`7B
X`09case`20NORTH:`09if`20(!mp`5Btx-1`5D.y`5Bty`5D)`09tx--;`20break;
X`09case`20SOUTH:`09if`20(!mp`5Btx+1`5D.y`5Bty`5D)`09tx++;`20break;
X`09case`20EAST:`09if`20(!mp`5Btx`5D.y`5Bty-1`5D)`09ty--;`20break;
X`09case`20WEST:`09if`20(!mp`5Btx`5D.y`5Bty+1`5D)`09ty++;`20break;
X`09default:
X`09`09MWError("bad`20direction`20in`20Backward");
X`09`7D
X`09if`20((M.xloc`20!=`20tx)`20`7C`7C`20(M.yloc`20!=`20ty))`20`7B
X`09`09M.xloc`20=`20tx;`20M.yloc`20=`20ty;
X`09`09updateView`20=`20TRUE;
X`09`09sendLocation`20=`20TRUE;
X`09`7D
X`7D
X
XmakeInvincible(neverDie)
XBoolean`20neverDie;
X`7B
X`09M.invincible`20=`20neverDie;
X`09ShowPosition(M.xloc,`20M.yloc,`20M.invincible,`20M.dir);
X`7D
X
XmakeOmniscient(allSeeing)
XBoolean`20allSeeing;
X`7B
X`09M.omniscient`20=`20allSeeing;
X`09ShowAllPositions();
X`7D
X
XpeekLeft()
X`7B
X`09M.xPeek`20=`20M.xloc;
X`09M.yPeek`20=`20M.yloc;
X`09M.dirPeek`20=`20M.dir;
X
X`09switch(M.dir)`20`7B
X`09case`20NORTH:`09if`20(!mp`5BM.xloc+1`5D.y`5BM.yloc`5D)`20`7B
X`09`09`09`09M.xPeek`20=`20M.xloc`20+`201;
X`09`09`09`09M.dirPeek`20=`20WEST;
X`09`09`09`7D
X`09`09`09break;
X
X`09case`20SOUTH:`09if`20(!mp`5BM.xloc-1`5D.y`5BM.yloc`5D)`20`7B
X`09`09`09`09M.xPeek`20=`20M.xloc`20-`201;
X`09`09`09`09M.dirPeek`20=`20EAST;
X`09`09`09`7D
X`09`09`09break;
X
X`09case`20EAST:`09if`20(!mp`5BM.xloc`5D.y`5BM.yloc+1`5D)`20`7B
X`09`09`09`09M.yPeek`20=`20M.yloc`20+`201;
X`09`09`09`09M.dirPeek`20=`20NORTH;
X`09`09`09`7D
X`09`09`09break;
X
X`09case`20WEST:`09if`20(!mp`5BM.xloc`5D.y`5BM.yloc-1`5D)`20`7B
X`09`09`09`09M.yPeek`20=`20M.yloc`20-`201;
X`09`09`09`09M.dirPeek`20=`20SOUTH;
X`09`09`09`7D
X`09`09`09break;
X
X`09default:
X`09`09`09MWError("bad`20direction`20in`20PeekLeft");
X`09`7D
X
X`09/*`20if`20any`20change,`20display`20the`20new`20view`20without`20moving!
V`20*/
X
X`09if`20((M.xPeek`20!=`20M.xloc)`20`7C`7C`20(M.yPeek`20!=`20M.yloc))`20`7B
X`09`09M.peeking`20=`20TRUE;
X`09`09updateView`20=`20TRUE;
X`09`7D
X`7D
X
XpeekRight()
X`7B
X`09M.xPeek`20=`20M.xloc;
X`09M.yPeek`20=`20M.yloc;
X`09M.dirPeek`20=`20M.dir;
X
X`09switch(M.dir)`20`7B
X`09case`20NORTH:`09if`20(!mp`5BM.xloc+1`5D.y`5BM.yloc`5D)`20`7B
X`09`09`09`09M.xPeek`20=`20M.xloc`20+`201;
X`09`09`09`09M.dirPeek`20=`20EAST;
X`09`09`09`7D
X`09`09`09break;
X
X`09case`20SOUTH:`09if`20(!mp`5BM.xloc-1`5D.y`5BM.yloc`5D)`20`7B
X`09`09`09`09M.xPeek`20=`20M.xloc`20-`201;
X`09`09`09`09M.dirPeek`20=`20WEST;
X`09`09`09`7D
X`09`09`09break;
X
X`09case`20EAST:`09if`20(!mp`5BM.xloc`5D.y`5BM.yloc+1`5D)`20`7B
X`09`09`09`09M.yPeek`20=`20M.yloc`20+`201;
X`09`09`09`09M.dirPeek`20=`20SOUTH;
X`09`09`09`7D
X`09`09`09break;
X
X`09case`20WEST:`09if`20(!mp`5BM.xloc`5D.y`5BM.yloc-1`5D)`20`7B
X`09`09`09`09M.yPeek`20=`20M.yloc`20-`201;
X`09`09`09`09M.dirPeek`20=`20NORTH;
X`09`09`09`7D
X`09`09`09break;
X
X`09default:
X`09`09`09MWError("bad`20direction`20in`20PeekRight");
X`09`7D
X
X`09/*`20if`20any`20change,`20display`20the`20new`20view`20without`20moving!
V`20*/
X
X`09if`20((M.xPeek`20!=`20M.xloc)`20`7C`7C`20(M.yPeek`20!=`20M.yloc))`20`7B
X`09`09M.peeking`20=`20TRUE;
X`09`09updateView`20=`20TRUE;
X`09`7D
X`7D
X
XpeekStop()
X`7B
X`09M.peeking`20=`20FALSE;
X`09updateView`20=`20TRUE;
X`7D
X
XDoViewUpdate()
X`7B
X`09if`20(updateView)`20`7B`09/*`20paint`20the`20screen`20*/
X`09`09ShowPosition(M.xloc,`20M.yloc,`20M.invincible,`20M.dir);
X`09`09if`20(M.peeking)
X`09`09`09ShowView(M.xPeek,`20M.yPeek,`20M.dirPeek);
X`09`09else
X`09`09`09ShowView(M.xloc,`20M.yloc,`20M.dir);
X`09`09updateView`20=`20FALSE;
X`09`7D
X`7D
X
Xshoot()
X`7B
X`09M.score--;
X`09M.ratcb.rats`5BM.myRatId`5D.score--;
X`09UpdateScoreCard(M.myRatId);
X`09sendKill();
X`7D
X
X/*`20
X`20*`20add`20the`20shot`20to`20the`20shot`20queue.`20It'll`20be`20processed
V`20later.
X`20*/
X
XholdBreath(ratKill)
XRatKill`09ratKill;
X`7B
X`09RatKillQ_t`09rkp;
X`09struct`20timeval`09now;
X`09
X`09DeadRatCursor();
X`09gettimeofday(`26now,`20NULL);
X
X`09if`20(RatKillQ`20==`20NULL)`20`7B
X`09`09RatKillQ`20=`20(RatKillQ_t)`20malloc(sizeof(AqRatKillQ));
X`09`09rkp`20=`20RatKillQ;
X`09`7D`20else`20`7B
X`09`09for`20(rkp`20=`20RatKillQ;`20rkp->nextOne`20!=`20NULL;`20rkp`20=`20rkp->
VnextOne)
X`09`09`09;
X`09`09rkp->nextOne`20=`20(RatKillQ_t)`20malloc(sizeof(AqRatKillQ));
X`09`09rkp`20=`20rkp->nextOne;
X`09`7D
X
X`09bcopy((char`20*)ratKill,`20(char`20*)`26rkp->thisOne,`20sizeof(AqRatKill));
V
X`09rkp->nextOne`20=`20NULL;
X`09rkp->shotHits`20=`20now;
X`09rkp->shotHits.tv_sec++;
X`7D
X
X/*`20
X`20*`20finally`20see`20if`20the`20shot`20hit`20home.
X`20*/
X
XhandleKill(tx,`20ty,`20td,`20ratId)
XLoc`09tx,`20ty;
XDirection`20td;
XRatId`09ratId;
X`7B
X`09while`20(!M.maze`5Btx`5D.y`5Bty`5D)`20`7B
X`09`09switch`20(td)`20`7B
X`09`09case`20NORTH:`09tx++;`20break;
X`09`09case`20SOUTH:`09tx--;`20break;
X`09`09case`20EAST:`09ty++;`20break;
X`09`09case`20WEST:`09ty--;`20break;
X`09`09`7D
X`09`09if`20((M.xloc`20==`20tx)`20`26`26`20(M.yloc`20==`20ty))`20`7B`09/*`20Oh
V`20oh...`20*/
X`09`09`09sendDead(ratId);
X`09`09`09NewPosition();`09/*`20avoid`20multiple`20hits`20*/
X`09`09`09FlashScreen();
X`09`09`09M.score`20-=`205;`09/*`20minus`205`20points`20for`20getting`20killed
V`20*/
X`09`09`09M.ratcb.rats`5BM.myRatId`5D.score`20=`20M.score;
X`09`09`09UpdateScoreCard(M.myRatId);
X`09`09`09NotifyPlayer();
X`09`09`09updateView`20=`20TRUE;
X`09`09`09sendLocation`20=`20TRUE;
X`09`09`7D
X`09`7D
X`09RatCursor();
X`7D
X
X/*
X`20*`20Process`20the`20pending`20shots,`20if`20any.
X`20*/
X
XDoRatKillQ()
X`7B
X`09struct`20timeval`09now;
X`09RatKillQ_t`09rkp`20=`20RatKillQ;
X`09RatKill`09`09ratKill;
X
X`09if`20(RatKillQ`20!=`20NULL)`20`7B
X`09`09gettimeofday(`26now,`20NULL);
X`09`09while`20(rkp`20!=`20NULL)`20`7B
X`09`09`09if`20(now.tv_sec`20>=`20rkp->shotHits.tv_sec)`20`7B
X`09`09`09`09if`20(now.tv_usec`20>=
X`09`09`09`09`20`20`20`20rkp->shotHits.tv_usec)`20`7B
X`09`09`09`09`09ratKill`20=`20`26RatKillQ->thisOne;
X`09`09`09`09`09handleKill(ratKill->xLoc,
X`09`09`09`09`09`09`20`20`20ratKill->yLoc,
X`09`09`09`09`09`09`20`20`20ratKill->dir,
X`09`09`09`09`09`09`20`20`20ratKill->ratId);
X`09`09`09`09`09RatKillQ`20=`20RatKillQ->nextOne;
X`09`09`09`09`09free((char`20*)`20rkp);
X`09`09`09`09`09rkp`20=`20RatKillQ;
X`09`09`09`09`7D`20else
X`09`09`09`09`09break;
X`09`09`09`7D`20else
X`09`09`09`09break;
X`09`09`7D
X`09`09if`20(RatKillQ`20==`20NULL)
X`09`09`09RatCursor();
X`09`7D
X`7D
X`09`09
X/*`20
X`20*`20Convert`20the`20contents`20of`20a`20packet`20to`20network`20order`20bef
Vore`20sending.
X`20*/
X
XConvertOutgoing(p)
XRatPacket`20*p;
X`7B
X`09char`09`09buf`5B64`5D;
X`09RatId`09`09ratId;
X`09RatLocation`09ratLoc;
X`09RatKill`09`09ratKill;
X`09RatDead`09`09ratDead;
X`09RatStatus`09ratStatus;
X`09RatNew`09`09ratNew;
X`09RatGone`09`09ratGone;
X`09RatQuery`09ratQuery;
X`09RatAlive`09ratAlive;
X`09RatMove`09`09ratMove;
X
X`09switch(p->type)`20`7B
X`09case`20RAT_LOCATION:
X`09`09ratLoc`20=`20(RatLocation)`20`26p->body;
X`09`09ratLoc->ratId`20=`20htonl(ratLoc->ratId);
X`09`09ratLoc->xLoc`20=`20`20htons(ratLoc->xLoc);
X`09`09ratLoc->yLoc`20=`20`20htons(ratLoc->yLoc);
X`09`09ratLoc->dir`20=`20`20`20htons(ratLoc->dir);
X`09`09ratLoc->score`20=`20htonl(ratLoc->score);
X`09`09break;
X
X`09case`20RAT_KILL:
X`09`09ratKill`20=`20(RatKill)`20`26p->body;
X`09`09ratKill->ratId`20=`20htonl(ratKill->ratId);
X`09`09ratKill->xLoc`20`20=`20htons(ratKill->xLoc);
X`09`09ratKill->yLoc`20`20=`20htons(ratKill->yLoc);
X`09`09ratKill->dir`20`20`20=`20htons(ratKill->dir);
X`09`09break;
X
X`09case`20RAT_DEAD:
X`09`09ratDead`20=`20(RatDead)`20`26p->body;
X`09`09ratDead->ratId`20=`20htonl(ratDead->ratId);
X`09`09ratDead->killedBy`20=`20htonl(ratDead->killedBy);
X`09`09break;
X
X`09case`20RAT_STATUS:
X`09`09ratStatus`20=`20(RatStatus)`20`26p->body;
X`09`09ratStatus->dukeRat`20=`20htonl(ratStatus->dukeRat);
X`09`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)`20`7B
X`09`09`09RatInfo`09ratInfo;
X
X`09`09`09ratInfo`20=`20`26ratStatus->rats`5BratId`5D;
X`09`09`09ratInfo->playing`20=`20htons(ratInfo->playing);
X`09`09`09ratInfo->xLoc`20=`20htons(ratInfo->xLoc);
X`09`09`09ratInfo->yLoc`20=`20htons(ratInfo->yLoc);
X`09`09`09ratInfo->dir`20=`20htons(ratInfo->dir);
X`09`09`09ratInfo->score`20=`20htonl(ratInfo->score);
X`09`09`09ratInfo->addr.sin_family`20=
X`09`09`09`09ntohs(ratInfo->addr.sin_family);
X`09`09`09/*`20don't`20touch`20address`20or`20name`20*/
X`09`09`7D
X`09`09break;
X
X`09case`20RAT_NEW:
X`09`09ratNew`20=`20(RatNew)`20`26p->body;
X`09`09ratNew->pass`20=`20htons(ratNew->pass);
X`09`09ratNew->xLoc`20=`20htons(ratNew->xLoc);
X`09`09ratNew->yLoc`20=`20htons(ratNew->yLoc);
X`09`09ratNew->dir`20`20=`20htons(ratNew->dir);
X`09`09ratNew->addr.sin_family`20=
X`09`09`09htons(ratNew->addr.sin_family);
X`09`09/*`20don't`20touch`20address`20or`20name`20*/
X`09`09break;
X
X`09case`20RAT_GOING:
X`09`09ratGone`20=`20(RatGone)`20`26p->body;
X`09`09ratGone->ratId`20=`20htonl(ratGone->ratId);
X`09`09break;
X
X`09case`20RAT_QUERY:
X`09`09ratQuery`20=`20(RatQuery)`20`26p->body;
X`09`09ratQuery->ratId`20=`20htonl(ratQuery->ratId);
X`09`09break;
X
X`09case`20RAT_ALIVE:
X`09`09ratAlive`20=`20(RatAlive)`20`26p->body;
X`09`09ratAlive->ratId`20=`20htonl(ratAlive->ratId);
X`09`09break;
X
X`09case`20RAT_SURVEY:
X`09`09ratNew`20=`20(RatNew)`20`26p->body;
X`09`09ratNew->pass`20=`20htons(ratNew->pass);
X`09`09ratNew->xLoc`20=`20htons(ratNew->xLoc);
X`09`09ratNew->yLoc`20=`20htons(ratNew->yLoc);
X`09`09ratNew->dir`20`20=`20htons(ratNew->dir);
X`09`09/*`20don't`20touch`20address`20or`20name`20*/
X`09`09break;
X
X`09case`20RAT_MOVE:
X`09`09ratMove`20=`20(RatMove)`20`26p->body;
X`09`09ratMove->ratId`20=`20htonl(ratMove->ratId);
X`09`09break;
X
X`09default:
X`09`09sprintf(buf,`20"ConvertOutgoing`20bad`20type`20%d`20(%d)",
X`09`09`09p->type,`20htons(p->type));
X`09`09MWError(buf);
X`09`7D
X`09p->type`20=`20htonl(p->type);
X`7D
X
X/*`20
X`20*`20Convert`20the`20contents`20of`20a`20packet`20to`20host`20order`20after
V`20ConvertIncoming.
X`20*/
X
XConvertIncoming(p)
XRatPacket`20*p;
X`7B
X`09char`09`09buf`5B64`5D;
X`09RatId`09`09ratId;
X`09RatLocation`09ratLoc;
X`09RatKill`09`09ratKill;
X`09RatDead`09`09ratDead;
X`09RatStatus`09ratStatus;
X`09RatNew`09`09ratNew;
X`09RatGone`09`09ratGone;
X`09RatQuery`09ratQuery;
X`09RatAlive`09ratAlive;
X`09RatMove`09`09ratMove;
X
X`09p->type`20=`20ntohl(p->type);
X`09switch(p->type)`20`7B
X`09case`20RAT_LOCATION:
X`09`09ratLoc`20=`20(RatLocation)`20`26p->body;
X`09`09ratLoc->ratId`20=`20ntohl(ratLoc->ratId);
X`09`09ratLoc->xLoc`20=`20`20ntohs(ratLoc->xLoc);
X`09`09ratLoc->yLoc`20=`20`20ntohs(ratLoc->yLoc);
X`09`09ratLoc->dir`20=`20`20`20ntohs(ratLoc->dir);
X`09`09ratLoc->score`20=`20ntohl(ratLoc->score);
X`09`09break;
X
X`09case`20RAT_KILL:
X`09`09ratKill`20=`20(RatKill)`20`26p->body;
X`09`09ratKill->ratId`20=`20ntohl(ratKill->ratId);
X`09`09ratKill->xLoc`20`20=`20ntohs(ratKill->xLoc);
X`09`09ratKill->yLoc`20`20=`20ntohs(ratKill->yLoc);
X`09`09ratKill->dir`20`20`20=`20ntohs(ratKill->dir);
X`09`09break;
X
X`09case`20RAT_DEAD:
X`09`09ratDead`20=`20(RatDead)`20`26p->body;
X`09`09ratDead->ratId`20=`20ntohl(ratDead->ratId);
X`09`09ratDead->killedBy`20=`20ntohl(ratDead->killedBy);
X`09`09break;
X
X`09case`20RAT_STATUS:
X`09`09ratStatus`20=`20(RatStatus)`20`26p->body;
X`09`09ratStatus->dukeRat`20=`20ntohl(ratStatus->dukeRat);
X`09`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)`20`7B
X`09`09`09RatInfo`09ratInfo;
X
X`09`09`09ratInfo`20=`20`26ratStatus->rats`5BratId`5D;
X`09`09`09ratInfo->playing`20=`20ntohs(ratInfo->playing);
X`09`09`09ratInfo->xLoc`20=`20ntohs(ratInfo->xLoc);
X`09`09`09ratInfo->yLoc`20=`20ntohs(ratInfo->yLoc);
X`09`09`09ratInfo->dir`20=`20ntohs(ratInfo->dir);
X`09`09`09ratInfo->score`20=`20ntohl(ratInfo->score);
X`09`09`09ratInfo->addr.sin_family`20=
X`09`09`09`09ntohs(ratInfo->addr.sin_family);
X`09`09`09/*`20don't`20touch`20address`20or`20name`20*/
X`09`09`7D
X`09`09break;
X
X`09case`20RAT_NEW:
X`09`09ratNew`20=`20(RatNew)`20`26p->body;
X`09`09ratNew->pass`20=`20ntohs(ratNew->pass);
X`09`09ratNew->xLoc`20=`20ntohs(ratNew->xLoc);
X`09`09ratNew->yLoc`20=`20ntohs(ratNew->yLoc);
X`09`09ratNew->dir`20`20=`20ntohs(ratNew->dir);
X`09`09ratNew->addr.sin_family`20=
X`09`09`09ntohs(ratNew->addr.sin_family);
X`09`09/*`20don't`20touch`20address`20or`20name`20*/
X`09`09break;
X
X`09case`20RAT_GOING:
X`09`09ratGone`20=`20(RatGone)`20`26p->body;
X`09`09ratGone->ratId`20=`20ntohl(ratGone->ratId);
X`09`09break;
X
X`09case`20RAT_QUERY:
X`09`09ratQuery`20=`20(RatQuery)`20`26p->body;
X`09`09ratQuery->ratId`20=`20ntohl(ratQuery->ratId);
X`09`09break;
X
X`09case`20RAT_ALIVE:
X`09`09ratAlive`20=`20(RatAlive)`20`26p->body;
X`09`09ratAlive->ratId`20=`20ntohl(ratAlive->ratId);
X`09`09break;
X
X`09case`20RAT_SURVEY:
X`09`09ratNew`20=`20(RatNew)`20`26p->body;
X`09`09ratNew->pass`20=`20ntohs(ratNew->pass);
X`09`09ratNew->xLoc`20=`20ntohs(ratNew->xLoc);
X`09`09ratNew->yLoc`20=`20ntohs(ratNew->yLoc);
X`09`09ratNew->dir`20`20=`20ntohs(ratNew->dir);
X`09`09/*`20don't`20touch`20address`20or`20name`20*/
X`09`09break;
X
X`09case`20RAT_MOVE:
X`09`09ratMove`20=`20(RatMove)`20`26p->body;
X`09`09ratMove->ratId`20=`20ntohl(ratMove->ratId);
X`09`09break;
X
X`09default:
X`09`09sprintf(buf,`20"ConvertIncoming`20bad`20type`20%d`20(%d)",
X`09`09`09p->type,`20ntohs(p->type));
X`09`09MWError(buf);
X`09`7D
X`7D
X
X#ifdef`09PACKET_TRACE
Xstatic`20char`09*packTypes`5B`5D`20=`20`7B
X`09"RAT_LOCATION",
X`09"RAT_KILL",
X`09"RAT_DEAD",
X`09"RAT_STATUS",
X`09"RAT_NEW",
X`09"RAT_GOING",
X`09"RAT_QUERY",
X`09"RAT_ALIVE",
X`09"RAT_SURVEY",
X`09"RAT_MOVE",
X`090
X`7D;
X#endif`09PACKET_TRACE
X
XreadRats(evp)
XMWEvent`20*evp;
X`7B
X`09register`20RatLocation`09ratLoc;
X`09register`20RatLook`09ratLook;
X`09register`20RatAlive`09ratAlive;
X`09RatPacket`09*pack`20=`20evp->eventDetail;
X`09RatInfo`09`09ratInfo;
X`09Boolean`09`09oldVisible;
X`09RatId`09`09ratId;
X`09RatStatus`09status;
X`09RatNew`09`09ratNew;
X`09RatGone`09`09ratGone;
X`09RatKill`09`09ratKill;
X`09RatDead`09`09ratDead;
X`09RatQuery`09ratQuery;
X`09RatMove`09`09ratMove;
X`09Sockaddr`09nullAddr;
X`09char`09`09buf`5B32`5D;
X`09int`09`09newSocket;
X
X#ifdef`09PACKET_TRACE
X`09printf("received`20%s`20(%d)`5Cn",
X`09`09packTypes`5Bpack->type`20-`201`5D,`20pack->type);
X#endif`09PACKET_TRACE
X
X`09switch(pack->type)`20`7B
X`09case`20RAT_LOCATION:`09`09/*`20someone`20moved`20*/
X`09`09ratLoc`20=`20(RatLocation)`20`26pack->body;
X`09`09ratLook`20=`20`26R2d2`5BratLoc->ratId`5D;
X`09`09if`20((oldVisible`20=`20ratLook->visible)`20==`20TRUE)
X`09`09`09XORToken(ratLoc->ratId);
X`09`09ratInfo`20=`20`26M.ratcb.rats`5BratLoc->ratId`5D;
X`09`09ratInfo->xLoc`20=`20ratLoc->xLoc;
X`09`09ratInfo->yLoc`20=`20ratLoc->yLoc;
X`09`09ratInfo->dir`20`20=`20ratLoc->dir;
X`09`09DisplayOthersPosition(ratLoc->ratId,`20ratLoc->xLoc,
X`09`09`09`09`20`20`20`20`20`20ratLoc->yLoc,`20ratLoc->dir);
X`09`09TokenVisible(ratLoc->ratId);
X`09`09if`20(ratLook->visible`20==`20TRUE)
X`09`09`09XORToken(ratLoc->ratId);
X`09`09if`20((oldVisible`20!=`20ratLook->visible)`20`7C`7C
X`09`09`20`20`20`20(ratInfo->score`20!=`20ratLoc->score))`20`7B
X`09`09`09ratInfo->score`20=`20ratLoc->score;
X`09`09`09UpdateScoreCard(ratLoc->ratId);
X`09`09`7D
X`09`09ratHealth`5BratLoc->ratId`5D.rcvd`20=`20TRUE;
X`09`09break;
X
X`09case`20RAT_KILL:`09`09`09/*`20someone`20shot`20at`20me`20*/
X`09`09if`20(!M.invincible)`20`7B
X`09`09`09ratKill`20=`20(RatKill)`20`26pack->body;
X`09`09`09holdBreath(ratKill);
X`09`09`7D
X`09`09break;
X
X`09case`20RAT_DEAD:`09`09`09/*`20I`20hit`20someone`20*/
X`09`09ratDead`20=`20(RatDead)`20`26pack->body;
X`09`09if`20(ratDead->killedBy`20==`20M.myRatId)`20`7B
X`09`09`09FlashTop();`09/*`20got`20him!`20*/
X`09`09`09M.score`20+=`2010;`09/*`2010`20points`20for`20a`20kill`20*/
X`09`09`09M.score`20+=`201;`09/*`20make`20up`20for`20shot`20cost`20*/
X`09`09`09M.ratcb.rats`5BM.myRatId`5D.score`20=`20M.score;
X`09`09`09UpdateScoreCard(M.myRatId);
X`09`09`09sendLocToAll();
X`09`09`7D
X`09`09break;
X
X`09case`20RAT_STATUS:`09`09/*`20new`20info`20about`20everyone`20*/
X`09`09status`20=`20(RatStatus)`20`26pack->body;
X`09`09if`20(bcmp(`26status->rats`5BM.myRatId`5D.addr,`20`26M.myAddr,
X`09`09`09`20`20sizeof(M.myAddr))`20!=`200)
X`09`09`09break;`09`09/*`20not`20for`20me,`20from`20another`20game`20*/
X`09`09`09`09`09/*`20perhaps`20left`20over`20from`20findDuke()`20*/
X
X`09`09/*`20Have`20a`20new`20table,`20turn`20off`20any`20visible`20opponents
V`20*/
X
X`09`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)
X`09`09`09if`20(R2d2`5BratId`5D.visible`20==`20TRUE)
X`09`09`09`09XORToken(ratId);
X`09`09bcopy((char`20*)status,`20(char`20*)`26M.ratcb,`20sizeof(RatCb));
X`09`09if`20(M.ratcb.dukeRat`20==`20M.myRatId)
X`09`09`09M.duke`20=`20TRUE;
X`09`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)`20`7B
X`09`09`09TokenVisible(ratId);
X`09`09`09if`20(R2d2`5BratId`5D.visible`20==`20TRUE)
X`09`09`09`09XORToken(ratId);
X`09`09`7D
X`09`09NewScoreCard();
X`09`09ratInfo`20=`20`26M.ratcb.rats`5BM.myRatId`5D;
X`09`09if`20((ratInfo->xLoc`20!=`20M.xloc)`20`7C`7C
X`09`09`20`20`20`20(ratInfo->yLoc`20!=`20M.yloc)`20`7C`7C
X`09`09`20`20`20`20(ratInfo->dir`20`20!=`20M.dir))
X`09`09`09sendLocToAll();
X`09`09
X`09`09break;
X
X`09case`20RAT_NEW:`09`09`09/*`20new`20player`20*/
X`09`09ratNew`20=`20(RatNew)`20`26pack->body;
X`09`09if`20(ratNew->pass`20==`20RAT_PASSWORD)`20`7B
X`09`09`09if`20(M.duke)`20`7B
X`09`09`09`09/*`20
X`09`09`09`09`20*`20need`20to`20check`20for`20duplicates`20here;
X`09`09`09`09`20*`20a`20previous`20reply`20might`20have`20been
X`09`09`09`09`20*`20lost.`20Can't`20let`20the`20same`20guy`20in`20the
X`09`09`09`09`20*`20game`20twice.
X`09`09`09`09`20*/
X
X`09`09`09`09register`20RatId`09id;
X
X`09`09`09`09for`20(id`20=`200;`20id`20<`20MAXRATS;`20id++)
X`09`09`09`09`09if`20(M.ratcb.rats`5Bid`5D.playing`20`26`26
X`09`09`09`09`09`20`20`20`20!bcmp(`26M.ratcb.rats`5Bid`5D.addr,
X`09`09`09`09`09`09`20`20`26evp->eventSource,
X`09`09`09`09`09`09`20`20sizeof`20(Sockaddr)))`20`7B
X
X`09`09`09`09`09`09/*`20already`20there`20*/
X`09`09`09`09`09`09sendStatus(evp->eventSource);
X`09`09`09`09`09`09break;
X`09`09`09`09`09`7D
X`09`09`09`09if`20(id`20>=`20MAXRATS)`20`7B`09/*`20fell`20through`20*/
X`09`09`09`09`09allocateNewRat(ratNew);
X`09`09`09`09`09sendAllStatus();
X`09`09`09`09`7D
X`09`09`09`7D`20else
X`09`09`09`09sendStatus(evp->eventSource);
X`09`09`7D
X`09`09break;
X
X`09case`20RAT_GOING:`09`09`20`20`20`20`20`20`20/*`20player`20leaving,`20only
V`20rcvd`20if`20duke`20*/
X`09`09ratGone`20=`20(RatGone)`20`26pack->body;
X`09`09ratLeft(ratGone->ratId);
X`09`09break;
X
X`09case`20RAT_QUERY:`09`09`09/*`20are`20you`20alive?`20*/
X`09`09/*
X`09`09`20*`20register`20their`20net`20address,`20in`20case`20they`20got`20a
X`09`09`20*`20RAT_MOVE,`20moved,`20and`20the`20change`20got`20lost`20somewhere.
V
X`09`09`20*/
X`09`09ratQuery`20=`20(RatQuery)`20`26pack->body;
X`09`09M.ratcb.rats`5BratQuery->ratId`5D.addr`20=`20evp->eventSource;
X
X`09`09sendAlive();
X`09`09break;
X
X`09case`20RAT_ALIVE:`09`09`09/*`20I`20am`20alive`20*/
X`09`09ratAlive`20=`20(RatAlive)`20`26pack->body;
X`09`09ratHealth`5BratAlive->ratId`5D.rcvd`20=`20TRUE;
X`09`09break;
X
X`09case`20RAT_SURVEY:`09`09/*`20who's`20out`20there?`20*/
X`09`09ratNew`20=`20(RatNew)`20`26pack->body;
X`09`09if`20(ratNew->pass`20==`20RAT_PASSWORD)
X`09`09`09sendStatus(evp->eventSource);
X`09`09break;
X
X`09case`20RAT_MOVE:`09`09`09/*`20move`20to`20M.mazePort`20*/
X`09`09ratMove`20=`20(RatMove)`20`26pack->body;
X`09`09if`20(ratMove->ratId`20!=`20M.ratcb.dukeRat)
X`09`09`09MWError("bogus`20RAT_MOVE");
X#ifdef`20VMS
X`09`09socket_close(M.theSocket);
X#else
X`09`09close(M.theSocket);
X#endif
X
X`09`09/*`20
X`09`09`20*`20If`20the`20socket`20being`20closed`20is`20on`20this`20machine,
X`09`09`20*`20leave`20some`20time`20for`20the`20socket`20to`20close`20down`20be
Vfore
X`09`09`20*`20I`20try`20to`20grab`20it.
X`09`09`20*/
X
X`09`09if`20(bcmp((char`20*)`20`26evp->eventSource.sin_addr,
X`09`09`09`20`20(char`20*)`20`26M.myAddr.sin_addr,
X`09`09`09`20`20sizeof(M.myAddr.sin_addr))`20==`200)
X`09`09`09sleep(1);
X
X`09`09/*`20grab`20the`20socket`20*/
X
X`09`09newSocket`20=`20socket(AF_INET,`20SOCK_DGRAM,`200);
X`09`09if`20(newSocket`20<`200)
X`09`09`09MWError("RAT_MOVE`20lost`20socket");
X#ifdef`20VMS
X`09`09M.theSocket`20=`20newSocket;
X#else
X`09`09if`20(dup2(newSocket,`20M.theSocket)`20<`200)
X`09`09`09MWError("RAT_MOVE`20dup2`20failed");
X#endif
X`09`09`7B
X`09`09`20`20int`20opt`20=`201;
X`09`09`20`20if`20(setsockopt(M.theSocket,`20SOL_SOCKET,`20SO_REUSEADDR,
X`09`09`09`09`20`26opt,`20sizeof`20(opt))`20<`200)
X`09`09`20`20`20`20MWError("RAT_MOVE`20can't`20reuse`20addresses");
X`09`09`7D
X`09`09M.myAddr.sin_port`20=`20M.mazePort;
X`09`09nullAddr`20=`20M.myAddr;`09/*`20see`20netInit()`20*/
X`09`09bzero((char`20*)`20`26nullAddr.sin_addr,`20sizeof(nullAddr.sin_addr));
X`09`09if`20(bind(M.theSocket,`20`26nullAddr,`20sizeof(nullAddr))`20<`200)
X`09`09`09MWError("RAT_MOVE`20can't`20bind");
X#ifdef`20VMS
X`09`09arm_net_input`20(M.theSocket);
X#endif
X`09`09M.ratcb.rats`5BM.myRatId`5D.addr`20=`20M.myAddr;
X`09`09sendAllStatus();
X`09`09break;
X
X`09default:
X`09`09sprintf(buf,`20"readRats`20bad`20packet`20type`200x%x",`20pack->type);
X`09`09MWError(buf);
X`09`7D
X`7D
X
X/*`20
X`20*`20In`20order`20to`20reduce`20the`20network`20traffic,`20only`20send`20out
V`20the`20location`20change`20if
X`20*`20there's`20no`20keyboard`20input`20pending.
X`20*/
X
XSendLocation()
X`7B
X`09Boolean`09`09KBEventPending();
X`09if`20(!KBEventPending())
X`09`09if`20(sendLocation)`20`7B
X`09`09`09sendLocToAll();
X`09`09`09sendLocation`20=`20FALSE;
X`09`09`7D
X`7D
X
X/*`20
X`20*`20Let`20everyone`20know`20I've`20moved.
X`20*/
X
XsendLocToAll()
X`7B
X`09RatPacket`09pack;
X`09RatLocation`09ratloc;
X`09RatId`09`09i;
X`09RatInfo`09`09ratInfo`20=`20`26M.ratcb.rats`5BM.myRatId`5D;
X
X`09ratInfo->xLoc`20=`20M.xloc;`09`09/*`20update`20my`20table,`20too`20*/
X`09ratInfo->yLoc`20=`20M.yloc;
X`09ratInfo->dir`20`20=`20M.dir;
X`09ratInfo->score`20=`20M.score;
X
X`09pack.type`20=`20RAT_LOCATION;
X`09ratloc`20=`20(RatLocation)`20`26pack.body;
X`09ratloc->ratId`20=`20M.myRatId;
X`09ratloc->xLoc`20=`20ratInfo->xLoc;
X`09ratloc->yLoc`20=`20ratInfo->yLoc;
X`09ratloc->dir`20=`20ratInfo->dir;
X`09ratloc->score`20=`20ratInfo->score;
X`09ConvertOutgoing(`26pack);
X`09
X`09/*`20
X`09`20*`20Would`20really`20like`20this`20to`20be`20asynchronous,`20so`20play
V`20could
X`09`20*`20continue`20while`20the`20packets`20are`20being`20sent.`20Of`20course
V,`20then,
X`09`20*`20the`20data`20might`20change`20in`20the`20midst`20of`20all`20this...
X`09`20*/
X
X`09for`20(i`20=`200;`20i`20<`20MAXRATS;`20i++)
X`09`09if`20((i`20!=`20M.myRatId)`20`26`26`20(M.ratcb.rats`5Bi`5D.playing))
X`09`09`09if`20(sendto(M.theSocket,`20`26pack,`20sizeof(pack),`200,
X`09`09`09`09`20`20`26M.ratcb.rats`5Bi`5D.addr,`20sizeof(Sockaddr))`20<`200)
X`09`09`09`09MWError("sendLocToAll");
X`7D
X
XsendAllStatus()
X`7B
X`09RatId`09i;
X
X`09for`20(i`20=`200;`20i`20<`20MAXRATS;`20i++)
X`09`09if`20((i`20!=`20M.myRatId)`20`26`26`20(M.ratcb.rats`5Bi`5D.playing))
X`09`09`09sendStatus(M.ratcb.rats`5Bi`5D.addr);
X`7D
X
X/*`20
X`20*`20Send`20the`20entire`20status`20data`20to`20a`20rat.
X`20*/
X
XsendStatus(to)
XSockaddr`20to;
X`7B
X`09RatPacket`09pack;
X
X`09pack.type`20=`20RAT_STATUS;
X`09pack.body`20=`20M.ratcb;
X`09ConvertOutgoing(`26pack);
X`09if`20(sendto(M.theSocket,`20`26pack,`20sizeof(pack),`200,`20`26to,`20sizeof
V(to))`20<`200)
X`09`09MWError("sendStatus");
X`7D
X
X/*`20
X`20*`20Tell`20a`20player`20he's`20being`20shot`20at.
X`20*/
X
XsendKill()
X`7B
X`09RatPacket`09pack;
X`09RatKill`09`09ratKill;
X`09RatId`09`09ixRatId;
X
X`09for`20(ixRatId`20=`200;`20ixRatId`20<`20MAXRATS;`20ixRatId++)`20`7B
X`09`09if`20(ixRatId`20==`20M.myRatId)
X`09`09`09continue;
X`09`09if`20(R2d2`5BixRatId`5D.visible)`20`7B
X`09`09`09pack.type`20=`20RAT_KILL;
X`09`09`09ratKill`20=`20(RatKill)`20`26pack.body;
X`09`09`09ratKill->ratId`20=`20M.myRatId;
X`09`09`09ratKill->xLoc`20=`20M.xloc;
X`09`09`09ratKill->yLoc`20=`20M.yloc;
X`09`09`09ratKill->dir`20`20=`20M.dir;
X`09`09`09ConvertOutgoing(`26pack);
X`09`09`09if`20(sendto(M.theSocket,`20`26pack,`20sizeof(pack),`200,
X`09`09`09`09`20`20`20`26M.ratcb.rats`5BixRatId`5D.addr,
X`09`09`09`09`20`20`20sizeof(M.ratcb.rats`5BixRatId`5D.addr))`20<`200)
X`09`09`09`09MWError("sendKill");
X`09`09`7D
X`09`7D
X`7D
X
X/*`20
X`20*`20Tell`20a`20shooter`20he`20hit`20me.
X`20*/
X
XsendDead(killerRatId)
XRatId`09killerRatId;
X`7B
X`09RatPacket`09pack;
X`09RatDead`09`09ratDead;
X
X`09pack.type`20=`20RAT_DEAD;
X`09ratDead`20=`20(RatDead)`20`26pack.body;
X`09ratDead->ratId`20=`20M.myRatId;
X`09ratDead->killedBy`20=`20killerRatId;
X`09ConvertOutgoing(`26pack);
X`09if`20(sendto(M.theSocket,`20`26pack,`20sizeof(pack),`200,
X`09`09`20`20`26M.ratcb.rats`5BkillerRatId`5D.addr,`20sizeof(Sockaddr))`20<`200
V)
X`09`09MWError("sendDead");
X`7D
X
X/*`20
X`20*`20Tell`20the`20duke`20I'm`20leaving.
X`20*/
X
XsendGoing()
X`7B
X`09RatPacket`09pack;
X`09RatGone`09`09ratGone;
X
X`09pack.type`20=`20RAT_GOING;
X`09ratGone`20=`20(RatGone)`20`26pack.body;
X`09ratGone->ratId`20=`20M.myRatId;
X`09ConvertOutgoing(`26pack);
X`09if`20(sendto(M.theSocket,`20`26pack,`20sizeof(pack),`200,
X`09`09`20`20`26M.ratcb.rats`5BM.ratcb.dukeRat`5D.addr,`20sizeof(Sockaddr))`20<
V`200)
X`09`09MWError("sendGoing");
X`7D
X
X/*`20
X`20*`20Ask`20the`20silent`20types`20if`20they're`20alive.
X`20*/
X
XsendQuery()
X`7B
X`09RatPacket`09pack;
X`09RatId`09`09ratId;
X`09RatQuery`09ratQuery;
X
X`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)
X`09`09if`20(ratHealth`5BratId`5D.send)`20`7B
X`09`09`09pack.type`20=`20RAT_QUERY;
X`09`09`09ratQuery`20=`20(RatQuery)`20`26pack.body;
X`09`09`09ratQuery->ratId`20=`20M.myRatId;
X`09`09`09ratHealth`5BratId`5D.send`20=`20FALSE;
X`09`09`09ConvertOutgoing(`26pack);
X`09`09`09if`20(sendto(M.theSocket,`20`26pack,`20sizeof(pack),`200,
X`09`09`09`09`20`20`26M.ratcb.rats`5BratId`5D.addr,
X`09`09`09`09`20`20sizeof(Sockaddr))`20<`200)
X`09`09`09`09MWError("sendQuery");
X`09`09`7D
X`7D
X
X/*`20
X`20*`20Register`20someone`20as`20alive,`20and`20let`20them`20know`20we`20are,
V`20too.`20
X`20*/
X
XsendAlive()
X`7B
X`09RatPacket`09pack;
X`09RatId`09`09ratId;
X`09RatAlive`09ratAlive;
X
X`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)`20`7B
X`09`09if`20((ratId`20==`20M.myRatId)`20`7C`7C
X`09`09`20`20`20`20!M.ratcb.rats`5BratId`5D.playing)
X`09`09`09continue;
X`09`09pack.type`20=`20RAT_ALIVE;
X`09`09ratAlive`20=`20(RatAlive)`20`26pack.body;
X`09`09ratAlive->ratId`20=`20M.myRatId;
X`09`09ConvertOutgoing(`26pack);
X`09`09if`20(sendto(M.theSocket,`20`26pack,`20sizeof(pack),`200,
X`09`09`20`20`20`20`20`20`26M.ratcb.rats`5BratId`5D.addr,`20sizeof(Sockaddr))
V`20<`200)
X`09`09`09MWError("sendAlive");
X`09`7D
X`7D
X
X/*`20
X`20*`20Let`20a`20new`20player`20in`20the`20game.
X`20*/
X
XallocateNewRat(ratNew)
XRatNew`09ratNew;
X`7B
X`09RatId`09ratId;
X`09RatInfo`09ratInfo;
X
X`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)`20`7B
X`09`09ratInfo`20=`20`26M.ratcb.rats`5BratId`5D;
X`09`09if`20(!ratInfo->playing)`20`7B
X`09`09`09ratInfo->playing`20=`20TRUE;
X`09`09`09ratInfo->xLoc`20=`20ratNew->xLoc;
X`09`09`09ratInfo->yLoc`20=`20ratNew->yLoc;
X`09`09`09ratInfo->dir`20`20=`20ratNew->dir;
X`09`09`09ratInfo->score`20=`200;
X`09`09`09ratInfo->addr`20=`20ratNew->addr;
X`09`09`09strncpy(ratInfo->name,`20ratNew->name,`20NAMESIZE);
X`09`09`09TokenVisible(ratId);
X`09`09`09UpdateScoreCard(ratId);
X`09`09`09if`20(R2d2`5BratId`5D.visible`20==`20TRUE)
X`09`09`09`09XORToken(ratId);
X`09`09`09AddNewPlayer(ratId,`20ratNew->xLoc,`20ratNew->yLoc,
X`09`09`09`09`09ratNew->dir);
X`09`09`09return;
X`09`09`7D
X`09`7D
X`7D
X
X/*`20
X`20*`20I`20wanna`20go`20home!
X`20*/
X
Xquit()
X`7B
X`09RatId`09ratId;
X
X`09if`20(!M.duke)
X`09`09sendGoing();
X`09else`20`7B`09`09`09`09/*`20oh`20oh,`20I'm`20the`20duke`20rat`20*/
X`09`09M.ratcb.rats`5BM.myRatId`5D.playing`20=`20FALSE;
X`09`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)
X`09`09`09if`20(M.ratcb.rats`5BratId`5D.playing)`20`7B
X`09`09`09`09M.ratcb.dukeRat`20=`20ratId;
X`09`09`09`09sendAllStatus();
X`09`09`09`09break;
X`09`09`09`7D
X`09`09moveSomeone(M.myRatId);
X`09`7D
X`09StopWindow();
X`09exit(0);
X`7D
X
X/*`20
X`20*`20Clean`20up`20after`20someone`20who`20has`20left.`20Let`20everyone`20els
Ve`20know,`20too.
X`20*/
X
XratLeft(ratId)
XRatId`09ratId;
X`7B
X`09if`20(R2d2`5BratId`5D.visible`20==`20TRUE)
X`09`09XORToken(ratId);
X`09R2d2`5BratId`5D.visible`20=`20FALSE;
X`09M.ratcb.rats`5BratId`5D.playing`20=`20FALSE;
X`09ExitPlayer(ratId);
X`09UpdateScoreCard(ratId);
X`09sendAllStatus();
X`09moveSomeone(ratId);
X`7D
X
X/*`20
X`20*`20See`20if`20the`20guy`20leaving`20has`20vacated`20the`20reserved`20port.
V`20If`20so,`20try`20to
X`20*`20find`20someone`20else`20on`20that`20machine`20and`20tell`20him`20to`20m
Vove`20there.
X`20*/
X
XmoveSomeone(ratId)
XRatId`09ratId;
X`7B
X`09Sockaddr`09hisAddr;
X`09RatId`09`09newRat;
X`09RatPacket`09pack;
X`09RatMove`09`09ratMove;
X
X`09hisAddr`20=`20M.ratcb.rats`5BratId`5D.addr;
X`09if`20(hisAddr.sin_port`20!=`20M.mazePort)
X`09`09return;
X
X`09for`20(newRat`20=`200;`20newRat`20<`20MAXRATS;`20newRat++)`20`7B
X`09`09if`20(newRat`20==`20ratId)
X`09`09`09continue;
X`09`09if`20(M.ratcb.rats`5BnewRat`5D.playing`20==`20FALSE)
X`09`09`09continue;
X`09`09if`20(!bcmp(`26M.ratcb.rats`5BnewRat`5D.addr.sin_addr,
X`09`09`09`20`20`26hisAddr.sin_addr,`20sizeof(hisAddr.sin_addr)))`20`7B
X`09`09`09pack.type`20=`20RAT_MOVE;
X`09`09`09ratMove`20=`20(RatMove)`20`26pack.body;
X`09`09`09ratMove->ratId`20=`20M.ratcb.dukeRat;
X`09`09`09ConvertOutgoing(`26pack);
X`09`09`09if`20(sendto(M.theSocket,`20`26pack,`20sizeof(pack),`200,
X`09`09`09`09`20`20`26M.ratcb.rats`5BnewRat`5D.addr,
X`09`09`09`09`20`20sizeof(Sockaddr))`20<`200)
X`09`09`09`09MWError("moveSomeone");
X
X`09`09`09/*`20
X`09`09`09`20*`20If`20I'm`20the`20one`20leaving,`20must`20free`20up`20my`20port
V.
X`09`09`09`20*/
X
X`09`09`09if`20(ratId`20==`20M.myRatId)
X#ifdef`20VMS
X`09`09`09`09socket_close(M.theSocket);
X#else
X`09`09`09`09close(M.theSocket);
X#endif
X`09`09`09break;
X`09`09`7D
X`09`7D
X`09`09
X`7D
X
X/*`20
X`20*`20Make`20sure`20nobody`20has`20died`20unnoticed.
X`20*/
X
Xstatic`20Boolean`09`09started`20=`20FALSE;
Xstruct`20timeval`09waitStart;
Xstatic`20Boolean`09`09runDoctor`20=`20TRUE;
X
Xstatic
XratDoctor()
X`7B
X`09RatId`09ratId,`20nextRatId();
X`09struct`20timeval`09now;
X
X`09if`20(!runDoctor)
X`09`09return;
X
X`09if`20(started`20==`20FALSE)`20`7B
X`09`09gettimeofday(`26waitStart,`20NULL);
X`09`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)`20`7B
X`09`09`09ratHealth`5BratId`5D.count`20=`200;
X`09`09`09ratHealth`5BratId`5D.send`20=`20FALSE;
X`09`09`09ratHealth`5BratId`5D.rcvd`20=`20FALSE;
X`09`09`7D
X`09`09started`20=`20TRUE;
X`09`09return;
X`09`7D`20else`20`7B
X`09`09gettimeofday(`26now,`20NULL);
X`09`09if`20((now.tv_sec`20-`20waitStart.tv_sec)`20<`205)
X`09`09`09return;
X`09`09for`20(ratId`20=`200;`20ratId`20<`20MAXRATS;`20ratId++)`20`7B
X`09`09`09if`20((!M.ratcb.rats`5BratId`5D.playing)`20`7C`7C
X`09`09`09`20`20`20`20(ratId`20==`20M.myRatId))
X`09`09`09`09continue;
X`09`09`09if`20(ratHealth`5BratId`5D.rcvd)`20`7B
X`09`09`09`09ratHealth`5BratId`5D.count`20=`200;
X`09`09`09`09ratHealth`5BratId`5D.rcvd`20=`20FALSE;
X`09`09`09`09continue;
X`09`09`09`7D
X`09`09`09if`20(++ratHealth`5BratId`5D.count`20<`205)`20`7B
X`09`09`09`09ratHealth`5BratId`5D.send`20=`20TRUE;
X`09`09`09`09continue;
X`09`09`09`7D
X`09`09`09if`20(M.duke`20`7C`7C
X`09`09`09`20`20`20`20((M.ratcb.dukeRat`20==`20ratId)`20`26`26
X`09`09`09`20`20`20`20`20(nextRatId(ratId)`20==`20M.myRatId)))`20`7B
X`09`09`09`09M.duke`20=`20TRUE;
X`09`09`09`09M.ratcb.dukeRat`20=`20M.myRatId;
X`09`09`09`09ratLeft(ratId);
X`09`09`09`7D
X`09`09`7D
X`09`09sendQuery();
X`09`09gettimeofday(`26waitStart,`20NULL);
X`09`7D
X`09
X`7D
X
XRatId
XnextRatId(ratId)
XRatId`09ratId;
X`7B
X`09RatId`09ixRatId;
X
X`09for`20(ixRatId`20=`200;`20ixRatId`20<`20MAXRATS;`20ixRatId++)
X`09`09if`20(M.ratcb.rats`5BixRatId`5D.playing`20`26`26
X`09`09`20`20`20`20(ixRatId`20!=`20ratId))
X`09`09`09return`20ixRatId;
X`09return`20ixRatId;
X`7D
X
XNewPosition()
X`7B
X`09register`09rndCnt`20=`200;
X
X`09M.xloc`20=`20M.yloc`20=`200;`09`09/*`20start`20on`20occupied`20square`20*/
X`09while`20(mp`5BM.xloc`5D.y`5BM.yloc`5D)`20`7B
X`09`09M.xloc`20=`20random(MAZEXMAX);
X`09`09M.yloc`20=`20random(MAZEYMAX);
X`09`09if`20(++rndCnt`20==`20100)`20`7B
X`09`09`09rndCnt`20=`200;
X`09`09`09InitRandom();
X`09`09`7D
X`09`7D
X
X`09/*`20prevent`20a`20blank`20wall`20at`20first`20glimpse`20*/
X
X`09if`20(!M.maze`5BM.xloc+1`5D.y`5BM.yloc`5D)`20M.dir`20=`20NORTH;
X`09if`20(!M.maze`5BM.xloc-1`5D.y`5BM.yloc`5D)`20M.dir`20=`20SOUTH;
X`09if`20(!M.maze`5BM.xloc`5D.y`5BM.yloc+1`5D)`20M.dir`20=`20EAST;
X`09if`20(!M.maze`5BM.xloc`5D.y`5BM.yloc-1`5D)`20M.dir`20=`20WEST;
X
X`09return;
X`7D
X
X/*`20re-initialize`20the`20maze`20randomization`20vector`20*/
XInitRandom()
X`7B
X`09struct`20timeval`09t;
X`09struct`20timezone`09tz;
X`09register`20int`09i;
X
X`09gettimeofday(`26t,`20`26tz);
X`09for`20(i`20=`200;`20i`20<`20VECTORSIZE;`20i++)
X`09`09M.randomVector`5Bi`5D`20=`20M.randomVector`5Bi`5D`20+`20t.tv_sec`20`26
V`200xffff;
X`7D
X
Xrandom(limit)
Xregister`20int`09limit;
X`7B
X`09register`20unsigned`20int`09ret;
X
X`09ret`20=`20M.randomVector`5Bi1`5D`20=`20M.randomVector`5Bi1`5D`20+`20M.rando
VmVector`5Bi2`5D;
X`09if`20(++i1`20>=`20VECTORSIZE)
X`09`09i1`20=`200;
X`09if`20(++i2`20>=`20VECTORSIZE)
X`09`09i2`20=`200;
X`09return`20ret%limit;
X`7D
X
XMWError(s)
Xchar`20*s;
X`7B
X`09StopWindow();
X`09fprintf(stderr,`20"MazeWar:`20%s`5Cn",`20s);
X`09perror("MazeWar");
X`09exit(-1);
X`7D
$ call unpack [.MAZEWAR]MAZEWAR.C;17 1461979702 ""
$!
$ create 'f'
X
X
X
XMAZEWAR(6)`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20MAZEWAR(6
V)
X
X
XN`08NA`08AM`08ME`08E
X`20`20`20`20`20MazeWar`20-`20distributed`20rats`20in`20a`20maze
X
XS`08SY`08YN`08NT`08TA`08AX`08X
X`20`20`20`20`20/`08/u`08us`08sr`08r/`08/g`08ga`08am`08me`08es`08s/`08/m`08mw
V`08w`20`5B`20_`08w_`08i_`08n_`08d_`08o_`08w`20_`08s_`08y_`08s_`08t_`08e_`08m
V`20_`08o_`08p_`08t_`08i_`08o_`08n_`08s`20`5D
X
XD`08DE`08ES`08SC`08CR`08RI`08IP`08PT`08TI`08IO`08ON`08N
X`20`20`20`20`20This`20`20program`20implements`20the`20age-old`20game`20of`20Ma
VzeWar.`20`20Maze-
X`20`20`20`20`20War`20first`20appeared`20at`20MIT`20in`20the`20early`20`201970s
V,`20`20using`20`20IMLAC
X`20`20`20`20`20displays`20`20and`20`20the`20`20ArpaNet`20network.`20`20Legend
V`20has`20it`20that,`20at
X`20`20`20`20`20one`20point`20during`20that`20period,`20MazeWar`20was`20`20bann
Ved`20`20by`20`20DARPA
X`20`20`20`20`20from`20`20the`20ArpaNet`20because`20half`20of`20all`20the`20pac
Vkets`20in`20a`20given
X`20`20`20`20`20month`20were`20MazeWar`20packets`20flying`20between`20Stanford
V`20and`20`20MIT.
X
X`20`20`20`20`20MazeWar`20`20appeared`20again`20at`20the`20Xerox`20Palo`20Alto
V`20Research`20Cen-
X`20`20`20`20`20ter`20in`20the`20late`201970's`20on`20the`20Alto,`20the`20first
V`20personal`20`20com-
X`20`20`20`20`20puter.`20`20`20This`20`20version`20`20has`20subsequently`20been
V`20ported`20to`20many
X`20`20`20`20`20personal`20machines,`20and`20forms`20the`20basis`20for`20`20thi
Vs`20`20Unix`20`20ver-
X`20`20`20`20`20sion.
X
X`20`20`20`20`20_`08M_`08w`20`20attempts`20`20to`20be`20as`20faithful`20to`20th
Ve`20original`20Alto`20version
X`20`20`20`20`20as`20possible.`20`20The`20shape`20and`20pictures`20of`20the`20m
Vaze`20are`20`20as`20`20in
X`20`20`20`20`20the`20`20original,`20and`20there`20are`20no`20embellishments
V`20such`20as`20tele-
X`20`20`20`20`20port`20traps`20or`20robot`20amanuenses.
X
XP`08PL`08LA`08AY`08Y
X`20`20`20`20`20You,`20the`20player,`20are`20a`20rat`20in`20a`20maze,`20and`20t
Vhe`20`20objective`20`20is
X`20`20`20`20`20to`20find`20your`20opponents`20and`20shoot`20them`20before`20th
Vey`20shoot`20you.
X
X`20`20`20`20`20Each`20of`20the`20(up`20to`20eight)`20players`20in`20a`20game
V`20may`20be`20on`20a`20dif-
X`20`20`20`20`20ferent`20`20host.`20`20`20Upon`20`20startup,`20you`20are`20aske
Vd`20for`20the`20name`20by
X`20`20`20`20`20which`20you`20wish`20to`20be`20known`20for`20the`20duration`20o
Vf`20the`20game,`20and
X`20`20`20`20`20the`20`20name`20of`20the`20`60`60Duke`20host''.`20`20If`20you
V`20type`20a`20bare`20carriage
X`20`20`20`20`20return`20to`20this`20query,`20_`08m_`08w`20will`20find`20a`20ga
Vme`20by`20broadcasting`20on
X`20`20`20`20`20the`20`20local`20network,`20and`20join`20any`20game`20it`20find
Vs.`20`20If`20you`20wish
X`20`20`20`20`20to`20join`20a`20specific`20game,`20or`20a`20game`20on`20`20anot
Vher`20`20network,`20`20or
X`20`20`20`20`20your`20`20network`20doesn't`20support`20broadcasting,`20type
V`20in`20the`20name
X`20`20`20`20`20of`20one`20of`20the`20hosts`20involved`20`20in`20`20that`20`20g
Vame.`20`20`20The`20`20program
X`20`20`20`20`20_`08m_`08a_`08z_`08e_`08f_`08i_`08n_`08d`20`20will`20`20aid`20
V`20you`20`20in`20finding`20out`20what`20games`20are`20cur-
X`20`20`20`20`20rently`20being`20played.
X
X`20`20`20`20`20Once`20in`20a`20game,`20you`20are`20`20presented`20`20with`20
V`20the`20`20game`20`20window.
X`20`20`20`20`20This`20window`20is`20made`20up`20of`20three`20sections.`20`20Th
Ve`20upper`20section
X`20`20`20`20`20is`20a`20perspective`20view`20of`20your`20view`20forward.`20
V`20By`20pressing`20the
X`20`20`20`20`20left`20`20or`20`20right`20`20mouse`20`20buttons,`20you`20may
V`20peek`20to`20the`20left`20or
X`20`20`20`20`20right`20around`20corners.
X
X`20`20`20`20`20The`20middle`20section`20of`20the`20window`20is`20a`20top`20vie
Vw`20of`20the`20`20maze,
X`20`20`20`20`20showing`20`20your`20current`20position`20and`20heading`20in`20t
Vhe`20maze.`20`20You
X`20`20`20`20`20move`20around`20the`20maze`20by`20using`20the`20following`20key
Vs:
X
X`20`20`20`20`20A`20`20`20`20`20About`20face;`20flip`20end-for-end
X`20`20`20`20`20S`20`20`20`20`20Turn`2090`20degrees`20left
X`20`20`20`20`20D`20`20`20`20`20Move`20forward`20one`20cell
X
X
X
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20`20`20`20`20`20`20`20`20`20`20`20`201
X
X
X
X
X
XMAZEWAR(6)`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20MAZEWAR(6
V)
X
X
X`20`20`20`20`20F`20`20`20`20`20Turn`2090`20degrees`20right
X`20`20`20`20`20<space>Move`20backward`20one`20cell
X`20`20`20`20`20Q`20`20`20`20`20Quit
X
X`20`20`20`20`20For`20left-handers,`20there`20are`20equivalents`20on`20the`20nu
Vmeric`20`20key-
X`20`20`20`20`20pad.`20`20On`20the`20DEC`20LK201`20keyboard,`20the`20`604',`20
V`605',`20`606',`20`60,',`20and
X`20`20`20`20`20right`20cursor`20arrow`20keys`20perform`20the`20equivalent`20op
Verations.
X
X`20`20`20`20`20The`20lower`20section`20of`20the`20window`20shows`20the`20names
V`20`20and`20`20scores
X`20`20`20`20`20of`20`20the`20`20other`20`20players`20in`20the`20game.`20`20Whe
Vn`20you`20sight`20another
X`20`20`20`20`20rat,`20that`20rat's`20score`20line`20is`20highlighted.`20`20Sho
Vot`20by`20`20press-
X`20`20`20`20`20ing`20`20the`20`20middle`20`20mouse`20`20button.`20`20`20When
V`20you`20are`20shot`20at,`20the
X`20`20`20`20`20mouse`20cursor`20changes`20from`20a`20rat`20to`20a`20dead`20rat
V,`20and`20you`20`20have
X`20`20`20`20`20one`20`20second`20to`20move`20out`20of`20the`20way`20of`20the
V`20shot`20or`20shoot`20back
X`20`20`20`20`20or`20both.`20`20A`20shot`20costs`20one`20point;`20`20getting
V`20`20hit`20`20costs`20`20five
X`20`20`20`20`20points;`20`20hitting`20someone`20adds`20ten`20points.`20`20When
V`20you`20are`20hit,
X`20`20`20`20`20the`20screen`20flashes`20and`20you`20are`20transported`20to`20
V`20another`20`20sec-
X`20`20`20`20`20tion`20of`20the`20maze.
X
X`20`20`20`20`20If`20your`20window`20system`20supports`20it,`20when`20you`20ico
Vnify`20the`20game
X`20`20`20`20`20window,`20it`20will`20let`20you`20know`20when`20someone`20joins
V`20the`20game`20`20or
X`20`20`20`20`20shoots`20`20at`20`20you`20(by`20flashing,`20in`20most`20cases).
V`20`20This`20way,`20you
X`20`20`20`20`20can`20be`20notified`20whenever`20someone`20else`20is`20interest
Ved`20in`20wast-
X`20`20`20`20`20ing`20some`20time,`20by`20always`20leaving`20a`20game`20around.
V
X
XS`08SE`08EE`08E`20A`08AL`08LS`08SO`08O
X`20`20`20`20`20mazefind(6)
X
XA`08AU`08UT`08TH`08HO`08OR`08R
X`20`20`20`20`20Christopher`20A.`20Kent
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20
V`20`20`20`20`20`20`20`20`20`20`20`20`20`202
X
X
$ call unpack [.MAZEWAR]MAZEWAR.DOC;1 1109228115 ""
$!
$ create 'f'
X/*`20$Header:`20mazewar.h,v`201.7`2088/08/25`2009:59:51`20kent`20Exp`20$`20*/
X
X/*`20
X`20*`20mazewar.h`20-`20Definitions`20for`20MazeWar
X`20*`20
X`20*`20Author:`09Christopher`20A.`20Kent
X`20*`20`09`09Western`20Research`20Laboratory
X`20*`20`09`09Digital`20Equipment`20Corporation
X`20*`20Date:`09Wed`20Sep`2024`201986
X`20*/
X
X/***********************************************************
XCopyright`201986`20by`20Digital`20Equipment`20Corporation,`20Maynard,`20Massac
Vhusetts,
X
X`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20`20All
V`20Rights`20Reserved
X
XPermission`20to`20use,`20copy,`20modify,`20and`20distribute`20this`20software
V`20and`20its`20
Xdocumentation`20for`20any`20purpose`20and`20without`20fee`20is`20hereby`20gran
Vted,`20
Xprovided`20that`20the`20above`20copyright`20notice`20appear`20in`20all`20copie
Vs`20and`20that
Xboth`20that`20copyright`20notice`20and`20this`20permission`20notice`20appear
V`20in`20
Xsupporting`20documentation,`20and`20that`20the`20names`20of`20Digital`20not
V`20be
Xused`20in`20advertising`20or`20publicity`20pertaining`20to`20disstribution`20o
Vf`20the
Xsoftware`20without`20specific,`20written`20prior`20permission.`20`20
X
XDIGITAL`20DISCLAIMS`20ALL`20WARRANTIES`20WITH`20REGARD`20TO`20THIS`20SOFTWARE,
V`20INCLUDING
XALL`20IMPLIED`20WARRANTIES`20OF`20MERCHANTABILITY`20AND`20FITNESS,`20IN`20NO
V`20EVENT`20SHALL
XDIGITAL`20BE`20LIABLE`20FOR`20ANY`20SPECIAL,`20INDIRECT`20OR`20CONSEQUENTIAL
V`20DAMAGES`20OR
XANY`20DAMAGES`20WHATSOEVER`20RESULTING`20FROM`20LOSS`20OF`20USE,`20DATA`20OR
V`20PROFITS,
XWHETHER`20IN`20AN`20ACTION`20OF`20CONTRACT,`20NEGLIGENCE`20OR`20OTHER`20TORTIO
VUS`20ACTION,
XARISING`20OUT`20OF`20OR`20IN`20CONNECTION`20WITH`20THE`20USE`20OR`20PERFORMANC
VE`20OF`20THIS
XSOFTWARE.
X
X******************************************************************/
X
X/*
X`20*`20$Log:`09mazewar.h,v`20$
X`20*`20Revision`201.7`20`2088/08/25`20`2009:59:51`20`20kent
X`20*`20Copyright.
X`20*`20
X`20*`20Revision`201.6`20`2088/08/11`20`2011:37:59`20`20kent
X`20*`20Fix`20a`20type`20clash`20with`20X11`20include`20files.`20We`20need`20a
V`20Boolean`20to`20be`20a`20short
X`20*`20for`20alignment`20purposes,`20but`20X11`20typedefs`20it`20to`20be`20a
V`20char.`20
X`20*`20
X`20*`20Revision`201.5`20`2087/03/31`20`2014:42:32`20`20kent
X`20*`20Portability`20considerations,`20especially`20byteswapping`20to/from`20t
Vhe`20net.
X`20*`20
X`20*`20Revision`201.4`20`2086/12/03`20`2010:00:54`20`20kent
X`20*`20Changes`20to`20allow`20multiple`20players`20per`20machine.
X`20*`20
X`20*`20Revision`201.3`20`2086/12/01`20`2023:45:53`20`20kent
X`20*`20Housecleaning`20and`20documentation`20pass.
X`20*`20
X`20*`20Revision`201.2`20`2086/12/01`20`2014:47:52`20`20kent
X`20*`20Changes`20for`20a`20realistic`20implementation`20of`20shooting.
X`20*`20
X`20*`20Revision`201.1`20`2086/11/26`20`2016:58:19`20`20kent
X`20*`20Initial`20revision
X`20*`20
X`20*`20Revision`201.1`20`2086/11/26`20`2016:56:33`20`20kent
X`20*`20Initial`20revision
X`20*`20
X`20*/
X
X/*`20fundamental`20constants`20*/
X
X#ifndef`09TRUE
X#define`09TRUE`09`091
X#define`09FALSE`09`090
X#endif`09TRUE
X
X#define`09MAZEXMAX`0932
X#define`09MAZEYMAX`0916
X#define`09MAXRATS`09`098
X#define`09VECTORSIZE`0955
X#define`09NAMESIZE`0920
X#define`09NDIRECTION`094
X#define`09NORTH`09`090
X#define`09SOUTH`09`091
X#define`09EAST`09`092
X#define`09WEST`09`093
X#define`09NVIEW`09`094
X#define`09LEFT`09`090
X#define`09RIGHT`09`091
X#define`09REAR`09`092
X#define`09FRONT`09`093
X
X/*`20types`20*/
X
Xtypedef`09struct`20sockaddr_in`09`09Sockaddr;
X#define`09Boolean`09short`09`09/*`20don't`20clash`20with`20X11`20toolkit`20*/
Xtypedef`20struct`20`7BBoolean`09y`5BMAZEYMAX`5D;`7D`09MazeRow;
Xtypedef`09MazeRow`09`09`09`09MazeType
X`09`5BMAZEXMAX`5D;
Xtypedef`09MazeRow`09`09`09`09*MazeTypePtr;
Xtypedef`09short`09`09`09`09Direction;
Xtypedef`09struct`20`7Bshort`09x,`20y;`20`7D`09`09XYpoint;
Xtypedef`09struct`20`7BXYpoint`09p1,`20p2;`7D`09XYpair;
Xtypedef`09struct`20`7Bshort`09xcor,`20ycor;`7D`09XY;
X
Xtypedef`09struct`20`7Bshort`09bits`5B16`5D;`7D`09BitCell;
X
Xtypedef`09short`09`09`09`09Loc;
Xtypedef`09unsigned`20long`09`09`09Score;
Xtypedef`09char`09`09`09`09RatName
X`09`5BNAMESIZE`5D;
Xtypedef`09long`09`09`09`09RatId;
X
Xtypedef`09struct`20`7B
X`09RatId`09ratId;
X`09Score`09score;
X`09Loc`09xLoc,`20yLoc;
X`09Direction`09dir;
X`7D`09`09`09`09`09AqRatLocation;
Xtypedef`09AqRatLocation`20*`09`09`09RatLocation;
X
Xtypedef`20struct`20`7B
X`09RatId`09ratId;
X`09Loc`09xLoc,`20yLoc;
X`09Direction`09dir;
X`7D`09`09`09`09`09AqRatKill;
Xtypedef`09AqRatKill`20*`09`09`09RatKill;
X
Xstruct`20_AqRatKillQ`20`7B
X`09AqRatKill`09thisOne;
X`09struct`20_AqRatKillQ`09*nextOne;
X`09struct`20timeval`09shotHits;
X`7D;
Xtypedef`20struct`20_AqRatKillQ`09`09AqRatKillQ;
Xtypedef`09AqRatKillQ`20*`09`09`09RatKillQ_t;
X
Xtypedef`09struct`20`7B
X`09RatId`09ratId;
X`09RatId`09killedBy;
X`7D`09`09`09`09`09AqRatDead;
Xtypedef`09AqRatDead`20*`09`09`09RatDead;
X
Xtypedef`09struct`20`7B
X`09Sockaddr`09addr;
X`09short`09`09pass;
X`09Loc`09`09xLoc,`20yLoc;
X`09Direction`09dir;
X`09RatName`09`09name;
X`7D`09`09`09`09`09AqRatNew;
Xtypedef`09AqRatNew`20*`09`09`09RatNew;
X
Xtypedef`09struct`20`7B
X`09RatId`09ratId;
X`7D`09`09`09`09`09AqRatGone;
Xtypedef`09AqRatGone`20*`09`09`09RatGone;
X
Xtypedef`09struct`20`7B
X`09RatId`09ratId;
X`7D`09`09`09`09`09AqRatQuery;
Xtypedef`09AqRatQuery`20*`09`09`09RatQuery;
X
Xtypedef`20struct`20`7B
X`09RatId`09ratId;
X`7D`09`09`09`09`09AqRatAlive;
Xtypedef`09AqRatAlive`20*`09`09`09RatAlive;
X
Xtypedef`20struct`20`7B
X`09RatId`09ratId;
X`7D`09`09`09`09`09AqRatMove;
Xtypedef`09AqRatMove`20*`09`09`09RatMove;
X
Xtypedef`09struct`20`7B
X`09Sockaddr`09addr;
X`09Score`09`09score;
X`09Boolean`09`09playing;
X`09Loc`09`09xLoc,`20yLoc;
X`09Direction`09dir;
X`09RatName`09`09name;
X`7D`09`09`09`09`09RatObject;
Xtypedef`09RatObject`20*`09`09`09RatInfo;
X
Xtypedef`09struct`20`7B
X`09RatId`09`09dukeRat;
X`09RatObject`09rats`5BMAXRATS`5D;
X`7D`09`09`09`09`09RatCb;
Xtypedef`09RatCb`20*`09`09`09`09RatStatus;
X
Xtypedef`09long`09`09`09`09TokenId;
X
Xtypedef`09struct`20`7B
X`09Boolean`09visible;
X`09Loc`09x,`20y;
X`09short`09distance;
X`09TokenId`09tokenId;
X`7D`09`09`09`09`09RatAppearance;
Xtypedef`09RatAppearance`09`09`09R2d2_t
X`09`5BMAXRATS`5D;
Xtypedef`09RatAppearance`20*`09`09`09RatLook;
X
Xtypedef`09struct`20`7BTokenId`09t`5BNDIRECTION`5D;`7D`09RelativeTokens
X`09`5BNDIRECTION`5D;
X
Xtypedef`09struct`20`7B
X`09Boolean`09send;
X`09Boolean`09rcvd;
X`09short`09count;
X`7D`09`09`09`09`09RatNetHealth;
Xtypedef`09RatNetHealth`09`09`09RatHealth
X`09`5BMAXRATS`5D;
X
X/*`20network`20stuff`20*/
X
X#define`09MAZEPORT`091111
X#define`09MAZESERVICE`09"mazewar"
X
X#define`09RAT_LOCATION`091
X#define`09RAT_KILL`092
X#define`09RAT_DEAD`093
X#define`09RAT_STATUS`094
X#define`09RAT_NEW`09`095
X#define`09RAT_GOING`096
X#define`09RAT_QUERY`097
X#define`09RAT_ALIVE`098
X#define`09RAT_SURVEY`099
X#define`09RAT_MOVE`0910
X#define`09RAT_PASSWORD`09032610
X
Xtypedef`09struct`20`7B
X`09long`09type;
X`09RatCb`09body;`09`09`09/*`20largest`20type`20above`20*/
+-+-+-+-+-+-+-+- END OF PART 4 +-+-+-+-+-+-+-+-