home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume28
/
ldb
/
part01
/
game.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-15
|
6KB
|
202 lines
/* game.c 8/3/91
*
* Copyright 1991 Perry R. Ross
*
* Permission to use, copy, modify, and distribute this software and its
* documentation without fee is hereby granted, subject to the restrictions
* detailed in the README file, which is included here by reference.
* Any other use requires written permission from the author. This software
* is distributed "as is" without any warranty, including any implied
* warranties of merchantability or fitness for a particular purpose.
* The author shall not be liable for any damages resulting from the
* use of this software. By using this software, the user agrees
* to these terms.
*/
#include "ldb.h"
/*----------------------------------------------------------------------
* startgame -- start a game
*
* This function is called in response to the -start command line
* option to start a game with another user. It allocates a game
* record and fills it in, then sends a START packet to the opponent.
* The arguments are:
* The email address of the opponent
* The direction I want to play
* The color I want to play
* The color I want the opponent to play
*----------------------------------------------------------------------
*/
struct game *startgame(addr,d,mc,oc)
char *addr; /* path to opponent */
int d;
char mc, oc;
{
struct game *g;
char c1, c2, *newid;
newid = makeid(); /* give it a unique id */
g = addgame(); /* allocate new game */
g->gameid = newid; /* store new id */
g->opaddr = save(addr); /* save opponent's mail addr */
g->opname = NULL; /* we don't know his name yet */
g->mycolor = mc; /* set starting colors */
g->opcolor = oc;
g->mydir = d; /* set starting directions */
g->opdir = REV(d);
g->gameval = 1; /* no doubles yet */
g->adcnt = 0; /* no autodoubles yet */
g->admax = rc.autodouble; /* max allowed autodoubles */
g->flags = 0;
g->state = ST_OPSTART; /* need to send first roll */
g->seq = 1; /* start with sequence number = 1 */
if (d > 0) {
c1 = mc; /* upbound color is mine */
c2 = oc; /* downbound color is opponent's */
}
else {
c1 = oc; /* upbound color is opponent's */
c2 = mc; /* downbound color is mine */
}
clearmvs(g->mvs);
clearmvs(g->opmvs);
newboard(g->opbd,c1,c2); /* set up boards for new game */
newboard(g->mybd,c1,c2);
newboard(g->board,c1,c2);
g->mvs[0].roll = Rolldie(); /* roll an initial die */
sendpkt(g,START); /* send the start message */
return(g); /* and return pointer to new game */
}
/*----------------------------------------------------------------------
* makeid -- create a unique game identifier.
*
* This function creates a string that is guaranteed unique among all
* ldb games worldwide, provided that email addresses are unique.
* This should be a good assumption, since if there is a duplicate,
* the users with the duplicate id's will have a great deal of difficulty
* getting mail delivered, and therefore won't be able to play ldb anyway.
* To make id's created by the same user unique, the time is
* appended to the mail address; to make sure the time is unique when
* the user creates more than 1 game per second, the games list is searched
* for a new id before it is returned and, if it is found, we sleep for
* 1 second and try again.
*----------------------------------------------------------------------
*/
char *makeid()
{
char *n;
if ( (n = calloc(strlen(rc.myaddr)+10,1)) == NULL) {
FeFinishSession(); /* close down front-end */
TFinishSession(); /* close down transport */
fprintf(stderr,"ERROR: Out of memory!\n");
exit(1);
}
do {
sprintf(n,"%s|%08x",rc.myaddr,time(0));
if (findgame(n) == NULL)
return(n);
sleep(1);
} while (1);
}
/*---------------------------------------------------------------------------
* addgame -- allocate a game struct and link it into the game list
*
* This function allocates a game structure and links it into the
* doubly-linked game list. The head of this list is ghead, and the
* tail is gtail.
*
* NOTE: the memory-zeroing feature of calloc is depended on to
* initialize the allocated game struct.
*---------------------------------------------------------------------------
*/
struct game *addgame()
{
struct game *g;
if ( (g = (struct game *)calloc(sizeof(struct game),1)) == NULL) {
FeFinishSession(); /* close down front-end */
TFinishSession(); /* close down transport */
fprintf(stderr,"Out of memory!\n");
exit(1);
}
g->next = NULL;
if (gtail == NULL) { /* this is the first game in the list */
ghead = g;
gtail = g;
g->prev = NULL;
}
else {
g->prev = gtail; /* link onto end of list */
gtail->next = g;
gtail = g;
}
return(g);
}
/*----------------------------------------------------------------------
* deletegame -- delete a game from the game list
*
* This function removes a game from the game list by linking around
* it, then frees the memory associated with the game structure.
*----------------------------------------------------------------------
*/
deletegame(g)
struct game *g;
{
if (g == ghead) { /* deleting first game in list */
ghead = g->next; /* move head pointer to next game */
if (ghead == NULL) /* we just deleted the last game */
gtail = NULL; /* set both ptrs to NULL */
else
ghead->prev = NULL; /* first in list has no prev */
}
else if (g == gtail) { /* deleting last game in list */
gtail = g->prev; /* move tail pointer back */
gtail->next = NULL; /* last game has no next */
}
else {
g->next->prev = g->prev; /* link back link around g */
g->prev->next = g->next; /* and forward link too */
}
if (g->gameid != NULL)
free(g->gameid); /* free string space */
if (g->opname != NULL)
free(g->opname);
if (g->opaddr != NULL)
free(g->opaddr);
free(g); /* free the memory */
}
/*----------------------------------------------------------------------
* findgame -- find a game based on its game id
*
* This function performs a linear search through the game list
* for a game id. It returns a pointer to the game, or NULL if
* the game does not exist.
*----------------------------------------------------------------------
*/
struct game *findgame(gid)
char *gid;
{
struct game *g;
for (g = ghead; g != NULL; g = g->next)
if (strcmp(gid,g->gameid) == 0) /* is this it? */
return(g); /* yup, return it */
return(NULL); /* no such game */
}