|
|
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 c
Length: 24364 (0x5f2c)
Types: TextFile
Names: »cmd.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Cchess/cmd.c«
/* CCHESS USER INTERFACE version 1.00
*
* (C) Copyright - Jan D. Wolter - Apr 1986
*
* Mostly routines to talk to the user.
*/
#include "cchess.h"
#ifndef NOTERMCAP
extern char *DL;
#endif NOTERMCAP
int mredraw; /* flag used for redrawing while reading in move */
/* DOMOVE()
*
* This is the move mode driver. Show board and command menu. Accept
* move, forfiet, draw, and playback commands. This is the real center of
* the program.
*
* If <drawp> is RE_DRAW, then a draw has been proposed, and the options are
* to accept or reject the draw. If <drawp> is RE_CANCEL, then a cancelation
* has been proposed, and the same commands are available.
*/
domove(drawp)
int drawp;
{
int fr,fc,tr,tc;
int row,col;
char new_move[15];
char ch;
schar took,p;
boolean thru,himcheck,checked,firsttime=TRUE;
int i;
new_move[C_CMD] = 'M';
new_move[C_MAT] = ' ';
myillmoves = 0;
scrolled = TRUE;
mredraw = 0;
must_take = Musttake && canmove(b,mycolor,TRUE);
/* Loop until he is satisfied with a command */
for (;;)
{
#ifndef NOTERMCAP
/* make sure there is room for an error message */
if (moveok && errcode != E_OK && errcode != E_SY)
{
if (!DL && cy == LINES)
wputchar('\n');
}
else
errcode = E_OK;
#endif NOTERMCAP
/* draw board - "scrolled" basically just tells us to do so */
if (scrolled)
{
disp(b,kibitz?WHITE:mycolor);
printmov(mbuffer,illmoves,(mycolor == toplay) ? hisid : myid);
printcom();
wputchar('\n');
if (cy >= LINES)
msgarea = LINES - 1;
else
msgarea = cy;
}
/* Prompt for a command */
if (!moveok)
{
/* Not allowed to move - Playback or nothing */
if (!kibitz) wprint("It's not your turn to move.\n");
wprint("Do you want a playback? ");
ch = xenter("YNVOL\014");
if (ch == 'Y')
{
ch = 'P';
wprint("Yes\n");
}
if (ch == 'N')
{
ch = 'Z';
wprint("No\n");
}
}
else if (drawp == RE_NONE)
{
/* Normal case - Get a move command */
if (errcode != E_OK)
{
prterror();
wputchar('\n');
}
errcode = E_OK;
if (firsttime)
{
if (movecnt < 2)
wprint("Help, ");
else if (tamemoves >= MAXTAME)
wprint("Under the 50-move rule, you may unilaterally declare a draw.\n");
firsttime = FALSE;
}
wprint("Move, Playback, Forfeit or Draw? ");
if (mredraw > 0)
ch = 'M';
else
ch = xenter("MPFDECQVH?OL\014");
}
else
{
/* A draw or cancellation has been proposed */
if (drawp == RE_DRAW)
wprint("A draw");
else
wprint("A cancellation");
wprint(" has been proposed.\nAccept or Reject? ");
ch = xenter("PARVEQOL\014");
}
switch (ch)
{
case 'H':
case '?':
wprint("Help\n");
initmore();
mprint("Move - Enter a chess move\n");
mprint("Playback - View a replay of previous moves\n");
mprint("Forfeit - Admit that the other player won\n");
mprint("Draw - Propose that the game be a draw\n");
mprint("Last - Display date of last move made\n");
mprint("Options - Display the current game options\n");
mprint("^L - Redraw the screen\n");
mprint("Exit - Exit the program without moving\n");
mprint("Cancel - Propose that the game be abandoned\n");
break;
case 'L':
wprintf("Last move made on %s\n", cday(lastday));
break;
case 'O':
wprint("Options\n");
initmore();
printopts(mprintf);
break;
case 'M':
wprint("Move\n");
++consmade;
took = taken;
checked = incheck;
/* Get his move */
mget(mycolor,new_move+C_MOV,&fr,&fc,&tr,&tc);
if (mredraw > 0)
{
scrolled = TRUE;
--consmade;
break;
}
/* If it's an illegal move, give it up */
if (!(thru = (errcode==E_MC && consmade < consmoves && Thrucheck)))
{
if (errcode == E_OK)
wputchar('\n');
else
{
consmade--;
break;
}
}
/* Test if other player is in check */
if (Kingpiece(-mycolor) != SQ)
{
find(bc,Kingpiece(-mycolor),&row,&col);
himcheck = check(bc,mycolor,row,col);
}
else
himcheck = FALSE;
/* Has enemy been stripped of all forces? */
if (Stripresult != RE_NONE && taken != SQ && !forces(-mycolor,bc))
{
stripped = TRUE;
wprint("Capture of all enemy pieces ");
switch (Stripresult)
{
case RE_LOSE:
wprintf("is a win for you.\n");
break;
case RE_WIN:
wprintf("is a win for the other player.\n");
break;
case RE_DRAW:
wprintf("forces a draw.\n");
break;
}
}
else if (consmade < consmoves)
{
/* May not apply check until last move */
if (himcheck)
{
errcode = E_MM;
consmade--;
break;
}
repeated = inmate = FALSE;
incheck = thru;
}
else
{
/* Test if other player is in mate */
incheck = himcheck;
inmate = !canmove(bc,-mycolor,FALSE);
/* How often has this position has occured? */
if (inmate || !istame || tamemoves >= MAXTAME-1)
repeated = FALSE;
else
repeated = isrepeat(b,bc);
}
dispnew: /* Display the new position */
#ifndef NOTERMCAP
if (!scrolled && issmart && (!Kriegspiel || !inmate))
doupdate(b,bc,new_move,TRUE);
else
{
#endif NOTERMCAP
if (inmate) hidden = FALSE;
disp(bc, kibitz ? WHITE : mycolor);
printmov(new_move,myillmoves,hisid);
printcom();
wputchar('\n');
#ifndef NOTERMCAP
}
#endif NOTERMCAP
/* Warn him about effects of stalemate */
if (inmate && !incheck)
{
wprint("Stalemate ");
switch(Staleresult)
{
case RE_WIN:
wprint("is a win for the other player.\n");
break;
case RE_LOSE:
wprint("is a win for you.\n");
break;
case RE_DRAW:
wprint("forces a draw.\n");
break;
}
}
/* Let him declare a draw under fifty move rule */
if (repeated)
{
wprint("This position has occurred twice before.\n");
wprint("Would you like to declare a draw?");
repeated = (enteryn());
}
/* Give him a chance to change his mind */
if (!Kriegspiel)
{
if (Help_me && (consmade == consmoves) &&
(p = compkib(bc,mycolor)) != SQ)
wprintf("Your %s may be at risk.\n", piecename[p]);
wprint("Are you sure? ");
if ((ch = enter("YN\014")) == '\014')
{
/* Redraw the screen */
scrolled = TRUE;
goto dispnew;
}
if (ch == 'N')
{
/* Don't make this move after all */
wprint("o\n");
taken = took;
incheck = checked;
consmade--;
inmate = FALSE;
stripped = FALSE;
errcode = E_OK;
#ifndef NOTERMCAP
if (issmart)
doupdate(bc,b,mbuffer,FALSE);
else
#endif NOTERMCAP
scrolled = TRUE;
break;
}
else
wprint("es\n");
}
savemove((consmoves == consmade || stripped)?'M':'m',
new_move+C_MOV);
/* Finish off ended games */
if (inmate || repeated || stripped)
{
copy(bc,b); /* So playbacks will work right */
if (incheck && inmate)
askplayback(RE_WIN,EV_CHECKMATE);
else if (inmate)
askplayback(flip(Staleresult),EV_STALEMATE);
else if (stripped)
askplayback(flip(Stripresult),EV_FORCES);
else
askplayback(RE_DRAW,EV_REPEATED);
asktrans();
return;
}
if (consmoves == consmade)
return;
else
{
/* Multi-move game: ask him for another */
errcode = E_OK;
copy(bc,b);
must_take = Musttake && canmove(b,mycolor,TRUE);
break;
}
case 'F':
wprint("Forfeit\nDo you want to forfeit? ");
if (!enteryn()) break;
if (Kriegspiel)
{
hidden = FALSE;
disp(bc, kibitz ? WHITE : mycolor);
printmov(new_move,myillmoves,hisid);
printcom();
wputchar('\n');
}
savemove('F',"forf ");
askplayback(RE_LOSE,EV_FORFIET);
asktrans();
return;
case 'D': /* Propose Draw */
wprintf("Draw\nDo you want to %s a draw? ",
(tamemoves >= MAXTAME)?"declare":"propose");
if (!enteryn()) break;
savemove('D',"draw?");
/* Unilateral if more than fifty moves have been made */
if (tamemoves >= MAXTAME)
{
askplayback(RE_DRAW,EV_FIFTYMOVES);
asktrans();
}
return;
case 'C': /* Propose Cancelation */
wprint("Cancel\n");
wprint("Do you want to propose that this game be discarded? ");
if (!enteryn()) break;
savemove('K',"canc?");
return;
case 'A': /* Accept Draw or Cancellation */
wprint("Accept\n");
savemove('Y',"yes ");
askplayback(drawp,EV_AGREEMENT);
asktrans();
return;
case 'R': /* Reject Draw or Cancellation */
wprint("Reject\n");
savemove('N',"no ");
return;
case 'Q': /* Quit */
wprint("Quit\n");
case 'E': /* Exit */
if (ch == 'E') wprint("Exit\n");
if (!interupt)
{
wprint("Sorry, not until you've moved...");
break;
}
wprint("Do you really want to ");
if (eachgame)
wprint("skip to the next game? ");
else
wprint("exit the program? ");
if (!enteryn()) break;
case 'Z': /* Exit without asking for confirmation */
return;
case 'P': /* Playback previous positions */
if (moveok) wprint("Playback\n");
if (playcnt == 0)
{
wprint("No moves to Playback.\n");
break;
}
wprintf("How many moves (1-%d) do you want replayed? ",
playcnt+(consmade > 0));
if ((i=readint(playcnt + (consmade > 0))) > 0)
{
if (!issmart) wputchar('\n');
playback(playcnt - i + (consmade > 0));
}
wputchar('\n');
/* If move arrives during replay...experiment */
if (!moveok && !kibitz && mycolor == toplay)
{
moveok = TRUE;
fseek(wfp,0L,2);
}
break;
case '\014': /* Control-L redraws the screen */
wprint("Redraw\n");
scrolled = TRUE;
break;
case 'V': /* Version */
versprint();
break;
}
}
}
/* DOMATE()
*
* End a game. There has been a checkmate, or the game has been drawn.
*
* <what> is RE_WIN, RE_LOSE, RE_DRAW, or RE_CANCEL depending on what
* became of the current player.
*
* <why> is EV_CHECKMATE, EV_STALEMATE, EV_FORCES, EV_FIFTYMOVES, EV_REPEATED,
* or EV_AGREEMENT depending on why the game ended.
*/
domate(what,why)
char what,why;
{
disp(b,kibitz?WHITE:mycolor);
printmov(mbuffer,illmoves,(mycolor == toplay) ? hisid : myid);
printcom();
wputchar('\n');
askplayback(what,why);
if (moveok)
{
/* MUST do the endgame *before* the transcript, */
/* curious though it seems. */
endgame(what);
asktrans();
}
}
/* ASKPLAYBACK()
*
* Ask the player for a playback, and keep asking him until he doesn't want one.
* Print the message before asking each time. It displays both sides, even if
* the game is kriegspiel. It is only meant to be called after a game is over.
*
* <what> is RE_WIN, RE_LOSE, RE_DRAW, or RE_CANCEL depending on what
* became of the current player.
*
* <why> is EV_CHECKMATE, EV_STALEMATE, EV_FORCES, EV_FIFTYMOVES, EV_REPEATED,
* or EV_AGREEMENT depending on why the game ended.
*/
askplayback(what,why)
char what,why;
{
static char tbuf[70];
boolean flag;
int i;
if (hidden) scrolled = TRUE;
hidden = FALSE; /* No reason to hide moves anymore */
switch (what)
{
case RE_WIN:
if (solo && !kibitz)
strcpy(tbuf,"Congratulations!\nYou have won");
else
sprintf(tbuf,"%s has won",
(mycolor == toplay) ? myid : hisid);
break;
case RE_LOSE:
if (solo && !kibitz)
strcpy(tbuf,"You have lost");
else
sprintf(tbuf,"%s has won",
(mycolor != toplay) ? myid : hisid);
break;
case RE_DRAW:
strcpy(tbuf,"The game is drawn");
break;
case RE_CANCEL:
strcpy(tbuf,"The game is canceled");
break;
}
switch (why)
{
case EV_CHECKMATE:
strcat(tbuf," by a checkmate.");
break;
case EV_STALEMATE:
strcat(tbuf," by a stalemate.");
break;
case EV_FORCES:
strcat(tbuf," by lose of forces.");
break;
case EV_FIFTYMOVES:
strcat(tbuf," under the fifty move rule.");
break;
case EV_REPEATED:
strcat(tbuf," because of repeated positions.");
break;
case EV_AGREEMENT:
strcat(tbuf," by mutual agreement.");
break;
case EV_FORFIET:
strcat(tbuf," by a forfieting.");
break;
}
do
{
wprint(tbuf);
if (playcnt == 0 && consmade == 0)
{
wputchar('\n');
return;
}
wprint("\nDo you want a playback? ");
if (flag = enteryn())
{
wprintf("How many moves (1-%d) do you want replayed? ",
playcnt+(consmade > 0));
if ((i=readint(playcnt + (consmade > 0))) > 0)
{
if (!issmart) wputchar('\n');
playback(playcnt - i + (consmade > 0));
wputchar('\n');
}
}
} while (flag);
}
#ifndef NOTERMCAP
/* DOUPDATE()
*
*Update() plus update the labels on the display.
*
*/
doupdate(bo,bn,move,mine)
schar bo[R_SIZE][C_SIZE], bn[R_SIZE][C_SIZE];
char *move;
boolean mine;
{
short ox=cx, oy=cy;
update(bo,bn);
printmov(move,mine?myillmoves:illmoves,mine?myid:hisid);
cursor(ox,oy);
}
#endif NOTERMCAP
/* MGET()
*
* Read a possibly illegal move from the player. Set the error code if he
* Gave an illegal response. Note that E_SY can only result if he hits
* return prematurely. It is not really an error; it is used as a command
* cancellation.
*/
mget(co,buffer,fr,fc,tr,tc)
char *buffer;
int *fr,*fc,*tr,*tc; /* from (row, column) to (row, column) */
int co;
{
char ch;
if (consmoves > 1)
wprintf("Enter your move (%d of %d): ",consmade,consmoves);
else
wprint("Enter your move: ");
if (mread(buffer))
if (mconv(buffer,fr,fc,tr,tc) &&
legal(co,*fr,*fc,*tr,*tc))
{
if (promote)
{
/* Patch up pawn promotion */
if (Promotion == PR_MINISTER)
/* Only Ministers can be promoted to */
bc[*tr][*tc] = promote = WM*co;
else if (Promotion == PR_NONE)
/* Can't Promote */
bc[*tr][*tc] = promote = WP*co;
else
{
/* Ask the player what to promote to */
for(;;)
{
wputchar('\n');
wprint("Promote pawn to: ");
if ((ch = xenter("QRBNK\014"))=='\014')
{
errcode = E_OK;
mredraw = 5;
return;
}
promote = PIECES-(index(pc,ch)-pc);
wprint(piecename[promote]);
if (promote != Kingtype(co))
break;
wprint("\nCan't promote to mateable piece");
}
bc[*tr][*tc] = promote *= co;
}
}
errcode = E_OK;
return;
}
else /* Illegal move */
{
/* Unless he should have know better, record it */
if (Kriegspiel &&
( (errcode == E_CP) || (errcode == E_CT) ||
(errcode == E_PI) || (errcode == E_QB) ||
(errcode == E_BB) || (errcode == E_BR) ||
(errcode == E_MC) || (errcode == E_MM) ) )
{
interupt = FALSE;
myillmoves++;
fprintf(wfp,"%5ld:I %5.5s\n",day(),buffer);
}
wputchar('\n');
}
else
if (mredraw == 0)
errcode = E_SY;
return;
}
/* PERROR()
*
* Print error messages. Current error is given by the global errcode.
*/
/* Three common messages */
static char kierrmsg[] = "Illegal Move.";
static char kcerrmsg[] = "Can't Castle.";
static char scerrmsg[] = "Castling has not been invented.";
prterror()
{
/* If no error, do nothing */
if (errcode == E_OK) return;
wprint("Error: ");
switch (errcode)
{
case E_MT: /* move from empty square */
wprint("No friendly piece in starting square.");
break;
case E_AF: /* attack on friendly piece */
wprint("Can't capture your own pieces.");
break;
case E_EQ: /* source and destination square are equal */
wprint("Null move.");
break;
case E_SY: /* Move syntax error */
wprint("Command syntax unrecognizable.");
break;
case E_CR:
wprint("Must capture if possible.");
break;
case E_NC:
wprint("Piece may not capture.");
break;
case E_CP:
if (Oldcastle)
wprint(scerrmsg);
else if (hidden)
wprint(kcerrmsg);
else
wprint("Not in position to castle.");
break;
case E_CM:
if (Oldcastle)
wprint(scerrmsg);
else
wprint("Can't castle after moving king or rook.");
break;
case E_CT:
if (Oldcastle)
wprint(scerrmsg);
else if (hidden)
wprint(kcerrmsg);
else
wprint("Can't castle through or out of check.");
break;
case E_MC: /* Move into Check */
if (hidden)
wprint(kierrmsg);
else
wprint("Move leaves you in check.");
break;
case E_MM: /* No Check on Multi-Moves */
if (hidden)
wprint(kierrmsg);
else
wprint("Can't apply check until last move.");
break;
case E_CC: /* Ta'biyat violation */
wprint("Can't cross center on first turn.");
break;
case E_IL: /* Illegal move */
wprint(kierrmsg);
break;
case E_KI: /* Illegal move of King or Jester */
case E_JI:
wprintf("%s moves only to adjacent squares.",
piecename[errcode & 033]);
break;
case E_QI: /* Illegal move of Queen */
wprintf("%s moves only along rows, columns and diagonals.",
piecename[WQ]);
break;
case E_BI: /* Illegal move of Bishop */
wprintf("%s moves only along diagonals.",piecename[WB]);
break;
case E_NI: /* Illegal move of Knight */
wprintf("%s moves two squares straight and one to the side.",
piecename[WN]);
break;
case E_RI: /* Illegal move of Rook */
wprintf("%s moves only along rows or columns.",piecename[WR]);
break;
case E_PI: /* Illegal move of Pawn */
if (hidden)
wprint(kierrmsg);
else
wprintf("%s moves forward or captures diagonally.",
piecename[WP]);
break;
case E_MI: /* Illegal move of Minister */
wprintf("%s moves only to diagonally adjacent squares.",
piecename[WM]);
break;
case E_EI: /* Illegal move of Elephant */
wprintf("%s moves two squares diagonally.",piecename[WE]);
break;
case E_DI: /* Illegal move of Duke */
wprintf("%s moves only to orthogonally adjacent squares.",
piecename[WD]);
break;
case E_HI: /* Illegal move of Maharajah */
wprintf("%s moves like knight or like queen.",piecename[WH]);
break;
case E_KB: /* Blocked move of Kamikazi King */
if (hidden)
wprint(kierrmsg);
else
wprintf("%s can't capture in this version of chess.",
piecename[WK]);
break;
case E_QB: /* Blocked move of Queen */
case E_BB: /* Blocked move of Bishop */
case E_BR: /* Blocked move of Rook */
case E_BH: /* Blocked move of Maharajah */
if (hidden)
wprint(kierrmsg);
else
wprintf("%s can't jump over other pieces.",
piecename[errcode & 033]);
break;
default:
wprintf("Weird Error %d.",errcode);
}
}
/* MREAD()
*
* Read a move from the terminal, return FALSE if player chickens out
* or asks for a redraw. In the latter case, mredraw is set. Supports
* backspaces. Sorry Edsger.
*/
char nums[] = "87654321\b\n\014";
char lets[] = "LKJIHGFEDCBA\b\n\014";
mread(buffer)
REGISTER char *buffer;
{
register int m;
short ox=cx;
if (mredraw > 0)
{
m = mredraw;
mredraw = 0;
if (m == 1) goto n0;
wputchar(buffer[0]);
if (m == 2) goto n1;
wputchar(buffer[1]);
wputchar('-');
if (m == 3) goto n2;
wputchar(buffer[3]);
if (m == 4) goto n3;
wputchar(buffer[4]);
return(TRUE);
}
n0: buffer[0] = enter(&lets[C_SIZE-1-Cols]);
switch (buffer[0])
{
case '\b':
bell();
wputchar(' ');
goto n0;
case '\014':
mredraw = 1;
case '\n':
return (FALSE);
}
n1: buffer[1] = enter(&nums[R_SIZE-1-Rows]);
switch (buffer[1])
{
case '\b':
if (erases)
{
wputchar(' ');
backspace();
}
else
indent(ox-1);
goto n0;
case '\014':
mredraw = 2;
case '\n':
return (FALSE);
}
buffer[2] = '-';
wputchar('-');
n2: buffer[3] = enter(&lets[C_SIZE-1-Cols]);
switch (buffer[3])
{
case '\b':
if (erases)
{
backspace();
wprint(blanks(2));
backspace();
backspace();
}
else
{
indent(ox-1);
wputchar(buffer[0]);
}
goto n1;
case '\014':
mredraw = 3;
case '\n':
return (FALSE);
}
n3: buffer[4] = enter(&nums[R_SIZE-1-Rows]);
switch (buffer[4])
{
case '\b':
if (erases)
{
wputchar(' ');
backspace();
}
else
{
indent(ox-1);
wputchar(buffer[0]);
wputchar(buffer[1]);
wputchar(buffer[2]);
}
goto n2;
case '\014':
mredraw = 4;
case '\n':
return (FALSE);
}
return(TRUE);
}
/* PREAD()
*
* Read a position from the terminal, return FALSE if player chickens out.
* Supports backspaces. Sorry Edsger.
*/
pread(buffer)
char *buffer;
{
short ox=cx;
n0: buffer[0] = enter(&lets[C_SIZE-1-Cols]);
if (buffer[0] == '\b')
{
bell();
wputchar(' ');
goto n0;
}
if (buffer[0] == '\n') return (FALSE);
buffer[1] = enter(&nums[R_SIZE-1-Rows]);
if (buffer[1] == '\n') return (FALSE);
if (buffer[1] == '\b')
{
if (erases)
{
wputchar(' ');
backspace();
}
else
indent(ox-1);
goto n0;
}
return(TRUE);
}
/* PLAYBACK()
*
* Display a playback of the game.
*/
playback(n)
REGISTER int n;
{
int fr,fc,tr,tc;
register int cnt,subcnt=0;
int ill = 0;
boolean wasmoveok;
char probuf[15];
char c;
boolean prompt = FALSE;
boolean didmove = FALSE;
if (n < 0)
{
wputchar('\n');
return;
}
rewind(rfp);
wasmoveok = moveok;
moveok = FALSE;
/* Read in the initial placement */
do
{
if (fgetl(mbuffer,MB_LEN,rfp)==NULL)
{
printf("Panic: No accept line\n");
done(1);
}
if (mbuffer[C_CMD] == 'C')
copy(ib,bc);
else if (mbuffer[C_CMD] == 'P')
place(bc,mbuffer[C_MOV],mbuffer+C_MOV+2);
} while (mbuffer[C_CMD] != 'A');
cnt = 0;
toplay = WHITE;
for (;;)
{
/* Prompt the user */
if (prompt)
{
cprint("*Hit return for next board:");
c=xenter("\nQ\014");
if (!issmart) wputchar('\n');
if (c != '\n')
if (c == 'Q')
{
/* No more updates or prompts */
n = playcnt + (consmade > 0);
prompt = FALSE;
}
else
{
/* Redraw the screen */
disp(b,kibitz?WHITE:mycolor);
wprint("\n\n");
continue;
}
}
/* Display the position */
if (cnt >= n || (cnt == playcnt && consmade == subcnt))
{
#ifndef NOTERMCAP
if (cleardown && !scrolled)
{
update(b,bc);
if (didmove)
printmov(mbuffer,ill,
toplay == mycolor ? hisid : myid);
clbot();
}
else
{
#endif NOTERMCAP
disp(bc,kibitz?WHITE:mycolor);
if (didmove)
printmov(mbuffer,ill,
toplay == mycolor ? hisid : myid);
#ifndef NOTERMCAP
}
#endif NOTERMCAP
prompt = TRUE; /* Prompt after a redraw */
copy(bc,b);
if (cnt != 0)
printcom();
else
wputchar('\n');
}
ill = 0;
/* Read until we find a move line */
for( ; ; )
{
if (fgetl(mbuffer,MB_LEN,rfp)==NULL)
{
moveok = wasmoveok;
return;
}
if (mbuffer[C_CMD] == 'I')
ill++;
else if (mbuffer[C_CMD] != 'R')
break;
}
didmove = TRUE;
if (mbuffer[C_CMD] == 'm' || mbuffer[C_CMD] == 'M')
{
/* Checked or Mated? */
incheck = (mbuffer[C_MAT] == 'C' || mbuffer[C_MAT] == 'M');
inmate = (mbuffer[C_MAT] == 'M' || mbuffer[C_MAT] == 'S');
/* Play it on the board */
if (mconv(mbuffer+C_MOV,&fr,&fc,&tr,&tc))
{
makemove(bc,toplay,fr,fc,tr,tc,FALSE);
if (promote)
{
fgetl(probuf,14,rfp);
bc[tr][tc] = promote =
toplay*(PIECES-(index(pc,probuf[C_MOV])-pc));
}
}
else
{
wprint("Format error: Bad move syntax.\n");
done(1);
}
}
if (mbuffer[C_CMD] != 'm')
{
cnt++;
subcnt = 0;
toplay = -toplay;
}
else
subcnt++;
}
}
/* ASKTRANS()
*
* Give him a transcript, if he wants one.
*/
asktrans()
{
wprint("Do you want a transcript of the game? ");
if (enteryn()) trans(hidden);
}
/* TRANS()
*
* Ask what sort of transcript he wants. In visual mode.
* If <masked> is true, don't print the other players moves.
*/
trans(masked)
{
FILE *tfp;
char tfile[80];
boolean comments;
clr();
wprintf("Printing transcript for game between %s and %s\n",
myid,hisid);
/* Revert to self so output files can be opened */
/* Note: Can't open game files any more after this */
setuid(getuid());
setgid(getgid());
/* Get output device */
for (;;)
{
wprint("\nDo you want it in a file? ");
if (!enteryn())
{
tfp = stdout;
break;
}
else
{
wprint("Enter the filename: ");
if (!readstr(tfile,0,79,TRUE)) continue;
if ((tfp = fopen(tfile,"w")) == NULL)
wprintf("Cannot open %s\n",tfile);
else
break;
}
}
wprint("Do you want comments included? ");
comments = enteryn();
/* In the future, ask about format */
cctrans(tfp,comments,masked);
}