home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** File: notation.c
- ** Written by: Eric Soldan
- **
- ** Copyright © 1990-1992 Apple Computer, Inc.
- ** All rights reserved. */
-
-
-
- /*****************************************************************************/
-
-
-
- #include "Kibitz.h" /* Get the Kibitz includes/typedefs, etc. */
- #include "KibitzCommon.h" /* Get the stuff in common with rez. */
- #include "Kibitz.protos" /* Get the prototypes for Kibitz. */
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __TEXTEDITCONTROL__
- #include <TextEditControl.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __UTILITIES__
- #include <Utilities.h>
- #endif
-
- extern GameListHndl gGenMovesHndl;
- extern Boolean gDescriptive;
-
- static Boolean Descriptive(FileRecHndl frHndl, short doMoveNum, short gameIndex, StringPtr pstr);
- static Boolean Algebraic(FileRecHndl frHndl, short doMoveNum, short gameIndex, StringPtr pstr);
- static short IsAlgebraic (FileRecHndl frHndl, Ptr cptr, short len, short *rfrom, short *rto, short *rpromote);
- static short IsDescriptive(FileRecHndl frHndl, Ptr cptr, short len, short *rfrom, short *rto, short *rpromote);
- static Boolean MoveCausesCheck(FileRecHndl game, short from, short to);
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- Boolean AnnotateMove(FileRecHndl frHndl, short doMoveNum, short gameIndex, StringPtr pstr)
- {
- if (gDescriptive)
- return(Descriptive(frHndl, doMoveNum, gameIndex, pstr));
- else
- return(Algebraic(frHndl, doMoveNum, gameIndex, pstr));
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- static Boolean Descriptive(FileRecHndl frHndl, short doMoveNum, short gameIndex, StringPtr pstr)
- {
- short from, to, piece;
- short i, r, c, rr, cc, rrr, ccc, fff, ttt, ppp;
- short color, check, ck, opFrom;
- short fromSide, fromCol, fromRow, toSide, toCol, toRow, toPiece;
- short c0, c1;
- Boolean fullDo;
- GameListHndl gameMoves;
- MoveListHndl legalMoves;
-
- color = WhosMove(frHndl);
-
- GenerateLegalMoves(frHndl);
- legalMoves = (*frHndl)->doc.legalMoves;
-
- gameMoves = (*frHndl)->doc.gameMoves;
- from = (**gameMoves)[doMoveNum].moveFrom;
- to = (**gameMoves)[doMoveNum].moveTo;
-
- check = MoveCausesCheck(frHndl, from, to);
-
- if (!from) {
- GetIndString(pstr, rGameStat, to);
- while (pstr[1] == ' ') BlockMove(pstr + 2, pstr + 1, --pstr[0]);
- return(false);
- }
-
- r = from / 10;
- c = from - 10 * r - 1;
- r -= 2;
-
- rr = to / 10;
- cc = to - 10 * rr - 1;
- rr -= 2;
-
- piece = (*frHndl)->doc.theBoard[from];
- if (piece < 0) piece = -piece;
- if (piece > BK) piece -= KSIDEPIECE;
-
- pstr[0] = 0;
-
- if (piece == KING) {
- i = c - cc;
- if (i == 2) {
- pcpy(pstr, "\pO-O-O");
- piece = EMPTY;
- }
- if (i == -2) {
- pcpy(pstr, "\pO-O");
- piece = EMPTY;
- }
- }
-
- opFrom = 0;
- fromSide = -1;
- fromCol = -1;
- fromRow = -1;
-
- toPiece = (*frHndl)->doc.theBoard[to];
- if (toPiece < 0) toPiece = -toPiece;
- if (toPiece > BK) toPiece -= KSIDEPIECE;
-
- if (!toPiece)
- if (piece == PAWN)
- if (to == (*frHndl)->doc.enPasMove)
- toPiece = PAWN;
-
- toSide = -1;
- toCol = -1;
- toRow = -1;
-
- if (piece) {
- pstr[++pstr[0]] = " PNBRQK"[piece];
- for (i = 0; i < (*frHndl)->doc.numLegalMoves; ++i) {
- fff = (**legalMoves)[i].moveFrom;
- ttt = (**legalMoves)[i].moveTo;
- if (ttt == to) {
- if (fff != from) {
- ck = MoveCausesCheck(frHndl, fff, ttt);
- if (ck == check) {
- ppp = (*frHndl)->doc.theBoard[fff];
- if (ppp < 0) ppp = -ppp;
- if (ppp > BK) ppp -= KSIDEPIECE;
- if (ppp == piece) {
- fromRow = r;
- rrr = fff / 10;
- ccc = fff - 10 * rrr - 1;
- rrr -= 2;
- if ((rrr == r) || (opFrom)) {
- if ((ccc != c) || (opFrom)) {
- c0 = c;
- if (c0 > 4) c0 = 7 - c0;
- fromRow = r;
- fromCol = c0;
- c1 = ccc;
- if (c1 > 4) c1 = 7 - c1;
- if (c0 == c1) {
- if (ccc != c) {
- if (c > 4) fromSide = 1;
- if (c < 3) fromSide = 0;
- }
- }
- }
- }
- opFrom = fff;
- }
- }
- }
- }
- }
-
- for (i = 0; i < (*frHndl)->doc.numLegalMoves; ++i) {
- fff = (**legalMoves)[i].moveFrom;
- ttt = (**legalMoves)[i].moveTo;
- ppp = (*frHndl)->doc.theBoard[fff];
- if (ppp < 0) ppp = -ppp;
- if (ppp > BK) ppp -= KSIDEPIECE;
- if (ppp == piece) {
- ck = MoveCausesCheck(frHndl, fff, ttt);
- if (ck == check) {
- ppp = (*frHndl)->doc.theBoard[ttt];
- if (ppp < 0) ppp = -ppp;
- if (ppp > BK) ppp -= KSIDEPIECE;
- if (!ppp)
- if (piece == PAWN)
- if (ttt == (*frHndl)->doc.enPasMove)
- ppp = PAWN;
-
- if (ppp == toPiece) {
- fullDo = ((!toPiece) && (ttt == to)) ? true : false;
- rrr = ttt / 10;
- ccc = ttt - 10 * rrr - 1;
- rrr -= 2;
- if ((ccc != cc) && (rrr != rr)) toRow = rr;
- if (ccc == cc) {
- if ((rrr != rr) || (fullDo)) {
- toRow = rr;
- }
- }
- if (rrr == rr) {
- if ((ccc != cc) || (fullDo)) {
- c0 = cc;
- if (c0 > 4) c0 = 7 - c0;
- toRow = rr;
- toCol = cc;
- c1 = ccc;
- if (c1 > 4) c1 = 7 - c1;
- if (c0 == c1) {
- if (ccc != cc) {
- if (cc > 4) toSide = 1;
- if (cc < 3) toSide = 0;
- }
- }
- }
- }
- }
- }
- }
- }
-
- if (opFrom) {
- pstr[++pstr[0]] = '(';
- if (fromSide != -1)
- pstr[++pstr[0]] = "QK"[fromSide];
- if (fromCol != -1)
- pstr[++pstr[0]] = "RNBQKBNR"[fromCol];
- if (fromRow != -1) {
- if (color == WHITE) fromRow = 7 - fromRow;
- pstr[++pstr[0]] = "12345678"[fromRow];
- }
- pstr[++pstr[0]] = ')';
- }
-
- if (toPiece) {
- pstr[++pstr[0]] = 'x';
- pstr[++pstr[0]] = " PNBRQK"[toPiece];
- if ((toRow == -1) && (toCol == -1) && (toSide == -1)) toPiece = 0;
- }
- else {
- pstr[++pstr[0]] = '-';
- if (toRow != -1) toPiece = -1;
- if (toCol != -1) toPiece = -1;
- if (toSide != -1) toPiece = -1;
- }
-
- if (toPiece) {
- if (toPiece > 0) pstr[++pstr[0]] = '(';
- if (toSide != -1)
- pstr[++pstr[0]] = "QK"[toSide];
- if (toCol != -1)
- pstr[++pstr[0]] = "RNBQKBNR"[toCol];
- if (toRow != -1) {
- if (color == WHITE) toRow = 7 - toRow;
- pstr[++pstr[0]] = "12345678"[toRow];
- }
- if (toPiece > 0) pstr[++pstr[0]] = ')';
- }
- }
-
- if (piece == PAWN) {
- to = (**gameMoves)[doMoveNum].promoteTo;
- if (to) {
- if (to < 0) to = -to;
- pstr[++pstr[0]] = '=';
- pstr[++pstr[0]] = " NBRQ"[to];
- }
- }
-
- if (check)
- pstr[++pstr[0]] = '+';
-
- return(doMoveNum == gameIndex - 1);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- static Boolean Algebraic(FileRecHndl frHndl, short doMoveNum, short gameIndex, StringPtr pstr)
- {
- short from, to, piece, extend, rowMatch, colMatch;
- short i, r, c, rr, cc, rrr, ccc, fff, ttt, ppp;
- short color, kingLoc;
- GameListHndl gameMoves;
- MoveListHndl legalMoves;
-
- gameMoves = (*frHndl)->doc.gameMoves;
- from = (**gameMoves)[doMoveNum].moveFrom;
- to = (**gameMoves)[doMoveNum].moveTo;
-
- if (!from) {
- GetIndString(pstr, rGameStat, to);
- while (pstr[1] == ' ') BlockMove(pstr + 2, pstr + 1, --pstr[0]);
- return(false);
- }
-
- r = from / 10;
- c = from - 10 * r - 1;
- r -= 2;
-
- rr = to / 10;
- cc = to - 10 * rr - 1;
- rr -= 2;
-
- piece = (*frHndl)->doc.theBoard[from];
- if (piece < 0) piece = -piece;
- if (piece > BK) piece -= KSIDEPIECE;
-
- pstr[0] = 0;
- if (piece == PAWN) {
- if (c != cc) {
- pstr[++pstr[0]] = "abcdefgh"[c];
- pstr[++pstr[0]] = 'x';
- }
- }
- if (piece == KING) {
- i = c - cc;
- if (i == 2) {
- pcpy(pstr, "\pO-O-O");
- piece = EMPTY;
- }
- if (i == -2) {
- pcpy(pstr, "\pO-O");
- piece = EMPTY;
- }
- }
-
- if (piece > PAWN) {
- rowMatch = colMatch = extend = false;
- GenerateLegalMoves(frHndl);
- legalMoves = (*frHndl)->doc.legalMoves;
- for (i = 0; i < (*frHndl)->doc.numLegalMoves; ++i) {
- fff = (**legalMoves)[i].moveFrom;
- ttt = (**legalMoves)[i].moveTo;
- if ((ttt == to) && (fff != from)) {
- ppp = (*frHndl)->doc.theBoard[fff];
- if (ppp < 0) ppp = -ppp;
- if (ppp > BK) ppp -= KSIDEPIECE;
- if (ppp != piece) continue;
- rrr = fff / 10;
- ccc = fff - 10 * rrr - 1;
- rrr -= 2;
- extend = true;
- if (r == rrr) rowMatch = true;
- if (c == ccc) colMatch = true;
- }
- }
- if ((extend) && (!colMatch)) rowMatch |= extend;
- pstr[++pstr[0]] = " NBRQK"[piece];
- if (rowMatch)
- pstr[++pstr[0]] = "abcdefgh"[c];
- if (colMatch)
- pstr[++pstr[0]] = "87654321"[r];
- i = (*frHndl)->doc.theBoard[to];
- if (!i)
- if (piece == PAWN)
- if (to == (*frHndl)->doc.enPasMove)
- i = PAWN;
- if ((i) && (i != OBNDS)) pstr[++pstr[0]] = 'x';
- }
-
- if (piece) {
- pstr[++pstr[0]] = "abcdefgh"[cc];
- pstr[++pstr[0]] = "87654321"[rr];
- }
- if (piece == PAWN) {
- to = (**gameMoves)[doMoveNum].promoteTo;
- if (to) {
- if (to < 0) to = -to;
- pstr[++pstr[0]] = '=';
- pstr[++pstr[0]] = " NBRQ"[to];
- }
- }
-
- if (doMoveNum < (*frHndl)->doc.numGameMoves) {
- RepositionBoard(frHndl, doMoveNum + 1, false);
- kingLoc = (*frHndl)->doc.king[color = WhosMove(frHndl)].kingLoc;
- if (SquareAttacked(frHndl, kingLoc, color)) pstr[++pstr[0]] = '+';
- RepositionBoard(frHndl, doMoveNum, false);
- }
-
- return(doMoveNum == gameIndex - 1);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- void MovesToOutBox(FileRecHndl frHndl, EventRecord *event)
- {
- short txtIndx, numGameMoves, gameIndex, startColor;
- short move, moveColor, moveNum, i, selStart, selEnd, condensed;
- Boolean needCR;
- Str255 txt;
- Handle txtHndl;
- TEHandle teHndl;
- WindowPtr oldPort;
-
- txtHndl = NewHandle(32000);
- if (!txtHndl) return;
- txtIndx = 0;
-
- condensed = (event->modifiers & optionKey);
-
- numGameMoves = (*frHndl)->doc.numGameMoves;
- gameIndex = (*frHndl)->doc.gameIndex;
- teHndl = (*frHndl)->doc.message[kMessageOut];
- startColor = (*frHndl)->doc.startColor;
-
- txt[0] = 0;
- needCR = false;
- for (move = gameIndex; move < numGameMoves; ++move) {
- moveColor = ((move + startColor) & 0x01);
- moveNum = ((move + startColor) / 2 + 1);
- if ((needCR) && (!moveColor)) {
- i = (condensed) ? 32 : 13;
- (*txtHndl)[txtIndx++] = i;
- needCR = false;
- }
- if ((!moveColor) || (move == gameIndex)) {
- pcpydec(txt, i = (move / 2 + 1));
- pcat(txt, "\p) ");
- if ((condensed) || (i > 9)) txt[0]--;
- BlockMove(txt + 1, *txtHndl + txtIndx, txt[0]);
- txtIndx += txt[0];
- needCR = true;
- }
- if ((moveColor) && (move == gameIndex)) {
- if (condensed) {
- BlockMove("...,", *txtHndl + txtIndx, 4);
- txtIndx += 4;
- }
- else {
- if (gDescriptive) {
- BlockMove("... ", *txtHndl + txtIndx, 13);
- txtIndx += 13;
- } else {
- BlockMove("... ", *txtHndl + txtIndx, 8);
- txtIndx += 8;
- }
- }
- needCR = true;
- }
- RepositionBoard(frHndl, move, false);
-
- AnnotateMove(frHndl, move, 0, txt);
- if (move < numGameMoves - 1) {
- if (condensed) {
- if (!moveColor) txt[++(txt[0])] = ',';
- }
- else {
- if (!moveColor) pcat(txt, "\p ");
- if (gDescriptive) {
- if (txt[0] > 13) txt[0] = 13;
- }
- else {
- if (txt[0] > 8 ) txt[0] = 8;
- }
- }
- }
- BlockMove(txt + 1, *txtHndl + txtIndx, txt[0]);
- txtIndx += txt[0];
- needCR = true;
- }
-
- LockHandleHigh(txtHndl);
- oldPort = SetFilePort(frHndl);
-
- CTENewUndo(CTEViewFromTE(teHndl), true);
- TEDelete(teHndl);
- selStart = (*teHndl)->selStart;
- TEInsert(*txtHndl, txtIndx, teHndl);
- selEnd = (*teHndl)->selStart;
- TESetSelect(selStart, selEnd, teHndl);
- TESelView(teHndl);
- CTEAdjustTEBottom(teHndl);
- CTEAdjustScrollValues(teHndl);
- (*frHndl)->fileState.docDirty = true;
-
- SetPort(oldPort);
- DisposeHandle(txtHndl);
-
- RepositionBoard(frHndl, gameIndex, false);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- void MovesFromText(FileRecHndl frHndl, Handle txtHndl, short txtLen,
- short beg, short end, Boolean slideMoves)
- {
- WindowPtr oldPort;
- short gameIndex, txtIndx, commentCount;
- short numUsed, nu, numLglMoves, lastChar, c0, c1, i;
- short from, to, promoteTo, f, t;
- long tick;
- char *cptr;
- MoveListHndl lglMoves;
- static char goodFirstChar[] = "Oo01abcdefghPNBRQK";
-
- oldPort = SetFilePort(frHndl);
- if (end == beg) end = txtLen;
-
- GenerateLegalMoves(frHndl);
- gameIndex = (*frHndl)->doc.gameIndex;
- txtIndx = beg;
- commentCount = 0;
-
- tick = TickCount();
- HLock(txtHndl);
-
- for (;; txtIndx += numUsed) {
-
- if (!commentCount) {
- numLglMoves = (*frHndl)->doc.numLegalMoves;
- lglMoves = (*frHndl)->doc.legalMoves;
- if (!numLglMoves) break;
- /* Can't accept any moves, as there are no legal moves. */
- }
-
- lastChar = end - txtIndx - 1;
- if (lastChar < 1) break;
- /* An algebraic move is at least 2 characters. */
-
- cptr = *txtHndl + txtIndx;
- c0 = cptr[0];
- numUsed = 1; /* Always use at least 1 character per pass. */
-
- if (c0 == '[') {
- ++commentCount;
- continue;
- }
-
- if (c0 == ']') {
- if (commentCount) --commentCount;
- continue;
- }
-
- if (commentCount) continue;
-
- for (i = 0; goodFirstChar[i]; ++i)
- if (c0 == goodFirstChar[i]) break;
- if (!goodFirstChar[i]) continue;
- /* Not good first character, so check next char. */
-
- from = to = 0;
- for (;;) { /* Used to break from for jump purposes. */
-
- if (i < 3) { /* First character is castling character... */
- if (lastChar < 2) break;
- /* Not enough characters for kside castling. */
- if (cptr[numUsed] != '-') break; /* Isn't a castle. */
- if (cptr[numUsed + 1] != '1') { /* Isn't a black-wins notation. */
- if (cptr[++numUsed] != c0) break; /* Isn't a castle. */
- from = (WhosMove(frHndl)) ? 25 : 95;
- to = from + 2;
- if (lastChar < 4) {
- ++numUsed;
- break;
- } /* Not enough characters for qside castling, so try kside. */
- if (cptr[++numUsed] != '-') break; /* Isn't a castle. */
- if (cptr[++numUsed] != c0) break; /* Isn't a castle. */
- to -= 4;
- ++numUsed;
- break; /* Try qside castle. */
- }
- }
-
- i -= 2;
- if (i < 2) { /* May be end-of-game notation. (1-0, 1/2, 0-1) */
- if (lastChar < 2) break;
- /* Not enough characters for end-of-game notation. */
- c1 = cptr[numUsed];
- if (c1 == '-') {
- if (cptr[numUsed + 1] == ('1' - i)) to = kWhiteResigns + i;
- }
- else if (c1 == '/') {
- if (cptr[numUsed + 1] == '2') to = kDrawGame;
- }
- if (to) EndTheGame(frHndl, to);
- to = 0;
- break; /* Done processing this character, either way. */
- }
-
- nu = IsAlgebraic(frHndl, cptr, lastChar, &from, &to, &promoteTo);
- if (from != -1) {
- numUsed += (nu - 1);
- break;
- }
- else {
- nu = IsDescriptive(frHndl, cptr, lastChar, &from, &to, &promoteTo);
- if (from != -1) {
- numUsed += (nu - 1);
- break;
- }
- }
- break;
- }
-
- for (i = 0; i < numLglMoves; ++i) {
- f = (**lglMoves)[i].moveFrom;
- t = (**lglMoves)[i].moveTo;
- if ((f == from) && (t == to)) break;
- }
- if (i < numLglMoves) {
- from = (**lglMoves)[i].moveFrom;
- to = (**lglMoves)[i].moveTo;
- if (slideMoves) SlideThePiece(frHndl, from, to);
- MakeMove(frHndl, from, to, promoteTo);
- GenerateLegalMoves(frHndl);
- ImageDocument(frHndl, true);
- AdjustGameSlider(frHndl);
- UpdateGameStatus(frHndl);
- if (tick + 30 < TickCount()) { /* Send max 1 AppleEvent per 1/2 sec. */
- tick = TickCount();
- if ((*frHndl)->doc.twoPlayer) SendGame(frHndl, kScrolling, nil);
- }
- }
- else {
- if ((!from) && (!to)) {
- if (numUsed > 1) --numUsed;
- for (;;) {
- c0 = cptr[numUsed++];
- if (numUsed >= lastChar) break;
- if ((c0 >= 'A') && (c0 <= 'Z')) continue;
- if ((c0 >= 'a') && (c0 <= 'z')) continue;
- if ((c0 >= '0') && (c0 <= '9')) continue;
- break;
- }
- }
- }
- }
-
- HUnlock(txtHndl);
-
- if ((*frHndl)->doc.twoPlayer) SendGame(frHndl, kResync, nil);
- }
-
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- void MakeVerbose(FileRecHndl frHndl, StringPtr pstr)
- {
- Str255 result;
- Str32 piece, from, verb, to, epi;
- short i, enPas, pp, ff, tt, gameIndex;
- Boolean inParens;
- GameListHndl gameMoves;
- static StringPtr cols[] = {"\peigh,", "\pbee,", "\psea,", "\pdee,",
- "\pe,", "\pef,", "\pgee,", "\pH,"};
-
- if (!pstr[0]) return;
-
- result[0] = from[0] = to[0] = epi[0] = 0;
-
- enPas = false;
- gameMoves = (*frHndl)->doc.gameMoves;
- gameIndex = (*frHndl)->doc.gameIndex;
- ff = (**gameMoves)[gameIndex].moveFrom;
- tt = (**gameMoves)[gameIndex].moveTo;
- pp = (*frHndl)->doc.theBoard[ff];
- if (pp < 0) pp = -pp;
- if (pp > BK) pp -= KSIDEPIECE;
- if (pp == PAWN) {
- pp = (*frHndl)->doc.theBoard[tt];
- if (pp < 0) pp = -pp;
- if (pp > BK) pp -= KSIDEPIECE;
- if (!pp)
- if (tt == (*frHndl)->doc.enPasMove)
- enPas = true;
- }
-
- pcpy(piece, "\ppaun ");
- pcpy(verb, "\ptoo, ");
-
- if (pstr[i = 1] < 'Z') {
- if (pstr[i] == 'O') {
- ++i;
- if (pstr[0] < 3) return;
- pcpy(result, "\pcastle ");
- if (pstr[0] < 4) {
- pcat(result, "\p king side");
- pcpy(pstr, result);
- return;
- }
- if (pstr[4] == '+') {
- pcat(result, "\p king side, check");
- pcpy(pstr, result);
- return;
- }
- pcat(result, "\p kweenn side");
- if (pstr[0] >= 6) {
- if (pstr[6] == '+') pcat(result, "\p, check");
- pcpy(pstr, result);
- }
- pcpy(pstr, result);
- return;
- }
-
- if (pstr[i] == 'P') pcpy(piece, "\ppaun ");
- if (pstr[i] == 'N') pcpy(piece, "\pknight ");
- if (pstr[i] == 'B') pcpy(piece, "\pbishop ");
- if (pstr[i] == 'R') pcpy(piece, "\prook ");
- if (pstr[i] == 'Q') pcpy(piece, "\pkweenn ");
- if (pstr[i] == 'K') pcpy(piece, "\pking ");
- ++i;
- }
-
- if (i > pstr[0]) return;
-
- if (gDescriptive) {
- inParens = false;
- for (i = 1; i <= pstr[0]; ++i) {
- switch (pstr[i]) {
- case 'P':
- pcat(result, "\p pawn ");
- break;
- case 'N':
- pcat(result, "\p knight ");
- break;
- case 'B':
- pcat(result, "\p bishop ");
- break;
- case 'R':
- pcat(result, "\p rook ");
- break;
- case 'Q':
- pcat(result, "\p kweenn ");
- break;
- case 'K':
- pcat(result, "\p king ");
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- pcatchr(result, pstr[i], 1);
- if (inParens)
- pcatchr(result, ',', 1);
- pcatchr(result, ' ', 1);
- inParens = false;
- break;
- case '(':
- inParens = true;
- pcat(result, "\p, at, ");
- break;
- case ')':
- inParens = false;
- break;
- case '-':
- pcat(result, "\p too ");
- break;
- case 'x':
- pcat(result, "\p takes ");
- break;
- case '=':
- if (enPas) {
- pcat(result, "\p, en paw saunt ");
- enPas = false;
- }
- pcat(result, "\p, promote too ");
- break;
- case '+':
- if (enPas) {
- pcat(result, "\p, en paw saunt ");
- enPas = false;
- }
- pcat(result, "\p, check");
- break;
- }
- }
-
- if (enPas) {
- pcat(result, "\p, en paw saunt ");
- enPas = false;
- }
-
- pcpy(pstr, result);
- return;
- }
-
- if ((pstr[i] >= '1') && (pstr[i] <= '8')) {
- if (pstr[0] > (i + 1)) {
- pcpy(from, "\pat, ");
- pcatchr(from, pstr[i++], 1);
- pcat(from, "\p, ");
- }
- }
-
- if ((pstr[i] >= 'a') && (pstr[i] <= 'h')) {
- if (pstr[0] > (i + 1)) {
- if ((pstr[i + 1] < '1') || (pstr[i + 1] > '8')) {
- pcpy(from, "\pat, ");
- pcat(from, cols[pstr[i++] - 'a']);
- pcatchr(from, ' ', 1);
- }
- }
- }
-
- if (i > pstr[0]) return;
-
- if (pstr[i] == 'x') {
- pcpy(verb, "\ptakes, ");
- ++i;
- }
-
- if (i > pstr[0]) return;
-
- if ((pstr[i] >= 'a') && (pstr[i] <= 'h')) {
- pcat(to, cols[pstr[i++] - 'a']);
- pcatchr(to, ' ', 1);
- }
-
- if (i > pstr[0]) return;
-
- if ((pstr[i] >= '1') && (pstr[i] <= '8')) {
- pcatchr(to, pstr[i++], 1);
- pcatchr(to, ' ', 1);
- }
-
- if (i <= pstr[0]) {
- if (pstr[i] == '=') {
- pcat(epi, "\p, promote too ");
- if (++i > pstr[0]) return;
- if (pstr[i] == 'N') pcat(epi, "\pknight ");
- if (pstr[i] == 'B') pcat(epi, "\pbishop ");
- if (pstr[i] == 'R') pcat(epi, "\prook ");
- if (pstr[i] == 'Q') pcat(epi, "\pkweenn ");
- ++i;
- }
- }
-
- if (i <= pstr[0]) {
- if (pstr[i] == '+')
- pcat(epi, "\p, check");
- }
-
- pcpy(pstr, piece);
- pcat(pstr, from);
- pcat(pstr, verb);
- pcat(pstr, to);
- pcat(pstr, epi);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- void SayTheMove(FileRecHndl frHndl)
- {
- Handle txt;
- Str255 pstr;
- short i;
- Boolean move;
-
- if (!(*frHndl)->doc.doSpeech) return;
-
- MakeMove(frHndl, -1, 0, 0);
-
- i = (*frHndl)->doc.gameIndex;
- if (gDescriptive)
- move = Descriptive(frHndl, i, i + 1, pstr);
- else
- move = Algebraic(frHndl, i, i + 1, pstr);
- if (move) MakeVerbose(frHndl, pstr);
-
- MakeMove(frHndl, 1, 0, 0);
-
- switch (i = GameStatus(frHndl)) {
- case kYouWin:
- case kYouLose:
- pcat(pstr, "\p mate");
- break;
- }
-
- txt = NewHandle(pstr[0]);
- BlockMove(pstr + 1, *txt, pstr[0]);
- SayText(nil, txt, (*frHndl)->doc.theVoice);
- DisposeHandle(txt);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- static short IsAlgebraic(FileRecHndl frHndl, Ptr cptr, short lastChar, short *rfrom, short *rto, short *rpromote)
- {
- short numUsed, numLglMoves, c0, c1, i, j, k, numMatch;
- short from, to, fromRow, fromCol, toRow, toCol, piece, f, t, r, c;
- Boolean take, check;
- MoveListHndl lglMoves;
- static char goodFirstChar[] = "abcdefghPNBRQK";
-
- *rfrom = *rto = -1; /* Not algebraic move flag. */
- *rpromote = QUEEN;
-
- if (lastChar < 1) return(1); /* An algebraic move is at least 2 characters. */
-
- c0 = cptr[0];
- numUsed = 1; /* Always use at least 1 character per pass. */
-
- numLglMoves = (*frHndl)->doc.numLegalMoves;
- lglMoves = (*frHndl)->doc.legalMoves;
-
- for (i = 0; goodFirstChar[i]; ++i)
- if (c0 == goodFirstChar[i]) break;
-
- if (!goodFirstChar[i]) return(numUsed); /* Just used first char. */
-
- fromRow = fromCol = -1;
- toRow = toCol = -1;
- from = to = 0;
- take = check = false;
- /* From may be square or piece. */
- /* To will be square. */
- /* If to stays 0, then to = from, and from = PAWN. More on this later. */
-
- for (;;) { /* Used to break from for jump purposes. */
-
- if (i < 8) { /* It is probably a pawn move. The form is one of */
- /* the following: e4, dxe, dxe4, d3xe4, d3e4, d3-e4. */
- /* Due to this, it can't be decided yet as to */
- /* whether we are looking at the from or the to */
- /* location. */
-
- from = PAWN;
- fromCol = i; /* Might end up the toCol, so keep this in mind. */
- c1 = cptr[numUsed];
- if ((c1 >= '1') && (c1 <= '8')) {
- fromRow = 7 - (c1 - '1'); /* Might end up the toRow. */
- if (++numUsed > lastChar) break;
- c1 = cptr[numUsed];
- }
- if ((c1 == 'x') || (c1 == 'X')) take = true;
- if ((take) || (c1 == '-')) {
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- if ((c0 < 'a') || (c0 > 'h')) break;
- toCol = c0 - 'a';
- if (numUsed >= lastChar) break;
- else {
- c1 = cptr[++numUsed];
- if ((c1 >= '1') && (c1 <= '8')) {
- toRow = 7 - (c1 - '1');
- to = 10 * toRow + toCol + START_IBNDS;
- from = PAWN; /* Assume it is a pawn move. */
- if ((fromRow != -1) && (fromCol != -1))
- from = 10 * fromRow + fromCol + START_IBNDS;
- /* Move is of form d3-e4, so it doesn't have to be a pawn. */
- break;
- }
- }
- }
- else {
- if (fromRow != -1) { /* Of the form e4. */
- if ((c1 < 'a') || (c1 > 'h')) {
- from = PAWN;
- to = 10 * fromRow + fromCol + START_IBNDS;
- fromRow = fromCol = -1; /* No hint of where from. */
- }
- else {
- toCol = c1 - 'a';
- c0 = c1;
- if (++numUsed > lastChar) break;
- c1 = cptr[numUsed];
- if ((c1 >= '1') && (c1 <= '8')) {
- toRow = 7 - (c1 - '1');
- to = 10 * toRow + toCol + START_IBNDS;
- from = PAWN; /* Assume it is a pawn move. */
- if ((fromRow != -1) && (fromCol != -1))
- from = 10 * fromRow + fromCol + START_IBNDS;
- /* Move is of form d3e4, so it doesn't have to be a pawn. */
- ++numUsed;
- break;
- }
- }
- }
- break;
- }
- }
-
- else from = i - 7; /* Remember which kind of piece. */
-
- c0 = cptr[numUsed];
-
- if (c0 == '(') { /* Parens are optional -- just skip them. */
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
-
- if ((c0 >= 'a') && (c0 <= 'h')) {
- fromCol = c0 - 'a';
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
- if ((c0 >= 'a') && (c0 <= 'h')) {
- toCol = c0 - 'a';
- if (++numUsed > lastChar) break;
- c1 = cptr[numUsed];
- if ((c1 >= '1') && (c1 <= '8')) {
- toRow = 7 - (c1 - '1');
- to = 10 * toRow + toCol + START_IBNDS;
- ++numUsed;
- }
- break;
- }
- if ((c0 >= '1') && (c0 <= '8')) {
- fromRow = 7 - (c0 - '1');
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
-
- if (c0 == ')') { /* Parens are optional -- just skip them. */
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
-
- if ((c0 == 'x') || (c0 == 'X')) take = true;
- if ((take) || (c0 == '-')) {
- if ((c0 == 'x') || (c0 == 'X') || (c0 == '-')) ++numUsed;
- if (numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
-
- if ((c0 >= 'a') && (c0 <= 'h')) {
- toCol = c0 - 'a';
- if (++numUsed > lastChar) break;
- c1 = cptr[numUsed];
- if ((c1 >= '1') && (c1 <= '8')) {
- toRow = 7 - (c1 - '1');
- to = 10 * toRow + toCol + START_IBNDS;
- ++numUsed;
- }
- break;
- }
- else {
- if ((fromRow != -1) && (fromCol != -1)) {
- to = 10 * fromRow + fromCol + START_IBNDS;
- fromRow = fromCol = -1; /* No hint of where from. */
- }
- break;
- }
-
- break;
- }
-
- if ((!to) && (toRow == -1) && (toCol == -1)) {
- if ((fromRow != -1) && (fromCol != -1)) {
- to = 10 * fromRow + fromCol + START_IBNDS;
- fromRow = fromCol = -1;
- }
- }
-
- if ((to) || (toRow > -1) || (toCol > -1)) {
- if (numUsed < lastChar) {
- c0 = cptr[numUsed];
- if (c0 == '=') {
- if (++numUsed <= lastChar) {
- c0 = cptr[numUsed];
- if (c0 == 'N') *rpromote = KNIGHT;
- if (c0 == 'B') *rpromote = BISHOP;
- if (c0 == 'R') *rpromote = ROOK;
- if ((c0 == 'N') || (c0 == 'B') || (c0 == 'R') || (c0 == 'Q'))
- if (++numUsed <= lastChar)
- c0 = cptr[numUsed];
- }
- }
- }
- }
- if (c0 == '+') {
- check = true;
- if (++numUsed <= lastChar) c0 = cptr[numUsed];
- }
-
- for (numMatch = 0, j = 0; j < 2; ++j) {
- for (i = 0; i < numLglMoves; ++i) {
- f = (**lglMoves)[i].moveFrom;
- t = (**lglMoves)[i].moveTo;
-
- if (to >= START_IBNDS) { /* If we have a fully formed to... */
- if (to != t) continue; /* If to is different than this move, next move. */
- }
- else {
- if (to) {
- piece = (*frHndl)->doc.theBoard[t];
- if (piece < 0) piece = -piece;
- if (piece > BK) piece -= KSIDEPIECE;
- if (piece != to) continue;
- }
- if ((!to) && (toRow == -1) && (toCol == -1)) continue;
- r = (t - START_IBNDS) / 10;
- c = t - START_IBNDS - 10 * r;
- if (toRow == -1) r = -1;
- if (toCol == -1) c = -1;
- if ((toRow != r) || (toCol != c)) continue;
- if (take) {
- k = (**lglMoves)[i].moveTo;
- if (!(*frHndl)->doc.theBoard[k]) continue;
- }
- }
-
- if (from >= START_IBNDS) {
- if (from == f) {
- if (!j) ++numMatch;
- else {
- if (numMatch < 2) break;
- if (MoveCausesCheck(frHndl, f, t) == check) break;
- }
- }
- continue;
- }
- piece = (*frHndl)->doc.theBoard[f];
- if (piece < 0) piece = -piece;
- if (piece > BK) piece -= KSIDEPIECE;
- if (piece == from) {
- r = (f - START_IBNDS) / 10;
- c = f - START_IBNDS - 10 * r;
- if (fromRow == -1) r = -1;
- if (fromCol == -1) c = -1;
- if ((fromRow == r) && (fromCol == c)) {
- if (!j) ++numMatch;
- else {
- if (numMatch < 2) break;
- if (MoveCausesCheck(frHndl, f, t) == check) break;
- }
- }
- }
- }
- }
-
- if (i < numLglMoves) {
- *rfrom = (**lglMoves)[i].moveFrom;
- *rto = (**lglMoves)[i].moveTo;
- };
-
- return(numUsed);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- static short IsDescriptive(FileRecHndl frHndl, Ptr cptr, short lastChar, short *rfrom, short *rto, short *rpromote)
- {
- short numUsed, numLglMoves, c0, i, j, k, numMatch;
- short from, to, fromRow, fromCol, fromCol2, toRow, toCol, toCol2;
- short piece, f, t, r, c, color;
- Boolean take, check;
- MoveListHndl lglMoves;
- static char goodPieceChar[] = "PNBRQK";
- static char goodFTChar[] = "PNBRQK12345678";
-
- *rfrom = *rto = -1; /* Not algebraic move flag. */
- *rpromote = QUEEN;
-
- color = WhosMove(frHndl); /* Who's move it is. */
-
- if (lastChar < 1) return(1); /* An algebraic move is at least 2 characters. */
-
- c0 = cptr[0];
- numUsed = 1; /* Always use at least 1 character per pass. */
-
- numLglMoves = (*frHndl)->doc.numLegalMoves;
- lglMoves = (*frHndl)->doc.legalMoves;
-
- for (i = 0; goodPieceChar[i]; ++i) if (c0 == goodPieceChar[i]) break;
- if (!goodPieceChar[i]) return(numUsed); /* Just used first char. */
-
- fromRow = fromCol = fromCol2 = -1;
- toRow = toCol = toCol2 = -1;
- from = to = 0;
- take = check = false;
- /* From may be square or piece. */
- /* To will be square. */
- /* If to stays 0, then to = from, and from = PAWN. More on this later. */
-
- for (;;) { /* Used to break from for jump purposes. */
-
- from = i + 1; /* Remember which kind of piece. */
-
- c0 = cptr[numUsed];
- if (from == QUEEN) {
- if (c0 == 'R')
- from = ROOK;
- if (c0 == 'N')
- from = KNIGHT;
- if (c0 == 'B')
- from = BISHOP;
- if (from != QUEEN)
- if (++numUsed > lastChar)
- return(numUsed);
- c0 = cptr[numUsed];
- }
- if (from == KING) {
- if (c0 == 'R')
- from = ROOK + KSIDEPIECE;
- if (c0 == 'N')
- from = KNIGHT + KSIDEPIECE;
- if (c0 == 'B')
- from = BISHOP + KSIDEPIECE;
- if (from != KING)
- if (++numUsed > lastChar)
- return(numUsed);
- c0 = cptr[numUsed];
- }
-
- if (c0 == '(') {
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
-
- for (j = 1; goodFTChar[j]; ++j) if (c0 == goodFTChar[j]) break;
- if (!goodFTChar[j]) return(numUsed); /* Just used first char. */
-
- if (c0 == 'R') {
- fromCol = 0;
- fromCol2 = 7;
- }
- if (c0 == 'N') {
- fromCol = 1;
- fromCol2 = 6;
- }
- if (c0 == 'B') {
- fromCol = 2;
- fromCol2 = 5;
- }
- if (c0 == 'Q') {
- fromCol = 3;
- fromCol2 = 3;
- }
- if (c0 == 'K') {
- fromCol = 4;
- fromCol2 = 4;
- }
- if (fromCol != -1) {
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
-
- if (c0 == 'R') {
- if (fromCol == 3) {
- fromCol = 0;
- fromCol2 = 0;
- }
- if (fromCol == 4) {
- fromCol = 7;
- fromCol2 = 7;
- }
- if (fromCol != fromCol2) return(numUsed);
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
- if (c0 == 'N') {
- if (fromCol == 3) {
- fromCol = 1;
- fromCol2 = 1;
- }
- if (fromCol == 4) {
- fromCol = 6;
- fromCol2 = 6;
- }
- if (fromCol != fromCol2) return(numUsed);
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
- if (c0 == 'B') {
- if (fromCol == 3) {
- fromCol = 2;
- fromCol2 = 2;
- }
- if (fromCol == 4) {
- fromCol = 5;
- fromCol2 = 5;
- }
- if (fromCol != fromCol2) return(numUsed);
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
-
- if ((c0 >= '1') && (c0 <= '8')) {
- fromRow = '8' - c0;
- if (color == BLACK) fromRow = 7 - fromRow;
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
-
- if (c0 == ')') {
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
- }
-
- if ((c0 == 'x') || (c0 == 'X')) {
- take = true;
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- for (i = 0; goodPieceChar[i]; ++i) if (c0 == goodPieceChar[i]) break;
- if (!goodPieceChar[i]) return(numUsed);
- to = i + 1;
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
-
- switch (to) {
- case ROOK:
- if (c0 == 'P') {
- to = PAWN;
- toCol = 0;
- toCol2 = 7;
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
- break;
- case KNIGHT:
- if (c0 == 'P') {
- to = PAWN;
- toCol = 1;
- toCol2 = 6;
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
- break;
- case BISHOP:
- if (c0 == 'P') {
- to = PAWN;
- toCol = 2;
- toCol2 = 5;
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
- break;
- case QUEEN:
- if (c0 == 'R')
- to = ROOK;
- if (c0 == 'N')
- to = KNIGHT;
- if (c0 == 'B')
- to = BISHOP;
- if (to != QUEEN)
- if (++numUsed > lastChar)
- break;
- c0 = cptr[numUsed];
- if (c0 == 'P') {
- to = PAWN;
- toCol = 3;
- toCol2 = 3;
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
- break;
- case KING:
- if (c0 == 'R')
- to = ROOK + KSIDEPIECE;
- if (c0 == 'N')
- to = KNIGHT + KSIDEPIECE;
- if (c0 == 'B')
- to = BISHOP + KSIDEPIECE;
- if (to != KING)
- if (++numUsed > lastChar)
- break;
- c0 = cptr[numUsed];
- if (c0 == 'P') {
- to = PAWN;
- toCol = 4;
- toCol2 = 4;
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
- break;
- }
- if (numUsed > lastChar) break;
- }
-
- if ((c0 == '-') || (c0 == '(')) {
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
-
- if (c0 == '-') {
- for (j = 1; goodPieceChar[j]; ++j) if (c0 == goodPieceChar[j]) break;
- if (!goodPieceChar[j]) return(numUsed); /* Just used first char. */
- }
- if (c0 == '(') {
- for (j = 1; goodFTChar[j]; ++j) if (c0 == goodFTChar[j]) break;
- if (!goodFTChar[j]) return(numUsed); /* Just used first char. */
- }
-
- if (c0 == 'R') {
- toCol = 0;
- toCol2 = 7;
- }
- if (c0 == 'N') {
- toCol = 1;
- toCol2 = 6;
- }
- if (c0 == 'B') {
- toCol = 2;
- toCol2 = 5;
- }
- if (c0 == 'Q') {
- toCol = 3;
- toCol2 = 3;
- }
- if (c0 == 'K') {
- toCol = 4;
- toCol2 = 4;
- }
- if (toCol != -1) {
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
-
- if (c0 == 'R') {
- if (toCol == 3) {
- toCol = 0;
- toCol2 = 0;
- }
- if (toCol == 4) {
- toCol = 7;
- toCol2 = 7;
- }
- if (toCol != toCol2) return(numUsed);
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
- if (c0 == 'N') {
- if (toCol == 3) {
- toCol = 1;
- toCol2 = 1;
- }
- if (toCol == 4) {
- toCol = 6;
- toCol2 = 6;
- }
- if (toCol != toCol2) return(numUsed);
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
- if (c0 == 'B') {
- if (toCol == 3) {
- toCol = 2;
- toCol2 = 2;
- }
- if (toCol == 4) {
- toCol = 5;
- toCol2 = 5;
- }
- if (toCol != toCol2) return(numUsed);
- if (++numUsed > lastChar) return(numUsed);
- c0 = cptr[numUsed];
- }
-
- if ((c0 >= '1') && (c0 <= '8')) {
- toRow = '8' - c0;
- if (color == BLACK) toRow = 7 - toRow;
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
-
- if (c0 == ')') {
- if (++numUsed > lastChar) break;
- c0 = cptr[numUsed];
- }
- }
-
- break;
- }
-
- if ((to) || (toRow > -1) || (toCol > -1)) {
- if (numUsed < lastChar) {
- c0 = cptr[numUsed];
- if (c0 == '=') {
- if (++numUsed <= lastChar) {
- c0 = cptr[numUsed];
- if (c0 == 'N') *rpromote = KNIGHT;
- if (c0 == 'B') *rpromote = BISHOP;
- if (c0 == 'R') *rpromote = ROOK;
- if ((c0 == 'N') || (c0 == 'B') || (c0 == 'R') || (c0 == 'Q'))
- if (++numUsed <= lastChar)
- c0 = cptr[numUsed];
- }
- }
- }
- }
- if (c0 == '+') {
- check = true;
- if (++numUsed <= lastChar) c0 = cptr[numUsed];
- }
-
- for (numMatch = 0, j = 0; j < 2; ++j) {
- for (i = 0; i < numLglMoves; ++i) {
- f = (**lglMoves)[i].moveFrom;
- t = (**lglMoves)[i].moveTo;
-
- if (to >= START_IBNDS) { /* If we have a fully formed to... */
- if (to != t) continue; /* If to is different than this move, next move. */
- }
- else {
- if (to) {
- piece = (*frHndl)->doc.theBoard[t];
- if (piece < 0) piece = -piece;
- if (to <= BK)
- if (piece > BK)
- piece -= KSIDEPIECE;
- if (piece != to) continue;
- }
- if ((!to) && (toRow == -1) && (toCol == -1)) continue;
- r = (t - START_IBNDS) / 10;
- c = t - START_IBNDS - 10 * r;
- if (toRow == -1) r = -1;
- if (toCol == -1) c = -1;
- if (
- (toRow != r) ||
- ((toCol != c) && (toCol2 != c))
- ) continue;
- if (take) {
- k = (**lglMoves)[i].moveTo;
- if (!(*frHndl)->doc.theBoard[k]) continue;
- }
- }
-
- if (from >= START_IBNDS) {
- if (from == f) {
- if (!j) ++numMatch;
- else {
- if (numMatch < 2) break;
- if (MoveCausesCheck(frHndl, f, t) == check) break;
- }
- }
- continue;
- }
- piece = (*frHndl)->doc.theBoard[f];
- if (piece < 0) piece = -piece;
- if (from <= BK)
- if (piece > BK)
- piece -= KSIDEPIECE;
- if (piece == from) {
- r = (f - START_IBNDS) / 10;
- c = f - START_IBNDS - 10 * r;
- if (fromRow == -1) r = -1;
- if (fromCol == -1) c = -1;
- if (
- (fromRow == r) &&
- ((fromCol == c) || (fromCol2 == c))
- ) {
- if (!j) ++numMatch;
- else {
- if (numMatch < 2) break;
- if (MoveCausesCheck(frHndl, f, t) == check) break;
- }
- }
- }
- }
- }
-
- if (i < numLglMoves) {
- *rfrom = (**lglMoves)[i].moveFrom;
- *rto = (**lglMoves)[i].moveTo;
- };
-
- return(numUsed);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment Window
- Boolean MoveCausesCheck(FileRecHndl game, short from, short to)
- {
- short numGameMoves, color, check;
- Boolean docDirty;
- GameListHndl gameMoves;
- long size;
-
- gameMoves = (*game)->doc.gameMoves;
- numGameMoves = (*game)->doc.numGameMoves;
- docDirty = (*game)->fileState.docDirty;
-
- SetHandleSize((Handle)gGenMovesHndl, size = GetHandleSize((Handle)gameMoves));
- BlockMove(*(Handle)gameMoves, *(Handle)gGenMovesHndl, size);
- (*game)->doc.gameMoves = gGenMovesHndl; /* Protect the game moves list. */
-
- color = (WhosMove(game) ^ 1); /* Who's move it is. */
-
- MakeMove(game, from, to, QUEEN);
- check = SquareAttacked(game,
- (*game)->doc.king[color].kingLoc, color);
- UnmakeMove(game);
-
- (*game)->doc.gameMoves = gameMoves;
- (*game)->doc.numGameMoves = numGameMoves;
- (*game)->fileState.docDirty = docDirty;
- /* Restore things the way we were. We are done with MakeMove services. */
-
- if (check) return(true);
- else return(false);
- }
-
-
-
-