home *** CD-ROM | disk | FTP | other *** search
Text File | 1986-09-06 | 6.4 KB | 224 lines | [TEXT/MACA] |
- /*
- * move.c - support for Tablut game moves.
- */
- #include <quickdraw.h>
- #include <window.h>
- #include <memory.h>
- #include "tablut.h"
-
- /*
- * movepiece() - attempt to move the given piece to the given grid location.
- * Check the legality of the move;
- * if the move is illegal, put the piece back where it was...
- * otherwise, move the piece, record the move, and do any captures.
- * NOTE: in setup mode almost all moves are legal,
- * no moves are recorded, and no captures are made.
- */
- movepiece(pidx, togridp)
- int pidx; /* index of the piece to try to move */
- Point *togridp; /* grid coords to try to move to */
- {
- struct pieceimage *p;
-
- p = &piece[pidx];
- if (!islegal(pidx, togridp)) { /* illegal move -- put it back */
- if (!onboard(p)) removepiece(pidx);
- else placepiece(pidx, p->grid.h, p->grid.v);
- } else {
- if (togridp->h == NOGRID) removepiece(pidx);
- else placepiece(pidx, togridp->h, togridp->v);
- if (!insetup) {
- seecaptures(pidx); seeraichi(); writeboard();
- }
- }
- }
-
- /*
- * islegal() - given a piece and a place to move it, islegal returns 1
- * if that move is legal; 0 otherwise.
- * NOTE: this routine assumes that findpiece() and dragpiece() have
- * weeded out a large set of possible illegal moves. Islegal() only
- * has to weed out the moves that they can't.
- */
- int
- islegal(pidx, togridp)
- int pidx; /* index of the piece to try to move */
- Point *togridp; /* grid coords to try to move to */
- {
- struct pieceimage *p;
-
- p = &piece[pidx];
- if (togridp->h == NOGRID) {
- return(insetup); /* moving off-board is legal only in setup */
- }
- if (EqualPt(pass(p->grid), pass(*togridp))) {
- return(0); /* already there -- that's no move */
- }
- if (togridp->h == 0 && togridp->v == 0 && p != &piece[THEKING]) {
- return(0); /* only the king can occupy the throne */
- }
- if ((*gridp)[togridp->h][togridp->v]) {
- return(0); /* can't move to an occupied square */
- }
- return(1);
- }
-
- /*
- * seecaptures() - examine the board for captures that were caused by
- * moving the given piece.
- */
- seecaptures(pidx)
- int pidx; /* index of the moved piece */
- {
- struct pieceimage *p; /* pointer to the moved piece */
- short kh, kv; /* grid coords of the king */
- short h, v;
-
- p = &piece[pidx];
- h = p->grid.h; v = p->grid.v;
- trycapture((*gridp)[h-2][v], (*gridp)[h-1][v], (*gridp)[h][v]);
- trycapture((*gridp)[h][v-2], (*gridp)[h][v-1], (*gridp)[h][v]);
- trycapture((*gridp)[h+2][v], (*gridp)[h+1][v], (*gridp)[h][v]);
- trycapture((*gridp)[h][v+2], (*gridp)[h][v+1], (*gridp)[h][v]);
- if (onboard(&piece[THEKING])) {
- /*
- * The king is captured if there is a circle
- * of muscovites (or the throne) surrounding the king
- * and the circle was completed by the current move.
- */
- kh = piece[THEKING].grid.h; kv = piece[THEKING].grid.v;
- if (kingdanger(kh-1, kv) && kingdanger(kh, kv-1) &&
- kingdanger(kh+1, kv) && kingdanger(kh, kv+1)) {
- if ((*gridp)[kh-1][kv] == p || (*gridp)[kh][kv-1] == p ||
- (*gridp)[kh+1][kv] == p || (*gridp)[kh][kv+1] == p) {
- winner = BLACKWIN;
- blinksquares(&(piece[THEKING].grid),
- &(piece[THEKING].grid));
- }
- }
- }
- }
-
- /*
- * trycapture() - given three adjacent pieces (or nothing) see if the
- * middle swede or muscovite (but not the swedish king) can be captured.
- * If it can, remove it from the board.
- */
- trycapture(pl, pc, pr)
- struct pieceimage *pl, *pc, *pr; /* adjacent pieces to check */
- {
- if (!pl || !pc || !pr) return;
- if (whitepiece(pl) && blackpiece(pc) && whitepiece(pr)) {
- removepiece((int)(pc - &piece[0])); return;
- }
- if (blackpiece(pl) && classbase(pc) == FIRSTSWEDE && blackpiece(pr)) {
- removepiece((int)(pc - &piece[0])); return;
- }
- }
-
- /*
- * kingdanger() - given grid coords of a position, see if there is direct
- * danger to the king from that square -- I.E., see if that square is the
- * throne or if it contains a black piece.
- */
- int
- kingdanger(h, v)
- short h,v; /* coords to check */
- {
- if (h == 0 && v == 0) return(1);
- if ((*gridp)[h][v] && blackpiece((*gridp)[h][v])) return(1);
- return(0);
- }
-
- /*
- * seeraichi() - see if there is a Raichi or Tuichi
- */
- seeraichi()
- {
- Point minloc, maxloc; /* bounds of the king's movement */
- Point raichis[4]; /* storage for raichi moves */
- Point *rp; /* points to the next free raichi slot */
- Point kingloc; /* the king's current grid coordinates */
- int numraichis; /* number of raichis */
- int blockable; /* "all raichis can be blocked" */
-
- blockable = 1;
- if (!onboard(&piece[THEKING])) return;
- findbounds(THEKING, &minloc, &maxloc);
- kingloc.h = piece[THEKING].grid.h; kingloc.v = piece[THEKING].grid.v;
- rp = &raichis[0];
- if (minloc.h == -4) {
- SetPt(rp++, -4, kingloc.v);
- blockable &= vblock(kingloc.v, -4, kingloc.h - 1);
- }
- if (minloc.v == -4) {
- SetPt(rp++, kingloc.h, -4);
- blockable &= hblock(kingloc.h, -4, kingloc.v - 1);
- }
- if (maxloc.h == 4) {
- SetPt(rp++, 4, kingloc.v);
- blockable &= vblock(kingloc.v, kingloc.h + 1, 4);
- }
- if (maxloc.v == 4) {
- SetPt(rp++, kingloc.h, 4);
- blockable &= hblock(kingloc.h, kingloc.v + 1, 4);
- }
- numraichis = (int)(rp - &raichis[0]);
- if (numraichis >= 1) blinksquares(&raichis[0], rp - 1);
- if (numraichis >= 2 || !blockable || (blacksmove() && numraichis >= 1)) {
- winner = WHITEWIN;
- }
- }
-
- /*
- * vblock(), hblock() - see if the given row (or column) can be blocked by
- * a black piece. This routine is used to see if a Raichi is blockable.
- */
- int
- vblock(kv, fromh, toh)
- short kv; /* the row to be examined (the king's row) */
- short fromh, toh; /* the bounds of the part to be blocked */
- {
- short h,v; /* grid square being examined for a piece */
-
- for (h = fromh; h <= toh; ++h) {
- for (v = kv - 1; v >= -4; --v) {
- if ((*gridp)[h][v]) {
- if (blackpiece((*gridp)[h][v])) return(1);
- else break;
- }
- }
- for (v = kv + 1; v <= 4; ++v) {
- if ((*gridp)[h][v]) {
- if (blackpiece((*gridp)[h][v])) return(1);
- else break;
- }
- }
- }
- return(0);
- }
-
- int
- hblock(kh, fromv, tov)
- short kh; /* the col to be examined (the king's col) */
- short fromv, tov; /* the bounds of the part to be blocked */
- {
- short h,v; /* grid square being examined for a piece */
-
- for (v = fromv; v <= tov; ++v) {
- for (h = kh - 1; h >= -4; --h) {
- if ((*gridp)[h][v]) {
- if (blackpiece((*gridp)[h][v])) return(1);
- else break;
- }
- }
- for (h = kh + 1; h <= 4; ++h) {
- if ((*gridp)[h][v]) {
- if (blackpiece((*gridp)[h][v])) return(1);
- else break;
- }
- }
- }
- return(0);
- }
-