home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 240_01 / bg3.c < prev    next >
Text File  |  1987-07-30  |  26KB  |  840 lines

  1.  
  2. /*
  3. **  bg3.c -- gameplan
  4. */
  5.  
  6. #include "backgmmn.h"
  7.  
  8.  
  9. /*=============================================*/
  10. /*     M Y   M O V E                           */
  11. /*=============================================*/
  12.  
  13.  
  14. static naked() {  /* am I leaving too many blots? */
  15. static int i, clink;
  16.      i = 24;  clink = 0;
  17.      while (i) {
  18.           if (point[i].stones == 1 && point[i].owner == ME) clink++;
  19.           i--;
  20.      }
  21.      return (clink > 2);
  22. } /* end: naked */
  23.  
  24.  
  25. static yourfolly() { /* look for lotsa blots in your inner table */
  26. static int i, clink;
  27.      i = 18; clink = 0;
  28.      while (i < 25) {
  29.           if (point[i].owner == YU && point[i].stones == 1) 
  30.                clink++; 
  31.           i++;
  32.      }
  33.      return (clink >= 3);
  34. } /* end: yourfolly */
  35.  
  36.  
  37. static goodboard() { /* look for four made points near my inner table */
  38. static int i, clank, clink;
  39.      i = 9; clank = 0;
  40.      while (i > 3) {
  41.           if (point[i].owner == ME && point[i].stones > 1) clank++;
  42.           i--;
  43.      }
  44.      if (clank > 4) return (TRUE);  /* bar is nearly blocked */
  45.  
  46.      i = 6; clank = clink = 0;
  47.      while (i) {
  48.           if (point[i].owner != ME) 
  49.                ;
  50.           else if (point[i].stones == 1) clink++; else clank++;
  51.           i--;
  52.      }
  53.      return (clank > 3 && clink < 2);
  54. } /* end: goodboard */
  55.  
  56.  
  57. static scanahead( from ) int from; {
  58. static int count;
  59.  
  60.      count = 0;
  61.      while (--from > 0) {
  62.           ++count;
  63.           if ( point[ from ].owner == YU ) return (count);
  64.      }
  65.      return (7);
  66.  
  67. } /* end: scanahead */
  68.  
  69.  
  70.  
  71.  
  72. /*------------------------------------------------------------*/
  73. /* MATCHUP                                                    */
  74. /*                                                            */
  75. /* 2-stone functions that force the choice of the next move.  */
  76. /* These are the HEART and SOUL of this backgammon algorithm! */
  77. /*------------------------------------------------------------*/
  78.  
  79. static setpend( from, to ) int from, to; {
  80.      pending.fr   = from;
  81.      pending.to   = to;
  82.      pending.flag = TRUE;
  83. } /* end: setpend */
  84.  
  85.  
  86. static natural(f1,t1,f2,t2) int f1,t1,f2,t2; {
  87.      clrpend();
  88.      if (point[t2].stones == 1 && t1 == f2) setpend(f2,t2);
  89.      return (pending.flag);
  90. } /* end: natural */
  91.  
  92.  
  93. static matchup( test4 ) int (* test4)(); {
  94. static int i, j, ti, tj;
  95.  
  96.      if ( pending.flag ) return (FALSE); /* this is probably redundant */
  97.  
  98.      for (i = 1; i < 26; i++) {
  99.           ti = list[0][i];
  100.           if ( ti == ERROR ) goto zoo;
  101.           for (j = 1; j < 26; j++) {
  102.                tj = list[1][j];
  103.                if ( tj == ERROR ) goto voo;
  104.                if ( (* test4)( i, ti, j, tj ) ) {
  105.                     lurch( i, ti, 0);
  106.                     return (TRUE);
  107.                }
  108.              voo: ;
  109.           }
  110.         zoo: ;
  111.      }
  112.      return (FALSE);
  113.  
  114. } /* end: matchup */
  115.  
  116.  
  117. static matchhi( test4 ) int (* test4)(); {
  118. static int i, j, ti, tj;
  119.  
  120.      if ( pending.flag ) return (FALSE); /* this is probably redundant */
  121.  
  122.      for (i = 1; i < 26; i++) {
  123.           ti = list[1][i];
  124.           if ( ti == ERROR ) goto zoo;
  125.           for (j = 1; j < 26; j++) {
  126.                tj = list[0][j];
  127.                if ( tj == ERROR ) goto voo;
  128.                if ( (* test4)( i, ti, j, tj ) ) {
  129.                     lurch( i, ti, 1);
  130.                     return (TRUE);
  131.                }
  132.              voo: ;
  133.           }
  134.         zoo: ;
  135.      }
  136.      return (FALSE);
  137.  
  138. } /* end: matchhi */
  139.  
  140.  
  141.  
  142. /*--------------------------------------------------------*/
  143. /* CLOCKWISE and COUNTERCLOCK                             */
  144. /*                                                        */
  145. /* the rest of these are single-stone decisions based on  */
  146. /* rules of thumb, board-scanning functions               */
  147. /*--------------------------------------------------------*/
  148.  
  149. static plainstupid( from ) int from; { /* don't break a safe point */
  150.      return (from < 13 && (point[from].stones == 2 && scanahead(from) < 7));
  151. } /* end: plainstupid */
  152.  
  153.  
  154. static unwise( innertablept ) int innertablept; {
  155.      /* if it's a hit, just for god's sake don't put him on the bar!! */
  156.      if ( innertablept < 7 ) {
  157.           if (point[ innertablept ].owner == YU ||
  158.               point[ YRBAR ].stones > 0) 
  159.                return (TRUE);
  160.      }
  161.      return(FALSE);
  162. } /* end: unwise */
  163.  
  164.  
  165.  
  166. static covermine( from, to ) int from, to; {
  167.      if ( from < 8 ) return(FALSE);
  168.      return ( (point[ to ].stones == 1) && (point[ to ].owner == ME) );
  169. } /* end: covermine */
  170.  
  171.  
  172. static idareyou( from, to ) int from, to; {
  173.      if (unwise( to )) return (FALSE);
  174.      if ( (point[ from ].stones != 2)
  175.           && (point[ to ].stones < 2)
  176.           && (scanahead( to ) > 6) ) return ( TRUE );
  177.      else return (FALSE);
  178. } /* end: idareyou */
  179.  
  180.  
  181. static hitandrun( from, to ) int from, to; {
  182.      return ( point[ to ].owner == YU );
  183. } /* end: hitandrun */
  184.  
  185.  
  186. static dbuild( from, to ) int from, to; {
  187. static int diceleft;
  188.      diceleft = (myturns? 2 + movesleft: movesleft);
  189.      if (diceleft > 1) {
  190.           /* can't possibly be only one stone on from point */
  191.           /* or kamikaze would have covered it on last move */
  192.           return ( point[to].stones == 0 );
  193.      }
  194.      return (FALSE);
  195. } /* end: dbuild */
  196.  
  197.  
  198. static kamikaze( from, to ) int from, to; { 
  199. /* cover my distant blot, or razzle-dazzle 'em with the long doubles hit */
  200. static int j, k, diceleft;
  201.      
  202.      k = from; 
  203.      j = from - to;
  204.      diceleft = myturns * movesleft;  /* NB: 2*2 == 2+2, "fourtunately" */
  205.      while ( diceleft-- ) {   /* predicting where doubles land is easy! */
  206.           k -= j;
  207.           if (k < 1) return (FALSE); /* out of bounds */
  208.           if ( point[ k ].stones == 0 ) continue;        /* simplify */
  209.           if ( point[ k ].stones == 1 )   /* found my blot or yours? */
  210.                return (TRUE);
  211.           else if ( point[k].owner == YU )   /* found your blockade? */
  212.                return (FALSE); 
  213.           else continue;        /* found my safe point, so ignore it */
  214.      }
  215.      return (FALSE);
  216.  
  217. } /* end: kamikaze */
  218.  
  219.  
  220. static hittite( from, to ) int from, to; {
  221.      return (hitandrun(from,to) && to > 9);
  222. } /* end: hittite */
  223.  
  224.  
  225. static safehit( from, to ) int from, to; {
  226.      return (hittite(from,to) && idareyou(from,to));
  227. } /* end: safehit */
  228.  
  229.  
  230. static foolsdemise( from, to ) int from, to; { 
  231.         /* annihilate orphaned blots in enemy's inner, my outer table */
  232.      return (to > 17 && point[to].owner == YU);
  233. } /* end: foolsdemise */
  234.  
  235.  
  236. static landonme( from, to ) int from, to; {
  237.      if ( plainstupid(from) ) return (FALSE);
  238.      if ( loneranger(from,to) ) {
  239.           if (from < 19 && to > 6) return(TRUE);
  240.      }
  241.      else return ( point[ to ].owner == ME && point[to].stones < 4);
  242. } /* end: landonme */
  243.  
  244.  
  245.  
  246. /* these evaluations have meaning only in the endgame */
  247.  
  248.  
  249. static nobackgammon( from, to ) int from, to; { /* endgame */
  250.      return (from > 19);
  251. } /* end: nobackgammon */
  252.  
  253.  
  254. static crosstable( from, to ) int from, to; { 
  255.      /* always move a table ahead if possible, in the endgame */
  256.      if (from < 7) return (FALSE);
  257.      if (from > 18 && to <= 18) return (TRUE);
  258.      if (from > 12 && to <= 12) return (TRUE);
  259.      if (from >  6 && to <=  6) return (TRUE);
  260.      return (FALSE);
  261. } /* end: crosstable */
  262.  
  263.  
  264. static fiftytworule( from, to ) int from, to; { /* endgame */
  265. static int p;
  266.      if (from < 7) return (FALSE);   /* not in inner table! */
  267.      p = from % 6;
  268.      if (p == 0) return (TRUE);            /* improve the six */
  269.      if (p != 5) return ( (to % 6) < 3 );    /* best improve under five */
  270. } /*  end: fiftytworule */
  271.  
  272.  
  273.  
  274.  
  275. /* these evaluations are universally applicable, last resort moves */
  276.  
  277.  
  278. static gohome( from, to ) int from, to; { /* always go home if you can */
  279.      return (to == MYHOME);
  280. } /* end: gohome */
  281.  
  282.  
  283. static scatter( from, to ) int from, to; {  /* scatter, esp. in the endgame */
  284.      if (plainstupid(from) || unwise(to)) return (FALSE);
  285.      return ( point[ from ].stones > 1 && point[ to ].stones == 0 );
  286. } /* end: scatter */
  287.  
  288.  
  289. static runnerup( from, to ) int from, to; {
  290.      if (from < 10 || from > 18) return (FALSE);
  291.      return (TRUE);
  292. } /* end: runnerup */
  293.  
  294.  
  295. static loneranger( from, to ) int from, to; {
  296.      return( point[ from ].stones == 1 );
  297. } /* end: loneranger */
  298.  
  299.  
  300. static run( dummy1, dummy2 ) int dummy1, dummy2; { /* MUST move something! */
  301.      return (TRUE);
  302. } /* end: run */
  303.  
  304.  
  305.  
  306.  
  307.  
  308. /* clockwise and counterclock make a 1-stone choice on rules of thumb */
  309.  
  310.  
  311. static counterclock( test ) int (* test)(); {
  312. static int i,j;
  313.  
  314.      for (i = 0; i < 2; i++) {
  315.           for (j = 1; j < 25; j++) {
  316.                if ( list[i][j] == ERROR ) continue;
  317.                if ( (* test)( j, list[i][j] ) ) {
  318.                     lurch( j, list[i][j], i);
  319.                     return ( TRUE );
  320.      }     }     }
  321.      return (FALSE);
  322.  
  323. } /* end: counterclock */
  324.  
  325.  
  326. static clockwise( test ) int (* test)(); {
  327. static int i,j;
  328.  
  329.      for (i = 0; i < 2; i++) {
  330.           for (j = 25; j > 0; j--) {
  331.                if ( list[i][j] == ERROR ) continue;
  332.                if ( (* test)( j, list[i][j] ) ) {
  333.                     lurch( j, list[i][j], i);
  334.                     return ( TRUE );
  335.      }     }     }
  336.      return (FALSE);
  337.  
  338. } /* end: clockwise */
  339.  
  340.  
  341.  
  342.  
  343.  
  344. /*-------------------------------------------*/
  345. /*  Make Prime                               */
  346. /*-------------------------------------------*/
  347.  
  348. static int prmchk;
  349.  
  350.  
  351. static buildprime( f1,t1,f2,t2 ) int f1,t1,f2,t2; {
  352.      clrpend();
  353.      /* check for the doubles bug */
  354.      if ((dice[0] == dice[1]) && (point[f1].stones < 2)) return(FALSE);
  355.  
  356.      /* look for the combination */
  357.      if ( t1 == prmchk && t2 == prmchk) setpend(f2,t2);
  358.  
  359.      /* stick like glue to a made point, but doubles may move forward */
  360.      if (dice[0] != dice[1]) { 
  361.           if ((f2 < 8) && (point[f2].stones == 2)) clrpend();
  362.           if ((f1 < 8) && (point[f1].stones == 2)) clrpend();
  363.      }
  364.  
  365.      return(pending.flag);
  366.  
  367. } /* end: buildprime */
  368.  
  369.  
  370. static makeprime() {
  371. static int i, tab[] = { ERROR,1,2,3,20,22,24,9,4,6,8,5,7 };
  372.      i = 12;
  373.      while (i) {
  374.           prmchk = tab[i]; 
  375.           i--;
  376.           if ( point[ prmchk ].stones > 1 ) continue;
  377.           else if ( matchup( buildprime ) ) return(TRUE);
  378.      }
  379.      return(FALSE);
  380. } /* end: makeprime */
  381.  
  382.  
  383. static coverprime( from, to ) int from, to; {
  384.      return (((to == prmchk) && 
  385.           (point[prmchk].owner == ME)) &&
  386.           (point[from].stones != 2));
  387. } /* coverprime */
  388.  
  389.  
  390. static cleanup() {
  391. static int i, tab[] = { ERROR,1,2,3,20,22,24,9,4,6,8,5,7 };
  392.      i = 12;
  393.      while (i) {
  394.           prmchk = tab[i]; 
  395.           i--;
  396.           if ( point[ prmchk ].stones != 1 ) continue;
  397.           else if ( counterclock( coverprime ) ) return(TRUE);
  398.      }
  399.      return(FALSE);
  400. } /* end: cleanup */
  401.  
  402.  
  403. /*-------------------------------------*/
  404. /* Walking Prime                       */
  405. /*-------------------------------------*/
  406.  
  407. static swivelhips( from, to ) int from, to; {
  408.      return ( from > prmchk );
  409. } /* end: swivelhips */
  410.  
  411.  
  412. static slink( from, to ) int from, to; {
  413.      return( (from > prmchk) && (point[to].stones == 1) );
  414. } /* end: slink */
  415.  
  416.  
  417. static weasel() {
  418.      if ( clockwise( slink ) )
  419.           return(TRUE);
  420.      if ( counterclock( swivelhips ) ) 
  421.           return(TRUE);
  422.      if ( clockwise( run ) )
  423.           return(TRUE);
  424. } /* end: weasel */
  425.  
  426. static ihaveprime( from )  int from; {
  427. static int i, to, ez;
  428.      ez = 0;
  429.      for (i = 0; i < 6; i++) {
  430.           to = from - i;
  431.           if ((point[to].owner == ME) && (point[to].stones > 1)) ez++;
  432.      }
  433.      return (ez > 4);
  434. } /* end: ihaveprime */
  435.  
  436.  
  437. static walkingprime() { 
  438. /* looks for the walking prime anywhere in the front tables */
  439. /* then tries to bring up a runner from behind the prime,   */
  440. /* ensuring that a back stone WILL move before a front one  */
  441. static int i;
  442.      i = 12;
  443.      while (i > 5) {
  444.           if ( ihaveprime(i) ) {
  445.                prmchk = i;
  446.                if ( weasel() ) return (TRUE);
  447.           }
  448.           i--;
  449.      }
  450.      return(FALSE);
  451. } /* end: walkingprime */
  452.  
  453.  
  454. /*---------- Book Moves ----------*/
  455. /* only valid if my move is first */
  456. /*--------------------------------*/
  457.  
  458. static zip(a,b,c,d) int a,b,c,d; {
  459.      lurch(a,b,0);
  460.      lurch(c,d,0);
  461.      movesleft = 0; return( TRUE );
  462. } /* end: zip */
  463.  
  464.  
  465. static zoom( a,b,c,d,e,f,g,h ) int a,b,c,d,e,f,g,h; {
  466.      myturns = 0; zip(a,b,c,d); zip(e,f,g,h); return( TRUE );
  467. } /* end: zoom */
  468.  
  469.  
  470. static book() {
  471. int a,b;
  472.      if (!firstmove) return (FALSE);
  473.      firstmove = FALSE;
  474.      a = min(dice[0],dice[1]);
  475.      b = max(dice[0],dice[1]);
  476.      switch (level) {
  477.           case 0: { return ( book0(a,b) ); break; }
  478.           case 1: { return ( book1(a,b) ); break; }
  479.           case 2: { return ( book2(a,b) ); break; }
  480.      }
  481. }
  482.  
  483. static book0( a,b ) int a, b; { 
  484.      switch (a) {
  485.           case 1: { switch (b) {
  486.                     case 1: return ( zoom(8,7,8,7,6,5,6,5) );
  487.                     case 2: return ( zip(24,23,13,11) );
  488.                     case 3: return ( zip(8,5,6,5) );
  489.                     case 4: return ( zip(24,23,13,9) );
  490.                     case 5: return ( zip(24,23,13,8) );
  491.                     case 6: return ( zip(13,7,8,7) );
  492.                  }
  493.                break; }
  494.           case 2: { switch (b) {
  495.                     case 2: return ( zoom(6,4,6,4,13,11,13,11) );
  496.                     case 3: return ( zip(13,11,13,10) );
  497.                     case 4: return ( zip(8,4,6,4) );
  498.                     case 5: return ( zip(13,8,13,11) );
  499.                     case 6: return ( zip(24,18,13,11) );
  500.                  }
  501.                break; }
  502.           case 3: { switch (b) {
  503.                     case 3: return ( zoom(13,10,13,10,10,7,10,7) );
  504.                     case 4: return ( zip(13,10,13,9) );
  505.                     case 5: return ( zip(13,10,13,8) );
  506.                     case 6: return ( zip(24,18,13,10) );
  507.                  }
  508.                break; }
  509.           case 4: { switch (b) {
  510.                     case 4: return ( zoom(13,9,13,9,24,20,24,20) );
  511.                     case 5: return ( zip(13,8,13,9) );
  512.                     case 6: return ( zip(24,18,18,14) );
  513.                  }
  514.                break; }
  515.           case 5: { switch (b) {
  516.                     case 5: return ( zoom(13,8,13,8,8,3,8,3) );
  517.                     case 6: return ( zip(24,18,18,13) );
  518.                  }
  519.                break; }
  520.           case 6: { return ( zoom(13,7,13,7,24,18,24,18) );
  521.                break; }
  522.      }
  523.  
  524. } /* end: book0 */
  525.  
  526. static book1( a,b ) int a, b; { /* mostly follows Becker */
  527.      switch (a) {
  528.           case 1: { switch (b) {
  529.                     case 1: return ( zoom(8,7,8,7,6,5,6,5) );
  530.                     case 2: return ( zip(13,11,6,5) );
  531.                     case 3: return ( zip(8,5,6,5) );
  532.                     case 4: return ( zip(13,9,6,5) );
  533.                     case 5: return ( zip(13,8,6,5) );
  534.                     case 6: return ( zip(13,7,8,7) );
  535.                  }
  536.                break; }
  537.           case 2: { switch (b) {
  538.                     case 2: return ( zoom(6,4,6,4,13,11,13,11) );
  539.                     case 3: return ( zip(13,11,13,10) );
  540.                     case 4: return ( zip(8,4,6,4) );
  541.                     case 5: return ( zip(13,8,13,11) );
  542.                     case 6: return ( zip(13,7,7,5) );
  543.                  }
  544.                break; }
  545.           case 3: { switch (b) {
  546.                     case 3: return ( zoom(13,10,13,10,8,5,8,5) );
  547.                     case 4: return ( zip(13,10,13,9) );
  548.                     case 5: return ( zip(13,8,8,5) );
  549.                     case 6: return ( zip(13,7,13,10) );
  550.                  }
  551.                break; }
  552.           case 4: { switch (b) {
  553.                     case 4: return ( zoom(13,9,13,9,9,5,9,5) );
  554.                     case 5: return ( zip(13,8,13,9) );
  555.                     case 6: return ( zip(13,7,13,9) );
  556.                  }
  557.                break; }
  558.           case 5: { switch (b) {
  559.                     case 5: return ( zoom(13,8,13,8,8,3,8,3) );
  560.                     case 6: return ( zip(13,7,13,8) );
  561.                  }
  562.                break; }
  563.           case 6: { return ( zoom(13,7,13,7,24,18,24,18) );
  564.                break; }
  565.      }
  566.  
  567. } /* end: book1 */
  568.  
  569. static book2( a,b ) int a, b; { /* mostly follows Becker */
  570.      switch (a) {
  571.           case 1: { switch (b) {
  572.                     case 1: return ( zoom(8,7,8,7,6,5,6,5) );
  573.                     case 2: return ( zip(13,11,24,23) );
  574.                     case 3: return ( zip(8,5,6,5) );
  575.                     case 4: return ( zip(13,9,24,23) );
  576.                     case 5: return ( zip(13,8,24,23) );
  577.                     case 6: return ( zip(13,7,8,7) );
  578.                  }
  579.                break; }
  580.           case 2: { switch (b) {
  581.                     case 2: return ( zoom(6,4,6,4,24,23,24,23) );
  582.                     case 3: return ( zip(13,11,13,10) );
  583.                     case 4: return ( zip(8,4,6,4) );
  584.                     case 5: return ( zip(13,8,13,11) );
  585.                     case 6: return ( zip(13,7,13,11) );
  586.                  }
  587.                break; }
  588.           case 3: { switch (b) {
  589.                     case 3: return ( zoom(13,10,13,10,10,7,10,7) );
  590.                     case 4: return ( zip(13,10,13,9) );
  591.                     case 5: return ( zip(13,8,8,5) );
  592.                     case 6: return ( zip(13,7,13,10) );
  593.                  }
  594.                break; }
  595.           case 4: { switch (b) {
  596.                     case 4: return ( zoom(13,9,13,9,9,5,9,5) );
  597.                     case 5: return ( zip(13,8,13,9) );
  598.                     case 6: return ( zip(13,7,13,9) );
  599.                  }
  600.                break; }
  601.           case 5: { switch (b) {
  602.                     case 5: return ( zoom(13,8,13,8,8,3,8,3) );
  603.                     case 6: return ( zip(13,7,13,8) );
  604.                  }
  605.                break; }
  606.           case 6: { return ( zoom(13,7,13,7,24,18,24,18) );
  607.                break; }
  608.      }
  609.  
  610. } /* end: book2 */
  611.  
  612.  
  613. /*====== MyMove ======*/
  614.  
  615. static torve() {
  616.      if ( makeprime() ) {  /* this will use doubles, if it can */
  617.                return;
  618.      }
  619.      else if ( walkingprime() ) {  /* i have six prime points, so run!!! */
  620.                return;
  621.      }
  622.      else if ( dice[0] == dice[1] ) {           /* this is too easy! */
  623.           if ( counterclock( kamikaze ) )
  624.                return;
  625.           if ( counterclock( dbuild ) ) /* claim new turf */
  626.                return;
  627.           if ( clockwise( run ) )
  628.                return;
  629.      }
  630.      else if ( cleanup() ) {  /* cover my single blot on prime points */
  631.                return;
  632.      }
  633.      else if ( bearoff() ) { /* I'm ready, but you're in the back game! */
  634.           if ( counterclock( gohome ) )
  635.                return;
  636.           if ( clockwise( run ) )
  637.                return; 
  638.      }
  639.      else {
  640.           if ( clockwise( hitandrun ) )
  641.                return;
  642.           if ( matchup( natural ) )
  643.                return; 
  644.           if ( clockwise( landonme ) )
  645.                return;
  646.           if ( counterclock( runnerup ) )
  647.                return;
  648.           if ( clockwise( scatter ) )
  649.                return;
  650.           if ( clockwise( run ) )
  651.                return;
  652.      }
  653.  
  654. } /* end: torve */
  655.  
  656.  
  657.  
  658. static villiers() {
  659.      if ( makeprime() ) {  /* this will use doubles, if it can */
  660.                return;
  661.      }
  662.      else if ( walkingprime() ) {  /* i have six prime points, so run!!! */
  663.                return;
  664.      }
  665.      else if ( dice[0] == dice[1] ) {           /* this is too easy! */
  666.           if ( counterclock( kamikaze ) )
  667.                return;
  668.           if ( counterclock( dbuild ) ) /* claim new turf */
  669.                return;
  670.           if ( clockwise( run ) )
  671.                return;
  672.      }
  673.      else if ( cleanup() ) {  /* cover my single blot on prime points */
  674.                return;
  675.      }
  676.      else if ( bearoff() ) { /* I'm ready, but you're in the back game! */
  677.           if ( counterclock( gohome ) )
  678.                return;
  679.           if ( clockwise( run ) )
  680.                return; 
  681.      }
  682.      else {                             
  683.           if ( clockwise( foolsdemise ) )
  684.                return;
  685.           if ( clockwise( idareyou ) ) 
  686.                return;
  687.           if ( counterclock( covermine ) )
  688.                return;
  689.           if ( matchup( natural ) )
  690.                return;
  691.           if ( clockwise( landonme ) )
  692.                return;
  693.           if ( clockwise( runnerup ) )
  694.                return;
  695.           if ( clockwise( scatter ) )
  696.                return;
  697.           if ( clockwise( run ) )
  698.                return;
  699.      }
  700.  
  701. } /* end: villiers */
  702.  
  703.  
  704.  
  705. static louisa() {
  706.      if ( makeprime() ) {  /* this will use doubles, if it can */
  707.                return;
  708.      }
  709.      else if ( walkingprime() ) {  /* i have six prime points, so run!!! */
  710.                return;
  711.      }
  712.      else if ( dice[0] == dice[1] ) {           /* this is too easy! */
  713.           if ( counterclock( kamikaze ) )
  714.                return;
  715.           if ( counterclock( dbuild ) ) /* claim new turf */
  716.                return;
  717.           if ( clockwise( run ) )
  718.                return;
  719.      }
  720.      else if ( cleanup() ) {  /* cover my single blot on prime points */
  721.                return;
  722.      }
  723.      else if ( bearoff() ) { /* I'm ready, but you're in the back game! */
  724.           if ( counterclock( gohome ) )
  725.                return;
  726.           if ( clockwise( run ) )
  727.                return; 
  728.      }
  729.      else if ( (!naked() && goodboard()) || yourfolly() ) { 
  730.           if ( clockwise( hitandrun ) )
  731.                return;
  732.           if ( matchup( natural ) )
  733.                return; 
  734.           if ( clockwise( landonme ) )
  735.                return;
  736.           if ( counterclock( runnerup ) )
  737.                return;
  738.           if ( clockwise( scatter ) )
  739.                return;
  740.           if ( clockwise( run ) )
  741.                return;
  742.      }
  743.      else {                             
  744.           if ( clockwise( foolsdemise ) )
  745.                return;
  746.           if ( clockwise( idareyou ) ) 
  747.                return;
  748.           if ( counterclock( covermine ) )
  749.                return;
  750.           if ( matchup( natural ) )
  751.                return;
  752.           if ( clockwise( landonme ) )
  753.                return;
  754.           if ( clockwise( runnerup ) )
  755.                return;
  756.           if ( clockwise( scatter ) )
  757.                return;
  758.           if ( clockwise( run ) )
  759.                return;
  760.      }
  761. } /* end: louisa */
  762.  
  763.  
  764. mymove() {
  765. int i, d;
  766.  
  767.      if ( nomove() ) {
  768.           if (lookforit && (dice[0] != dice[1])) {
  769.                lookforit = FALSE;
  770.                wprintf("\b... ");
  771.                if (tone) { beep(); beep(); }
  772.                switch (level) {
  773.                     case 0: { wprintf("Blocked!");  break; }
  774.                     case 1: { wprintf("Well, no!"); break; }
  775.                     case 2: { wprintf("Thurb!");    break; }
  776.                }
  777.                sleep(1);
  778.                restoreboard();
  779.                update(); 
  780.  
  781.                /* put the high die in list zero */
  782.                d = dice[0]; dice[0] = dice[1]; dice[1] = d;
  783.  
  784.                cantuse = ERROR; movesleft = 2; myturns = 1;
  785.                switch (level) {
  786.                     case 0: { setchat("I move");  break; }
  787.                     case 1: { setchat("Let's try"); break; }
  788.                     case 2: { setchat("Move is"); break; }
  789.                }
  790.                msg(5,22,chatter);
  791.                prmchk = 12;
  792.                weasel();
  793.                /* the rules say, use both dice if you can, or  */
  794.                /* the highest if one or the other but not both */
  795.           }
  796.           else {
  797.                lookforit = TRUE;
  798.                strcat(chatter," and now I'm blocked ");
  799.                myturns = movesleft = 0;
  800.      }     }
  801.      else if ( book() ) {
  802.           return;
  803.      }
  804.      else if ( pending.flag ) {
  805.           lurch( pending.fr, pending.to, 1 );
  806.           clrpend();
  807.      }
  808.      else if ( endgame() ) {
  809.           if ( clockwise( gohome ) )
  810.                return;
  811.           if ( clockwise( nobackgammon ) ) /* no excuse! */
  812.                return;
  813.           if ( clockwise( crosstable ) )
  814.                return;
  815.           if ( clockwise( fiftytworule ) )
  816.                return;
  817.           if ( clockwise( scatter ) )
  818.                return;
  819.           if ( clockwise( run ) ) 
  820.                return;
  821.      }
  822.      else if ( point[ MYBAR ].stones > 0 ) {         /* I'm on the bar! */
  823.           if ( clockwise( hitandrun ) )       /* wreak havoc, please */
  824.                return;
  825.           if ( clockwise( run ) )     /* note: uses low die first */
  826.                return;
  827.      }
  828.      else switch (level) {
  829.           case 0: { villiers(); break; }
  830.           case 1: { louisa(); break; }
  831.           case 2: { torve(); break; }
  832.      }
  833.  
  834.  
  835. } /* end: mymove */
  836.  
  837.  
  838. /* eof: bg3.c */
  839.  
  840.