home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume28 / ldb / part01 / game.c < prev    next >
C/C++ Source or Header  |  1992-03-15  |  6KB  |  202 lines

  1. /*    game.c        8/3/91
  2.  *
  3.  * Copyright 1991  Perry R. Ross
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software and its
  6.  * documentation without fee is hereby granted, subject to the restrictions
  7.  * detailed in the README file, which is included here by reference.
  8.  * Any other use requires written permission from the author.  This software
  9.  * is distributed "as is" without any warranty, including any implied
  10.  * warranties of merchantability or fitness for a particular purpose.
  11.  * The author shall not be liable for any damages resulting from the
  12.  * use of this software.  By using this software, the user agrees
  13.  * to these terms.
  14.  */
  15.  
  16. #include "ldb.h"
  17.  
  18. /*----------------------------------------------------------------------
  19.  *    startgame -- start a game
  20.  *
  21.  * This function is called in response to the -start command line
  22.  * option to start a game with another user.  It allocates a game
  23.  * record and fills it in, then sends a START packet to the opponent.
  24.  * The arguments are:
  25.  *    The email address of the opponent
  26.  *    The direction I want to play
  27.  *    The color I want to play
  28.  *    The color I want the opponent to play
  29.  *----------------------------------------------------------------------
  30.  */
  31.  
  32. struct game *startgame(addr,d,mc,oc)
  33. char *addr;            /* path to opponent */
  34. int d;
  35. char mc, oc;
  36. {
  37. struct game *g;
  38. char c1, c2, *newid;
  39.  
  40. newid = makeid();        /* give it a unique id */
  41. g = addgame();            /* allocate new game */
  42. g->gameid = newid;        /* store new id */
  43. g->opaddr = save(addr);        /* save opponent's mail addr */
  44. g->opname = NULL;        /* we don't know his name yet */
  45. g->mycolor = mc;        /* set starting colors */
  46. g->opcolor = oc;
  47. g->mydir = d;            /* set starting directions */
  48. g->opdir = REV(d);
  49. g->gameval = 1;            /* no doubles yet */
  50. g->adcnt = 0;            /* no autodoubles yet */
  51. g->admax = rc.autodouble;    /* max allowed autodoubles */
  52. g->flags = 0;
  53. g->state = ST_OPSTART;        /* need to send first roll */
  54. g->seq = 1;            /* start with sequence number = 1 */
  55. if (d > 0) {
  56.     c1 = mc;    /* upbound color is mine */
  57.     c2 = oc;    /* downbound color is opponent's */
  58.     }
  59. else {
  60.     c1 = oc;    /* upbound color is opponent's */
  61.     c2 = mc;    /* downbound color is mine */
  62.     }
  63. clearmvs(g->mvs);
  64. clearmvs(g->opmvs);
  65. newboard(g->opbd,c1,c2);    /* set up boards for new game */
  66. newboard(g->mybd,c1,c2);
  67. newboard(g->board,c1,c2);
  68. g->mvs[0].roll = Rolldie();    /* roll an initial die */
  69. sendpkt(g,START);        /* send the start message */
  70. return(g);            /* and return pointer to new game */
  71. }
  72.  
  73.  
  74. /*----------------------------------------------------------------------
  75.  *    makeid -- create a unique game identifier.
  76.  *
  77.  * This function creates a string that is guaranteed unique among all
  78.  * ldb games worldwide, provided that email addresses are unique.
  79.  * This should be a good assumption, since if there is a duplicate,
  80.  * the users with the duplicate id's will have a great deal of difficulty
  81.  * getting mail delivered, and therefore won't be able to play ldb anyway.
  82.  * To make id's created by the same user unique, the time is
  83.  * appended to the mail address; to make sure the time is unique when
  84.  * the user creates more than 1 game per second, the games list is searched
  85.  * for a new id before it is returned and, if it is found, we sleep for
  86.  * 1 second and try again.
  87.  *----------------------------------------------------------------------
  88.  */
  89.  
  90. char *makeid()
  91. {
  92. char *n;
  93.  
  94. if ( (n = calloc(strlen(rc.myaddr)+10,1)) == NULL) {
  95.     FeFinishSession();    /* close down front-end */
  96.     TFinishSession();    /* close down transport */
  97.     fprintf(stderr,"ERROR: Out of memory!\n");
  98.     exit(1);
  99.     }
  100. do {
  101.     sprintf(n,"%s|%08x",rc.myaddr,time(0));
  102.     if (findgame(n) == NULL)
  103.         return(n);
  104.     sleep(1);
  105.     } while (1);
  106. }
  107.  
  108.  
  109. /*---------------------------------------------------------------------------
  110.  *    addgame -- allocate a game struct and link it into the game list
  111.  *
  112.  * This function allocates a game structure and links it into the
  113.  * doubly-linked game list.  The head of this list is ghead, and the
  114.  * tail is gtail.
  115.  *
  116.  * NOTE: the memory-zeroing feature of calloc is depended on to
  117.  *     initialize the allocated game struct.
  118.  *---------------------------------------------------------------------------
  119.  */
  120.  
  121. struct game *addgame()
  122. {
  123. struct game *g;
  124.  
  125. if ( (g = (struct game *)calloc(sizeof(struct game),1)) == NULL) {
  126.     FeFinishSession();    /* close down front-end */
  127.     TFinishSession();    /* close down transport */
  128.     fprintf(stderr,"Out of memory!\n");
  129.     exit(1);
  130.     }
  131. g->next = NULL;
  132. if (gtail == NULL) {        /* this is the first game in the list */
  133.     ghead = g;
  134.     gtail = g;
  135.     g->prev = NULL;
  136.     }
  137. else {
  138.     g->prev = gtail;    /* link onto end of list */
  139.     gtail->next = g;
  140.     gtail = g;
  141.     }
  142. return(g);
  143. }
  144.  
  145.  
  146. /*----------------------------------------------------------------------
  147.  *    deletegame -- delete a game from the game list
  148.  *
  149.  * This function removes a game from the game list by linking around
  150.  * it, then frees the memory associated with the game structure.
  151.  *----------------------------------------------------------------------
  152.  */
  153.  
  154. deletegame(g)
  155. struct game *g;
  156. {
  157.  
  158. if (g == ghead) {        /* deleting first game in list */
  159.     ghead = g->next;    /* move head pointer to next game */
  160.     if (ghead == NULL)    /* we just deleted the last game */
  161.         gtail = NULL;    /* set both ptrs to NULL */
  162.     else
  163.         ghead->prev = NULL;    /* first in list has no prev */
  164.     }
  165. else if (g == gtail) {        /* deleting last game in list */
  166.     gtail = g->prev;    /* move tail pointer back */
  167.     gtail->next = NULL;    /* last game has no next */
  168.     }
  169. else {
  170.     g->next->prev = g->prev;    /* link back link around g */
  171.     g->prev->next = g->next;    /* and forward link too */
  172.     }
  173. if (g->gameid != NULL)
  174.     free(g->gameid);        /* free string space */
  175. if (g->opname != NULL)
  176.     free(g->opname);
  177. if (g->opaddr != NULL)
  178.     free(g->opaddr);
  179. free(g);            /* free the memory */
  180. }
  181.  
  182.  
  183. /*----------------------------------------------------------------------
  184.  *    findgame -- find a game based on its game id
  185.  *
  186.  * This function performs a linear search through the game list
  187.  * for a game id.  It returns a pointer to the game, or NULL if
  188.  * the game does not exist.
  189.  *----------------------------------------------------------------------
  190.  */
  191.  
  192. struct game *findgame(gid)
  193. char *gid;
  194. {
  195. struct game *g;
  196.  
  197. for (g = ghead; g != NULL; g = g->next)
  198.     if (strcmp(gid,g->gameid) == 0)        /* is this it? */
  199.         return(g);            /* yup, return it */
  200. return(NULL);                    /* no such game */
  201. }
  202.