home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume28 / ldb / part01 / check.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-15  |  5.2 KB  |  274 lines

  1. /*    check.c        10/29/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.  * This file contains the functions that check for unused moves.
  20.  *======================================================================
  21.  */
  22.  
  23.  
  24. PRIVATE int maxused, hiused, nlegal;
  25.  
  26. struct legal *rmlegal();
  27.  
  28.  
  29. legalmoves(g)
  30. struct game *g;
  31. {
  32. struct game tmp;
  33. int i;
  34. struct legal *l;
  35.  
  36. tmp = *g;            /* we don't want to change actual game */
  37. for (i = 0; i < 4; tmp.mvs[i++].pt = -1);    /* mark all unused */
  38. maxused = -1;            /* init to not all used */
  39. hiused = 0;            /* init to 0 */
  40. nlegal = 0;            /* init to no legal moves*/
  41. lhead = NULL;
  42. ltail = NULL;
  43. if (tmp.mvs[0].roll == tmp.mvs[1].roll)
  44.     scanmvs(&tmp,0,3);    /* there is only one ordering */
  45. else {
  46.     scanmvs(&tmp,0,1);        /* scan for one ordering */
  47.     i = tmp.mvs[0].roll;    /* reverse rolls */
  48.     tmp.mvs[0].roll = tmp.mvs[1].roll;
  49.     tmp.mvs[1].roll = i;
  50.     for (i = 0; i < 4; tmp.mvs[i++].pt = -1);    /* mark all unused */
  51.     scanmvs(&tmp,0,1);        /* scan for other ordering */
  52.     }
  53. trimunused();
  54. trimlowused();
  55. trimequal();
  56. g->maxused = maxused;
  57. g->hiused = hiused;
  58. if (nlegal == 0) {
  59.     if (g->dispmsg != NULL)
  60.         free(g->dispmsg);
  61.     g->dispmsg = save("You don't have any legal moves.");
  62.     }
  63. else if (nlegal == 1) {
  64.     if (g->dispmsg != NULL)
  65.         free(g->dispmsg);
  66.     g->dispmsg = save("You only have one legal move.");
  67.     if (*rc.automove == 'y') {
  68.         if ( (lhead->nmove==0) && (lhead->mvs[0].roll!=g->mvs[0].roll))
  69.             g->mvs[1] = g->mvs[0];
  70.         for (i = 0; i <= lhead->nmove; i++) {
  71.             g->mvs[i] = lhead->mvs[i];
  72.             apply(g,1,i,0,NULL);
  73.             }
  74.         }
  75.     }
  76.  
  77.     /* we have no use for the legal moves list, so free it */
  78.     /* maybe in the future we will have a use for it */
  79.  
  80. for (l = lhead; l != NULL; l = l->next)
  81.     free(l);
  82. lhead = NULL;
  83. ltail = NULL;
  84. }
  85.  
  86.  
  87. scanmvs(g,mn,max)
  88. struct game *g;
  89. {
  90. int i;
  91. board sv;
  92.  
  93. copyboard(g->board,sv);
  94. for (i = 0; i <= 24; i++) {
  95.     if (i == 0)
  96.         g->mvs[mn].pt = BARPT(g->mydir);
  97.     else
  98.         g->mvs[mn].pt = i;
  99.     if (apply(g,1,mn,0,NULL) < 0)    /* can't move from this pt */
  100.         continue;
  101.     addlegal(mn,g->mvs[mn].roll,g->mvs[mn].pt);
  102.     if (mn < max)
  103.         scanmvs(g,mn+1,max);
  104.     copyboard(sv,g->board);
  105.     }
  106. }
  107.  
  108.  
  109. addlegal(mn,r,pt)
  110. int mn, r, pt;
  111. {
  112. int i;
  113. struct legal *n;
  114.  
  115. if ( (n = (struct legal *) calloc(sizeof(struct legal),1)) == NULL) {
  116.     FeFinishSession();
  117.     TFinishSession();
  118.     fprintf(stderr,"Out of memory!\n");
  119.     exit(1);
  120.     }
  121. clearmvs(n->mvs);
  122. if (ltail != NULL)
  123.     for (i = 0; i < mn; i++)        /* copy prefix from prev move */
  124.         n->mvs[i] = ltail->mvs[i];
  125. n->mvs[mn].roll = r;
  126. n->mvs[mn].pt = pt;
  127. n->next = NULL;
  128. if (lhead == NULL) {
  129.     n->prev = NULL;
  130.     lhead = n;
  131.     ltail = n;
  132.     }
  133. else {
  134.     n->prev = ltail;
  135.     ltail->next = n;
  136.     ltail = n;
  137.     }
  138. n->himove = 0;
  139. for (i = 0; i <= mn; i++)
  140.     if (n->mvs[i].roll > n->himove)
  141.         n->himove = n->mvs[i].roll;
  142. if (mn > maxused)        /* keep track of whether it is possible */
  143.     maxused = mn;    /* to use all of the rolls */
  144. nlegal++;
  145. n->nmove = mn;
  146. }
  147.  
  148.  
  149. trimunused()
  150. {
  151. struct legal *l;
  152.  
  153. l = lhead;
  154. while (l != NULL) {
  155.     if (l->nmove < maxused)
  156.         l = rmlegal(l);
  157.     else
  158.         l = l->next;
  159.     }
  160. }
  161.  
  162.  
  163. trimlowused()
  164. {
  165. struct legal *l;
  166.  
  167. l = lhead;
  168. while (l != NULL) {
  169.     if (l->himove < hiused)
  170.         l = rmlegal(l);
  171.     else
  172.         l = l->next;
  173.     }
  174. }
  175.  
  176.  
  177. trimequal()
  178. {
  179. struct legal *l, *p;
  180. struct mv m1[4], m2[4];
  181. int i, n;
  182.  
  183. for (l = lhead; l != NULL; l = l->next) {
  184.     extractmvs(l,m1);
  185.     n = l->nmove;
  186.     p = l->next;
  187.     while (p != NULL) {
  188.         if (p->nmove != n) {
  189.             p = p->next;
  190.             continue;
  191.             }
  192.         extractmvs(p,m2);
  193.         for (i = 0; i <= n; i++)
  194.             if ((m1[i].roll != m2[i].roll)||(m1[i].pt != m2[i].pt))
  195.                 break;
  196.         if (i <= n)
  197.             p = p->next;
  198.         else
  199.             p = rmlegal(p);
  200.         }
  201.     }
  202. }
  203.  
  204.  
  205. struct legal *rmlegal(l)
  206. struct legal *l;
  207. {
  208. struct legal *t;
  209.  
  210. t = l;
  211. if (l == lhead) {
  212.     lhead = l->next;
  213.     l = lhead;
  214.     }
  215. else {
  216.     if ( (l->prev->next = l->next) != NULL)
  217.         l->next->prev = l->prev;
  218.     l = l->next;
  219.     }
  220. free(t);
  221. nlegal--;
  222. return(l);
  223. }
  224.  
  225.  
  226. extractmvs(l,m)
  227. struct legal *l;
  228. struct mv *m;
  229. {
  230. int i, n, s;
  231. struct mv tmp;
  232.  
  233. clearmvs(m);
  234. for (i = 0; i <= l->nmove; i++)        /* extract the moves */
  235.     m[i] = l->mvs[i];
  236. n = l->nmove;
  237. do {            /* sort by increasing roll then increasing point */
  238.     s = 0;
  239.     for (i = 0; i < n; i++) {        /* long live bubblesort */
  240.         if (m[i].roll < m[i+1].roll)
  241.             continue;
  242.         else if ( (m[i].roll == m[i+1].roll) && (m[i].pt < m[i+1].pt) )
  243.             continue;
  244.         tmp = m[i];
  245.         m[i] = m[i+1];
  246.         m[i+1] = tmp;
  247.         s = 1;
  248.         }
  249.     n--;
  250.     } while (s);
  251. }
  252.  
  253.  
  254. checkused(g)
  255. struct game *g;
  256. {
  257. int h, i;
  258.  
  259. h = 0;
  260. for (i = 0; i <= g->maxused; i++) {
  261.     if (g->mvs[i].pt < 0) {
  262.         FeMessage("You left a roll unused.");
  263.         return(1);
  264.         }
  265.     if (h < g->mvs[i].roll)
  266.         h = g->mvs[i].roll;
  267.     }
  268. if (g->hiused > h) {
  269.     FeMessage("You can use the higher roll.");
  270.     return(1);
  271.     }
  272. return(0);
  273. }
  274.