|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 22583 (0x5837)
Types: TextFile
Names: »init.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Cchess/init.c«
/* CCHESS CHALLENGE ROUTINES version 1.00
*
* (C) Copyright - Jan D. Wolter - Apr 1986
*
* Mostly routines to make and accept game challenges.
*/
#include "cchess.h"
#ifndef NOTERMCAP
extern char *DL;
#endif NOTERMCAP
/* CHALLENGE()
*
* Make a challenge. User is prompted for options. Challenge line is
* written in the game file. The flag counter is set if this is a
* counter challenge to a previous challenge.
*/
dochallenge(counter)
boolean counter;
{
register int i;
char ch,var;
/* Choose colors */
wprint("\nWhat color would you like ");
if (counter)
{
wprintf("[%s]? ",pcol(mycolor));
ch = enterd("WB",(mycolor==WHITE)?'W':'B');
}
else
{
wprint("(B/W)? ");
ch = enter("WB");
}
if (ch == 'W')
{
wprint("hite");
mycolor = WHITE;
}
else
{
wprint("lack");
mycolor = BLACK;
}
if (order == (schar) -1)
Firstwhite = (ch == 'B');
else
Firstwhite = (ch == 'W');
wprint("\nDo you wish to play a variant game ");
if (counter)
{
ch = (Game_type != TY_CHESS);
wprintf("[%s]? ",yorn(ch));
ch = enterdyn(ch);
}
else
{
wprint("(Y/N)? ");
ch = enteryn();
}
if (ch)
{
wprint("\nVariants games are:\n");
wprint(" (A) Chess - Standard modern game\n");
wprint(" (B) Kriegspiel - Other player's moves hidden\n");
wprint(" (C) Shatranj - 6th century Persian game\n");
wprint(" (D) Courier - 13th century 12x8 board game\n");
wprint(" (E) Halfboard - Standard game on 4x8 board\n");
wprint(" (F) Karma Chess - Capturing men promoted to victim's rank\n");
wprint(" (G) Rifle Chess - Capture without moving\n");
wprint(" (H) Kamikazi Chess - Capturing men lost\n");
wprint(" (I) Double Chess - Make two moves per turn\n");
wprint(" (J) Steamroller - White pawns and king move twice\n");
wprint(" (K) Progressive - One more move every turn\n");
wprint(" (L) Maharajah - White has only maharajah piece\n");
wprint(" (M) Losing Chess - First one to lose all his men wins.\n");
wprint(" (N) Conversion Chess - Combination of Karma and Rifle Chess\n");
/* If you add to the menu above, add letter to string below */
if (counter && Game_type == TY_MIXED)
wprint(" (Z) Mixed Game - Same custom game you were challenged to\n");
wprintf("\nWhich would you like to play [%s]? ",
typename[counter ? Game_type : TY_CHESS]);
ch = xenterd("ZABCDEFGHIJKLMN" + (!counter || Game_type != TY_MIXED),
counter?((Game_type == TY_MIXED)? 'Z': Game_type+'A'-1):'A');
var = (ch == 'Z') ? TY_MIXED : ch - 'A' + 1;
wprintf("%c - %s",ch,typename[var]);
if (var != TY_MIXED)
{
/* Set up default options */
for (i=1;i<OPTIONS;i++)
option[i] = defopt[var][i];
/* Make the initial board */
setup(b);
}
wprint("\nWould you like to customize the game? ");
if (enterdyn(counter?(Game_type==TY_MIXED):FALSE))
{
customize();
goto skip;
}
}
else
{
/* Copy in the default options */
for (i=1;i<OPTIONS;i++)
option[i] = defopt[1][i];
setup(b);
}
/* Ask about the basic stuff */
wprint("Would you like the game to be private (Y/N)? ");
Private = enterdyn(Kriegspiel);
if (!Musttake && !Kriegspiel && !Musttake &&
Capture == CA_NORMAL && Kcapture == CA_NORMAL)
{
wprint("Would you like the computer to kibitz (Y/N)? ");
Help_me = enterdyn(Help_me);
}
else
Help_me = FALSE;
/* write challenge line to game file */
skip:if (newgame)
{
if ((wfp=fopen(fname,"w"))==NULL)
{
wprintf("Cchess error: Unable to create gamefile %s\n",fname);
done(1);
}
chmod(fname,0700);
fprintf(wfp,"%5ld:V %s\n",day(),version);
}
/* Save the challenge */
fprintf(wfp,"%5ld:C ",day());
saveopts(wfp);
placeboard(b);
fflush(wfp);
/* send a challenge message */
sprintf(cbuffer,"You have been challenged to a game of chess by %s.\nRun \042%s %s\042 to respond.\n",myid,RUN_CMD,myid);
mesg("Cchess Challenge",cbuffer);
}
/* CUSTOMIZE
*
* Fiddle with low-level game options. This does run in visual mode.
* The use of the goofy loop here is to make suspends work correctly.
*/
customize()
{
schar ob[R_SIZE][C_SIZE];
register int question;
register int i;
boolean progress;
int v,r,c,tmparea;
hidden = FALSE;
question = 0;
#ifndef LSIGNAL
susp1_flg = TRUE;
setjmp(susp_env);
#endif LSIGNAL
scrolled = TRUE;
for ( ; question >= 0 ; question++)
{
if (scrolled)
{
disp(b,WHITE);
if (question != 9)
{
tmparea = (cy + 1 >= LINES) ? LINES - 1 : cy + 1;
cprint("[default answers shown in brackets]");
}
wputchar('\n');
msgarea = (cy >= LINES) ? LINES - 1 : cy;
}
switch(question)
{
case 0: /* Get the board size */
wprintf("Board Size [%dx%d]:",Rows+1,Cols+1);
wprintf("\nRows (1-%d)? ", HI_ROWS+1);
v = readdint(HI_ROWS+1,Rows+1)-1;
wputchar('\n');
if (v != Rows) scrolled = TRUE;
Rows = v;
break;
case 1:
wprintf("Columns (1-%d)? ", HI_COLS+1);
v = readdint(HI_COLS+1,Cols+1)-1;
wputchar('\n');
if (v != Cols) scrolled = TRUE;
Cols = v;
if (Cols == 0 && Rows == 0)
{
wprint("You got to be kidding!\n");
scrolled = FALSE;
question -=2;
}
break;
case 2:
wprintf("Is the board checkered [%s]? ",yorn(!Plain));
v = !enterdyn(!Plain);
if (v != Plain) scrolled = TRUE;
Plain = v;
break;
case 3: /* Piece names */
initmore();
mprintf("What names should the pieces be given");
Language = enterone(langname,HI_NAMES,Language);
piecename = chessname[Language];
break;
case 4: /* White King piece */
wprintf("Should white have a mateable piece [%s]? ",
yorn(Whiteking != SQ));
if (!enterdyn(Whiteking != SQ))
{
Whiteking = SQ;
question++;
}
break;
case 5:
wprintf("Which is the white mateable piece [%s]? ",
(Whiteking != SQ)? pman(Whiteking) : "");
while ((v = xenterd(pc,pc[PIECES-Whiteking])) == ' ')
bell();
Whiteking = PIECES - (index(pc,v)-pc);
wprintf("%s\n",pman(Whiteking));
break;
case 6: /* Black King piece */
wprintf("Should black have a mateable piece [%s]? ",
yorn(Blackking != SQ));
if (!enterdyn(Blackking != SQ))
{
Blackking = SQ;
question++;
}
break;
case 7:
wprintf("Which is the black mateable piece [%s]? ",
(Blackking != SQ)? pman(Blackking) : "");
while ((v = xenterd(pc,pc[PIECES-Blackking])) == ' ')
bell();
Blackking = PIECES - (index(pc,v)-pc);
wprintf("%s\n",pman(Blackking));
break;
case 8: /* Edit the board - If board is illegal keep asking till ok */
wprintf("Would you like to edit the initial placement [No]? ");
if (enterdyn(FALSE))
{
/* Set things up for the editor */
copy(b,bc);
copy(b,ob);
#ifndef NOTERMCAP
/* Clear scrolling area */
if (cleardown)
{
cursor(1,tmparea);
msgarea = tmparea;
clbot();
}
else
#endif NOTERMCAP
scrolled = TRUE;
break;
}
else
{
#ifndef NOTERMCAP
if (!DL && cy == LINES) wputchar('\n');
#endif NOTERMCAP
/* If he says not to edit, make sure board is OK */
if (!checkbd(b,WHITE) || !checkbd(b,BLACK))
question--;
else
question++;
}
break;
case 9: /* Take an editor command */
if (editbd(b,ob))
question--;
else
{
#ifndef NOTERMCAP
if (cleardown)
{
cursor(1,msgarea);
clbot();
cprint("[default answers shown in brackets]");
wputchar('\n');
msgarea = (cy >= LINES) ? LINES - 1 : cy;
}
else
#endif NOTERMCAP
scrolled = TRUE;
}
break;
case 10: /* Enter Capture Rules */
initmore();
mprint("What is the rule for pieces capturing");
Capture = enterone(captname,HI_CAPTURE,Capture);
break;
case 11:
if (Whiteking != SQ || Blackking != SQ)
{
initmore();
mprint("What is the rule for ");
pkings(mprintf);
mprint(" capturing");
Kcapture = enterone(captname,HI_KCAPTURE,Kcapture);
}
break;
case 12: /* Is this Kriegspiel? */
wprintf("Are enemy pieces visible to player [%s]? ",
yorn(!Kriegspiel));
Kriegspiel = !enterdyn(!Kriegspiel);
break;
case 13: /* May both players castle? */
if (cancastle(b,WHITE) || cancastle(b,BLACK))
{
wprintf("Is castling allowed [%s]? ", yorn(!Oldcastle));
Oldcastle = !enterdyn(!Oldcastle);
}
/* if not possible to castle, just leave option with default */
break;
case 14: /* Old fashioned pawns? */
/* Ask if there are any pawns, ask about pawn moves */
if ((find(b,WP,&r,&c),r != -1) || (find(b,BP,&r,&c),r != -1))
{
wprintf("Can Pawn move double on their first moves [%s]? ",
yorn(!Oldpawn));
Oldpawn = (!enterdyn(!Oldpawn));
}
else
question++;
break;
case 15:
if (Whiteking != WP && Blackking != WP)
{
wprintf("Pawn promotion to %s, %s, %s or %s [%s]? ",
piecename[WQ], piecename[WR], piecename[WB],
piecename[WN], yorn(Promotion==PR_QRBN));
if (enterdyn(Promotion==PR_QRBN))
{
Promotion = PR_QRBN;
question++;
}
}
else
{
Promotion = PR_NONE;
question++;
}
break;
case 16:
if (Whiteking != WM && Blackking != WM)
{
wprintf("Pawn promotion to %s only [%s]? ",
piecename[WM], yorn(Promotion!=PR_NONE));
if (enterdyn(Promotion!=PR_NONE))
Promotion = PR_MINISTER;
else
Promotion = PR_NONE;
}
else
Promotion = PR_NONE;
break;
case 17: /* Select Multiple moves */
if (Capture == CA_CONVERSION || Kcapture == CA_CONVERSION)
{
Whitemoves = Blackmoves = Winitmoves = Binitmoves = 1;
question += 4;
}
else
{
wprintf("Is this a Progressive chess game [%s]? ",
yorn(!Whitemoves));
progress = enterdyn(!Whitemoves);
}
break;
case 18:
wprintf("How many moves on White's first turn [%d]? ",Winitmoves);
Winitmoves = readdint(HI_WIMOVES,Winitmoves);
wputchar('\n');
if (progress)
{
Binitmoves = Whitemoves = Blackmoves = MO_PROGRESS;
question += 3;
}
break;
case 19:
wprintf("How many moves on White's later turns [%d]? ",
Whitemoves);
Whitemoves = readdint(HI_WMOVES,Whitemoves);
wputchar('\n');
break;
case 20:
wprintf("How many moves on Black's first turn [%d]? ",
Binitmoves);
Binitmoves = readdint(HI_BIMOVES,Binitmoves);
wputchar('\n');
break;
case 21:
wprintf("How many moves on Black's later turns [%d]? ",
Blackmoves);
Blackmoves = readdint(HI_BMOVES,Blackmoves);
wputchar('\n');
break;
case 22:
if (Winitmoves > 1 || Binitmoves > 1)
{
wprintf("Must players stay on their own sides on the first turns [%s]? ",yorn(Tabiyat));
Tabiyat = enterdyn(Tabiyat);
}
else
Tabiyat = FALSE;
break;
case 23:
if ((Winitmoves > 1 || Binitmoves > 1 ||
Whitemoves > 1 || Blackmoves > 1 ||
Whitemoves == MO_PROGRESS) &&
(Whiteking != SQ || Blackking != SQ))
{
wprintf("May ");
pkings(wprintf);
wprintf(" move through check [%s]? ",
yorn(Thrucheck));
Thrucheck = enterdyn(Thrucheck);
}
break;
case 24: /* Enter results */
initmore();
mprint("What is the effect of being stalemated");
Staleresult = enterone(resltname,HI_STALE,Staleresult);
break;
case 25:
initmore();
mprint("What is the effect of losing all forces");
if (Blackking != SQ || Whiteking != SQ)
mprint(" except your mateable piece");
Stripresult = enterone(resltname,HI_STRIP,Stripresult);
break;
case 26: /* Must take? */
if (Capture != CA_NONE || Kcapture != CA_NONE)
{
wprintf("Must pieces be captured whenever possible [%s]? ",
yorn(Musttake));
Musttake = enterdyn(Musttake);
}
else
Musttake = FALSE;
break;
case 27: /* Privacy */
if (Kriegspiel)
wprint("To prevent peeking, Kriegspiel games should be private:\n");
wprintf("Would you like the game to be private [%s]? ",
yorn(Kriegspiel));
Private = enterdyn(Kriegspiel);
break;
case 28: /* Computer Kibitzing */
if (!Musttake && !Kriegspiel &&
Capture == CA_NORMAL && Kcapture == CA_NORMAL)
{
wprintf("Would you like the computer to kibitz [Yes]? ");
Help_me = enterdyn(TRUE);
}
else
Help_me = FALSE;
break;
case 29: /* Give him a chance to make another pass */
/* Figure out if anything really got changed */
for (i=4;i<OPTIONS;i++)
if (i != OP_NAMES && i != OP_BOARD &&
option[i] != defopt[Game_type][i])
{
Game_type = TY_MIXED;
break;
}
/* Print out the options */
initmore();
mprint("Options selected:\n");
printopts(mprintf);
mprint("Are these correct? ");
if (enteryn())
question = -100; /* Exit loop */
else
question = -1; /* Restart loop */
break;
default:
wprint("Lost in customization\n");
question = -100;
break;
}
}
#ifndef LSIGNAL
susp1_flg = FALSE;
#endif LSIGNAL
}
int enterone(name,hi,def)
int hi;
char *name[];
int def;
{
register int i;
register char ch;
mprintf(" [%s]:\n",name[def]);
for (i = 0; i <= hi; i++)
mprintf(" (%c) %s\n",i+'A',name[i]);
mprintf("enter (A-%c)? ",hi+'A');
for (;;)
{
if ((ch = getchar()) == '\n' || ch == '\r')
i = def;
else
i = (ch <= 'Z') ? ch - 'A' : ch - 'a';
if (i > hi || i < 0)
bell();
else
break;
}
mprintf("%c - %s\n",i+'A',name[i]);
return(i);
}
/* PKINGS()
*
* Print names of mateable pieces. Don't call this if there are none.
* prtf is the function to print with. mprintf or wprintf or printf.
*/
pkings(prtf)
int (*prtf)();
{
if (Whiteking != SQ)
{
(*prtf)("%ss",pman(Whiteking));
if (Whiteking != Blackking && Blackking != SQ)
(*prtf)(" and %ss",pcolman(-Blackking));
}
else
(*prtf)("%ss", pcolman(-Blackking));
}
/* ACCEPT()
*
* Accept Challange mode. Print options. Accept, Reject or
* Counter-challenge. Write appropriate selection in game file.
* Not in visual mode.
*/
doaccept()
{
boolean first = TRUE;
boolean washidden;
/* Some initialization stuff */
washidden = hidden;
hidden = FALSE;
#ifndef LSIGNAL
susp1_flg = TRUE;
setjmp(susp_env);
#endif LSIGNAL
scrolled = TRUE;
for (;;)
{
if (scrolled)
{
disp(b,kibitz?WHITE:mycolor);
wputchar('\n');
msgarea = (cy >= LINES) ? LINES - 1 : cy;
}
if (first)
{
initmore();
if (kibitz)
{
if (moveok)
mprintf("%s has been challenged by %s",myid,hisid);
else
mprintf("%s has been challenged by %s",hisid,myid);
}
else
{
if (moveok)
mprintf("You have been challenged by %s",hisid);
else
mprintf("You have challenged %s",hisid);
}
mprint(" to a game of correspondence chess\nwith the following options:\n\n");
printopts(mprintf);
if (!moveok)
{
#ifndef LSIGNAL
susp1_flg = FALSE;
#endif LSIGNAL
hidden = washidden;
return;
}
mprint("Help, ");
first = FALSE;
}
mprint("Accept, Reject or Counter-Challenge? ");
switch (xenter("LACRVOH?EQ\014"))
{
case 'H': /* Offer help */
case '?':
wprint("Help\n");
initmore();
mprint(" A - Accept this cchess challenge\n");
mprint(" R - Reject this cchess challenge\n");
mprint(" C - Counter-challenge with different options\n");
mprint(" O - Print the options again\n");
mprint(" L - Print date of challenge\n");
mprint("^L - Redraw display\n");
mprint(" Q - Quit the program without doing anything\n");
break;
case '\014':
wprint("Redraw\n");
scrolled = TRUE;
break;
case 'L':
wprintf("Last challenge made on %s\n",cday(lastday));
break;
case 'O': /* Redisplay the options */
wprint("Options\n");
initmore();
printopts(mprintf);
break;
case 'Q': /* Quit */
wprint("Quit\n");
return;
case 'E': /* Exit */
wprint("Exit\n");
return;
case 'A': /* challenge accepted */
wprint("Accept\n");
#ifndef LSIGNAL
susp1_flg = FALSE;
#endif LSIGNAL
status = 3;
fprintf(wfp,"%5ld:A \n",day());
/* mail message */
sprintf(cbuffer,
"Your challenge has been accepted. Run \042%s %s\042.\n",
RUN_CMD,myid);
mesg("Cchess Challenge Accepted",cbuffer);
hidden = washidden;
return;
case 'R': /* challenge rejected */
wprint("Reject\n");
#ifndef LSIGNAL
susp1_flg = FALSE;
#endif LSIGNAL
unlink(fname);
mesg("Cchess Challenge Rejected",
"Your challenge has been rejected.\n");
return;
case 'C': /* counter challenge */
wprint("Challenge\n");
#ifndef LSIGNAL
susp1_flg = FALSE;
#endif LSIGNAL
clr();
dochallenge(TRUE);
return;
case 'V': /* version command */
versprint();
break;
}
}
}
/* EDITBD()
*
* Edit a board set up. Board ob is passed in with the original arrangment.
* Board nb is the current set up. Upon return, it contains the edited set up.
* The global board, bc should be a copy of nb. This reads just one command.
* It returns FALSE if the last command was a quit.
*/
boolean editbd(nb,ob)
schar nb[R_SIZE][C_SIZE];
schar ob[R_SIZE][C_SIZE];
{
short ox, oy;
int row,col,i;
char buf[40],*name;
char ch,cmd;
schar piece;
char *tp;
/* Prompt for a command */
wprint("Place, Delete or Quit? ");
cmd = xenter("PDUEQVH?\014");
switch (cmd)
{
case 'H':
case '?':
wprint("Help\n");
wprint("Would you like a list of commands? ");
if (enteryn())
{
initmore();
mprint("Place - Put a piece on a square\n");
mprint("Delete - Remove a piece from board\n");
mprint("Undo - Undo all changes to board\n");
mprint("Quit - Exit board edit mode\n");
mprint("^L - Redraw the screen\n");
}
wprint("Would you like a list of pieces? ");
if (enteryn())
{
initmore();
for (i=1;i<PIECES;i+=2)
mprintf(" %c = %-9.9s %c = %-9.9s\n",
pc[PIECES-i],piecename[i],
pc[PIECES-i-1],piecename[i+1]);
#if (PIECES % 2) == 1
mprintf(" %c = %-9.9s\n",
pc[0],piecename[PIECES]);
#endif
}
break;
case 'P':
wprint("Place\n");
/* Get the piece */
wprint("What Type of Piece (upper case for black)? ");
for (;;)
{
ch = getchar();
if (ch == '\n' || ch == '\r') break;
if (ch == 'p') ch = 'i';
else if (ch == 'P') ch = 'I';
if ((tp = index(pc,ch)) != 0) break;
bell();
}
if (ch == '\n' || ch == '\r')
{
wputchar('\n');
break;
}
piece = (tp-pc)-PIECES;
wprint(name = pcolman(piece));
/* Get the position */
wprintf("\nWhere should the %s be placed? ",name);
case 'D':
if (cmd == 'D')
{
piece = SQ;
wprint("Delete\nFrom what position? ");
}
if (!pread(buf)) break;
col = buf[0] - 'A';
row = buf[1] - '1';
wputchar('\n');
if (cmd == 'D' && nb[row][col] == SQ)
{
wprintf("No piece at %2.2s\n",buf);
break;
}
/* Make the change to the board copy */
bc[row][col] = piece;
/* Display the new position */
#ifndef NOTERMCAP
if (!scrolled && issmart)
{
ox = cx; oy = cy;
update(nb,bc);
cursor(ox,oy);
}
else
{
#endif NOTERMCAP
disp(bc, kibitz ? WHITE : mycolor);
wputchar('\n');
#ifndef NOTERMCAP
}
#endif NOTERMCAP
/* Make the change to the real board */
nb[row][col] = piece;
break;
case 'U':
wprint("Undo\n");
if (compare(nb,ob))
{
wprint("No changes have been made\n");
break;
}
wprint("Do you want to undo all changes? ");
if (!enteryn()) break;
#ifndef NOTERMCAP
if (!scrolled && issmart)
{
ox = cx; oy = cy;
update(nb,ob);
cursor(ox,oy);
}
else
#endif NOTERMCAP
scrolled = TRUE;
copy(ob,nb);
copy(ob,bc);
break;
case 'Q': /* Quit */
wprint("Quit\n");
case 'E': /* Exit */
if (cmd == 'E') wprint("Exit\n");
#ifndef NOTERMCAP
if (!DL && cy == LINES) wputchar('\n');
#endif NOTERMCAP
/* Make sure we got a sane board */
if (!(checkbd(nb,WHITE) && checkbd(nb,BLACK))) break;
/* Confirm that he is really done */
wprint("Are you sure you're done editing? ");
if (!enteryn()) break;
return(FALSE);
case '\014': /* Control-L redraws the screen */
wprint("Redraw\n");
scrolled = TRUE;
break;
case 'V': /* Version */
versprint();
break;
}
return(TRUE);
}
/* CHECKBD()
*
* Check if an edited board is a reasonable one. This is currently
* a bit too strict. It should really only check if the second player
* is in check, or the first player is stalemated.
*/
boolean checkbd(nb,color)
schar nb[R_SIZE][C_SIZE];
schar color;
{
int row,col;
register int r,c;
schar myking = Kingpiece(color);
if (myking != SQ)
{
/* Find a King */
switch (piececount(nb,myking,&row,&col))
{
case 0:
wprintf("No %s on board\n",pcolman(myking));
return(FALSE);
case 2:
wprintf("Too many %ss on the board\n",pcolman(myking));
return(FALSE);
}
if (check(nb,-color,row,col))
{
wprintf("%s is in check\n",pcolman(myking));
return(FALSE);
}
}
else
{
/* Make sure you have at least some sort of piece */
for (r=0;r<=Rows;r++)
for (c=0;c<=Cols;c++)
if (nb[r][c]*color > 0)
goto ok;
wprintf("No %s pieces on board\n",pcol(color));
return(FALSE);
}
ok: if(!canmove(nb,color,FALSE))
{
wprintf("%s cannot move\n",pcol(color));
return(FALSE);
}
return(TRUE);
}
/* PIECECOUNT
*
* Return 0 if there are no pieces of the type, 1 if there is exactly one,
* or 2 if there are more than one. The location of the first one found
* is returned in the last two.
*/
int piececount(nb,piece,row,col)
schar nb[R_SIZE][C_SIZE];
schar piece;
int *row,*col;
{
register int r,c,tcol;
/* Find one Piece */
find(nb,piece,row,col);
if (*row == -1)
return(0);
/* Any more of them? */
tcol = *col;
for (r = *row;r <= Rows;r++)
{
for (c=tcol+1; c<=Cols; c++)
if (nb[r][c] == piece)
return(2);
tcol = -1;
}
return(1);
}
/* CANCASTLE
*
* If there is a sensible way to castle on the current board?
*/
cancastle(nb,color)
schar nb[R_SIZE][C_SIZE];
schar color;
{
int row,col;
/* There is exactly one king of this color */
if (piececount(nb,color*WK,&row,&col) != 1)
return(FALSE);
/* There is a rook of the same color at one of the margins */
return (nb[row][0] == color*WR || nb[row][Cols] == color*WR);
}
versprint()
{
wprintf("Version %s %s\n",version,copyright);
}