home *** CD-ROM | disk | FTP | other *** search
- /* 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 */
- }
-