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

  1. /*    move.c        8/5/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.  *    apply -- apply a move to a board
  20.  *
  21.  * Apply applies a move to a board, detecting the following errors:
  22.  *    RJ_NOROLL    The mv struct did not contain a valid roll.
  23.  *    RJ_ONBAR    The move attempted to move from a point other than
  24.  *            the bar when pieces are on the bar.
  25.  *    RJ_NOOFF    The move attempted to move pieces off before all
  26.  *            pieces are in the inner table.
  27.  *    RJ_NOPIECE    The move attempted to take a piece from an empty point.
  28.  *    RJ_NOTYOURS    The move attempted to move the opponent's piece.
  29.  *    RJ_OCC        The move attempted to move to an occupied point.
  30.  *    RJ_EXACT    The move attempted to bear off a piece with a
  31.  *            larger roll than necessary when that piece was
  32.  *            not the outermost piece.
  33.  * If the move was legal, apply returns:
  34.  *    MVOK        if no blot was hit, or
  35.  *    point number    where the blot was before it was hit.
  36.  * Note that blot numbers are in the range [1-24], MVOK is 0, and
  37.  * the reject codes are negative.  When the move is rejected,
  38.  * the board is unchanged.  When a blot is hit, it is moved to the
  39.  * appropriate bar point automatically.
  40.  *
  41.  * If A_REDRAW is set in flags, apply redraws the relevant portions of
  42.  * the screen to reflect the move.  If A_CHKONLY is set in flags, the
  43.  * move is checked but the board is not modified.
  44.  *-----------------------------------------------------------------------
  45.  */
  46.  
  47. apply(g,who,mn,flags,dest)
  48. struct game *g;            /* game structure */
  49. int who;            /* 0 = opponent, 1 = me */
  50. int mn;                /* which element of mv array */
  51. int flags;            /* A_* */
  52. int *dest;            /* where to store destination point */
  53. {
  54. int i, j, blot;
  55. int op, np;
  56. int dir;
  57. char clr;
  58. struct mv *m;
  59. register struct point *b = g->board;
  60.  
  61. dir = who ? g->mydir : g->opdir;
  62. clr = who ? g->mycolor : g->opcolor;
  63. blot = MVOK;            /* no blot hit yet */
  64. m = who ? &g->mvs[mn] : &g->opmvs[mn];
  65. if (m->roll <= 0)        /* sanity check */
  66.     return(RJ_NOROLL);    /* reject move */
  67. op = m->pt;        /* starting point number */
  68. if (op < 0)        /* this roll is unused */
  69.     return(MVOK);    /* and that's ok */
  70. if ( (op == 0) || (op == 25) )    /* moving off bar */
  71.     op = BARPT(dir);    /* use correct bar point */
  72. else {            /* not moving off bar */
  73.     j = BARPT(dir);    /* make sure no pieces still on bar */
  74.     if (b[j].qty > 0)
  75.         return(RJ_ONBAR);    /* can't move, pieces on bar */
  76.     }
  77. np = op + m->roll*dir;    /* move piece correct number of pts */
  78. if ( (np <= 0) || (np >= 25) ) {
  79.     i = (dir > 0) ? 19 : 1;
  80.     j = (dir > 0) ? 24 : 6;
  81.     if (addpcs(b,clr,i,j)+b[OFFPT(dir)].qty < 15) /* all pcs not */
  82.         return(RJ_NOOFF);    /* in inner table, can't move off */
  83.     if ( (np != 0) && (np != 25) ) {/* using bigger roll than needed */
  84.         i = (dir > 0) ? 19   : op+1; /* check for pcs on higher pts */
  85.         j = (dir > 0) ? op-1 : 6;
  86.         if (addpcs(b,clr,i,j) > 0)    /* there are some */
  87.             return(RJ_EXACT);    /* must use roll on them */
  88.         }
  89.     np = OFFPT(dir);    /* this piece is moving off */
  90.     }
  91. if (b[op].qty <= 0)        /* no piece here to move */
  92.     return(RJ_NOPIECE);
  93. if (b[op].color != clr)    /* trying to move opponent's pieces? */
  94.     return(RJ_NOTYOURS);
  95. if (b[np].qty == 0)        /* moving to an empty point */
  96.     b[np].color = b[op].color;    /* copy color */
  97. if (b[np].color != b[op].color) {    /* moving to occupied pt */
  98.     if (b[np].qty == 1) {        /* whacked a blot */
  99.         blot = np;        /* save point number for return */
  100.         if ( (flags & A_CHKONLY) == 0) {
  101.             b[np].qty = 0;        /* bye bye */
  102.             j = BARPT(REV(dir));    /* send it to opponents bar */
  103.             b[j].color = b[np].color; /* copy color to bar pt */
  104.             b[j].qty++;        /* bump counter */
  105.             if (flags & A_REDRAW)    /* update screen */
  106.                 FeDrawPoint(b,j,0,g->flags & F_INVERT);
  107.             b[np].color = b[op].color;    /* my point now */
  108.             }
  109.         }
  110.     else
  111.         return(RJ_OCC);        /* point is occupied */
  112.     }
  113. if ( (flags & A_CHKONLY) == 0) {
  114.     b[op].qty--;                /* take piece from old pt */
  115.     b[np].qty++;                /* and put in on new pt */
  116.     if (flags & A_REDRAW) {
  117.         FeDrawPoint(b,op,0,g->flags & F_INVERT);/* update the screen */
  118.         FeDrawPoint(b,np,0,g->flags & F_INVERT);
  119.         }
  120.     }
  121. if (dest != NULL)            /* return new position */
  122.     *dest = np;
  123. return(blot);                /* succeeded, return MVOK or blot */
  124. }
  125.  
  126.  
  127. /*----------------------------------------------------------------------
  128.  *    addpcs -- add the number of pieces in a range of points
  129.  *
  130.  * This function returns the number of pieces of a certain color
  131.  * that reside within a range of points.
  132.  *----------------------------------------------------------------------
  133.  */
  134.  
  135. addpcs(b,clr,f,t)
  136. board b;
  137. char clr;
  138. int f, t;
  139. {
  140. int i, q;
  141.  
  142. q = 0;                /* quantity we have found so far */
  143. for (i = f; i <= t; i++)
  144.     if (b[i].color == clr)    /* found some */
  145.         q += b[i].qty;    /* count them */
  146. return(q);            /* return quantity found */
  147. }
  148.