home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume4 / xconq5 / part15 / util.c < prev    next >
C/C++ Source or Header  |  1988-07-01  |  5KB  |  230 lines

  1. /* Copyright (c) 1987, 1988  Stanley T. Shebs, University of Utah. */
  2. /* This program may be used, copied, modified, and redistributed freely */
  3. /* for noncommercial purposes, so long as this notice remains intact. */
  4.  
  5. /* RCS $Header: util.c,v 1.1 88/06/21 12:30:46 shebs Exp $ */
  6.  
  7. /* Random utilities not classifiable elsewhere. Most are not xconq-specific. */
  8.  
  9. #include "config.h"
  10. #include "misc.h"
  11. #include "dir.h"
  12.  
  13. char ordnum[BUFSIZE];           /* buffer for ordinal numbers */
  14. char pluralbuf[BUFSIZE];        /* buffer for plurals of words */
  15.  
  16. int dirx[] = DIRX, diry[] = DIRY;  /* arrays for dir-to-delta conversion */
  17.  
  18. /* This generates a file name in wherever xconq keeps its assorted files. */
  19. /* Note that for Unix machines, XCONQLIB should have a trailing slash. */
  20.  
  21. make_pathname(path, name, extn, pathbuf)
  22. char *path, *name, *extn, *pathbuf;
  23. {
  24. #ifdef UNIX
  25.     sprintf(pathbuf, "%s/%s%s%s",
  26.         ((path && strlen(path) > 0) ? path : "."),
  27.         name,
  28.         ((extn && strlen(extn) > 0) ? "." : ""),
  29.         ((extn && strlen(extn) > 0) ? extn : ""));
  30. #endif UNIX
  31. #ifdef ATARI
  32.     sprintf(pathbuf, "%s\\%s.%s", path, name, extn);
  33. #endif ATARI
  34. }
  35.  
  36. /* Remove a saved game from the system. */
  37.  
  38. remove_saved_game()
  39. {
  40. #ifdef UNIX
  41.     unlink(SAVEFILE);
  42. #endif UNIX
  43. }
  44.  
  45. /* Random number handling is important to game but terrible/nonexistent */
  46. /* in some systems.  Do it ourselves and hope it's better... */
  47.  
  48. long randstate;           /* The random state *must* be at least 32 bits. */
  49.  
  50. /* Seed can come from elsewhere, for repeatability.  Otherwise, it comes */
  51. /* the current time, scaled to a point where 32-bit arithmetic won't */
  52. /* overflow.  Pid is not so good, usually a smaller range of values. */
  53.  
  54. init_random(seed)
  55. int seed;
  56. {
  57.     if (seed >= 0) {
  58.     randstate = seed;
  59.     } else {
  60. #ifdef UNIX
  61.     randstate = (time((long *) 0) % 100000L);
  62. #endif UNIX
  63.     }
  64. }
  65.  
  66. /* Numbers lifted from Numerical Recipes, p. 198. */
  67. /* Arithmetic must be 32-bit. */
  68.  
  69. random(m)
  70. int m;
  71. {
  72.     randstate = (8121 * randstate + 28411) % 134456L;
  73.     return ((m * randstate) / 134456L);
  74. }
  75.  
  76. /* Percentage probability, with bounds checking. */
  77.  
  78. probability(prob)
  79. int prob;
  80. {
  81.     if (prob <= 0) return FALSE;
  82.     if (prob >= 100) return TRUE;
  83.     return (random(100) < prob);
  84. }
  85.  
  86. /* Read a line and save it away.  This routine should be used sparingly, */
  87. /* since the malloced space is never freed. */
  88.  
  89. char *
  90. read_line(fp)
  91. FILE *fp;
  92. {
  93.     char tmp[BUFSIZE], *line;
  94.  
  95.     fgets(tmp, BUFSIZE-1, fp);
  96.     tmp[strlen(tmp)-1] = '\0';
  97.     line = (char *) malloc(strlen(tmp)+2);
  98.     strcpy(line, tmp);
  99.     return line;
  100. }
  101.  
  102. /* Copy to new-allocated space.  Again, the new space is never freed. */
  103.  
  104. char *
  105. copy_string(str)
  106. char *str;
  107. {
  108.     char *rslt;
  109.  
  110.     rslt = (char *) malloc(strlen(str)+1);
  111.     strcpy(rslt, str);
  112.     return rslt;
  113. }
  114.  
  115. /* Computing distance in a hexagonal system is a little peculiar, since it's */
  116. /* sometimes just delta x or y, and other times is the sum.  Basically there */
  117. /* are six ways to compute distance, depending on the hextant we're in. */
  118.  
  119. distance(x1, y1, x2, y2)
  120. int x1, y1, x2, y2;
  121. {
  122.     int dx = x2 - x1, dy = y2 - y1;
  123.  
  124.     if (dx >= 0) {
  125.     if (dy >= 0) {
  126.         return (dx + dy);
  127.     } else if ((0 - dy) <= dx) {
  128.         return dx;
  129.     } else {
  130.         return (0 - dy);
  131.     }
  132.     } else {
  133.     if (dy <= 0) {
  134.         return (0 - (dx + dy));
  135.     } else if (dy <= (0 - dx)) {
  136.         return (0 - dx);
  137.     } else {
  138.         return dy;
  139.     }
  140.     }
  141. }
  142.  
  143. /* Convert any vector into a direction (not necessarily the closest one). */
  144. /* Fail horribly on zero vectors. */
  145.  
  146. find_dir(dx, dy)
  147. int dx, dy;
  148. {
  149.     if (dx < 0) {
  150.     if (dy < 0) return SW;
  151.     if (dy == 0) return WEST;
  152.     return NW;
  153.     } else if (dx == 0) {
  154.     if (dy > 0) return NE;
  155.     if (dy == 0) abort();
  156.     return SW;
  157.     } else {
  158.     if (dy < 0) return SE;
  159.     if (dy == 0) return EAST;
  160.     return NE;
  161.     }
  162. }
  163.  
  164. /* Given a number, figure out what suffix should go with it. */
  165. /* Note the use of static storage (to save a little mallocing) */
  166.  
  167. char *
  168. ordinal(n)
  169. int n;
  170. {
  171.     char *suff;
  172.  
  173.     if (n % 100 == 11 || n % 100 == 12 || n % 100 == 13) {
  174.     suff = "th";
  175.     } else {
  176.     switch (n % 10) {
  177.     case 1:   suff = "st"; break;
  178.     case 2:   suff = "nd"; break;
  179.     case 3:   suff = "rd"; break;
  180.     default:  suff = "th"; break;
  181.     }
  182.     }
  183.     sprintf(ordnum, "%d%s", n, suff);
  184.     return ordnum;
  185. }
  186.  
  187. /* Pluralize a word, attempting to be smart about various possibilities */
  188. /* that don't have a different plural form (such as "Chinese" and "Swiss"). */
  189. /* There should probably be a test for when to add "es" instead of "s". */
  190.  
  191. char *
  192. plural_form(word)
  193. char *word;
  194. {
  195.     char endch = ' ', nextend = ' ';
  196.  
  197.     if (strlen(word) > 0) endch   = word[strlen(word)-1];
  198.     if (strlen(word) > 1) nextend = word[strlen(word)-2];
  199.     if (endch == 'h' || endch == 's' || (endch == 'e' && nextend == 's')) {
  200.     sprintf(pluralbuf, "%s", word);
  201.     } else {
  202.     sprintf(pluralbuf, "%ss", word);
  203.     }
  204.     return pluralbuf;
  205. }
  206.  
  207. /* Get a *numeric* index into a string (more useful than ptr to xconq). */
  208. /* Return -1 on failed search. */
  209.  
  210. iindex(ch, str)
  211. char ch, *str;
  212. {
  213.     int i;
  214.  
  215.     if (str == NULL) return (-1);
  216.     for (i = 0; str[i] != '\0'; ++i) if (ch == str[i]) return i;
  217.     return (-1);
  218. }
  219.  
  220. /* This little routine goes at the end of all switch statements on internal */
  221. /* data values.  We want a core dump to debug. */
  222.  
  223. case_panic(str, var)
  224. char *str;
  225. int var;
  226. {
  227.     fprintf(stderr, "Panic! Unknown %s %d\n", str, var);
  228.     abort();
  229. }
  230.