|
|
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 r
Length: 11050 (0x2b2a)
Types: TextFile
Names: »readmove.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Draughts/readmove.c«
#include <stdio.h>
#include "damdefs.h"
/* read move; the intended format is
nn-mm
or
nnxmm
or
nnxmm(q1,...,qt)
*/
extern int dirt,prall,possct,captmax,captct,timew,timeb,timemax;
extern long lseek();
extern int optp,rdif,disp,playw,playb,me,optg,optu,optf;
extern unsigned prbwait;
extern int rdifmin,altermv,fplevel,rdmin;
extern int *mp,*mpf,conv[],bord[],moves[],mvnr,*findmove();
extern char *dsparr[],*emparr[],*fularr[],prtarr[];
int valstone[5] = {
EMPTY,WHITE,BLACK,WHITE|DAM,BLACK|DAM
};
#define LINSIZ 82
char line[LINSIZ]; /* terminal input line */
char ofile[LINSIZ]; /* output filename */
char ch, *ach;
#define ERRCHAR '\177'
rdlin(){
register char *lp;
register int c;
lp = line;
while((c = getchar()) != '\n'){
if(c == EOF) error("end of input");
if(lp == line+LINSIZ-1){
lp--;
c = ERRCHAR;
}
*lp++ = c;
}
*lp = 0;
ach = line;
}
newchar(){
return(ch = *ach++);
}
answer(){
ask:
rdlin();
switch(newchar()){
case '!':
rdcomd(line);
goto ask;
case 'j':
case 'y':
return(1);
case 'n':
return(0);
default:
pmesg("answer 'y' or 'n'\n");
goto ask;
}
}
skipspaces(){
while((ch == ' ') || (ch == '\t')) newchar();
}
rnum(){
int num;
num = 0;
skipspaces();
while(digit()) {
num = 10*num + (ch - '0');
newchar();
}
return(num);
}
digit(){
return((ch >= '0') && (ch <= '9'));
}
letter(){
register char c;
c = ch|040;
return((c >= 'a') && (c <= 'z'));
}
readnum(){
int num;
num = rnum();
skipspaces();
if((num < 0) || (num > 50)) num = 0;
return(conv[num]);
}
check(cc) char cc; {
if(ch != cc){
putcr('\'');
putsym(ch);
pmesg("' where '");
putsym(cc);
pmesg("' expected\n");
ch = ERRCHAR; /* some error occurred */
} else if(ch) newchar();
}
putsym(cc) char cc; {
if(!cc) pmesg("\\n");
else if(cc < ' ') pmesg("\\0%o",cc);
else putcr(cc);
}
/*
* a alter * k * u uit eval
* b black * l * v value
* c crown * m move back * w white
* d define * n no HP use * x exit
* e end * o output * y you
* f file,fp * p print * z zwart
* g (game) * q * = remise
* h halt * r read,rdepth * I I play
* i info * s sleep * : (debug)
* j * t time * \0 (no random)
*/
int *youmv = 0;
rdcomd(ac) char *ac; {
register char *sp,*sp2;
register int i;
int ct;
if(*ac == '!') ac++;
ach = ac; /* read from argstring instead of array line */
switch(newchar()){
case 'w':
playw = PDP;
break;
case 'b':
case 'z':
playb = PDP;
break;
case 'I':
newchar();
if(ch == 'w') playw = USER;
else if(ch == 'b' || ch == 'z') playb = USER;
else playw = playb = USER;
break;
case 'y':
youmv = findmove(me);
break;
case 'h':
while(1){
rdlin();
if(*ach == '.') break;
rdcomd(ach);
}
break;
case 'p':
newchar();
if(ch == 'b'){
pbundef();
newchar();
} else prall++;
if(digit()) optp = rnum();
prbord();
break;
case 'm':
newchar();
if(i = readcol()){
me = i;
mpf = 0;
break;
}
if(ch == '-'){
newchar();
i = mvnr-rnum()-2;
} else i = rnum();
check(0);
if(ch == ERRCHAR) goto ask;
if(i<0 || i+2>mvnr){
pmesg("impossible\n");
goto ask;
}
backup(i);
prbord();
break;
case 'n':
if(disp) home();
disp = 0;
break;
case 'a':
/*
* awk<nr>: alter field <nr> into white king
* a<nr>: make the nonempty field <nr> empty
*/
newchar();
ct = readstone();
alp:
i = readnum();
if(!i){
pmesg("bad field\n");
goto ask;
}
if((!ct) && (bord[i] == EMPTY)){
pmesg("empty already\n");
goto ask;
}
bord[i] = valstone[ct];
altermv = mvnr;
mpf = 0;
if(ch == ','){
newchar();
goto alp;
}
check(0);
if(ch == ERRCHAR) goto ask;
break;
case 'f':
if(newchar() == 'p'){
if(!newchar()){
pmesg("freepath values:\n");
pmesg("w: %d\n",freepath(WHITE));
pmesg("z: %d\n",freepath(BLACK));
break;
}
fplevel = rnum()-1;
break;
}
if(letter()){
pmesg("What?\n");
goto ask;
}
skipspaces();
sp = ofile;
while(*sp++ = ch){
if(sp > ofile+LINSIZ) goto ask;
newchar();
}
if(optf >= 0) (void) close(optf);
optf = open(ofile,1);
if(optf < 0) optf=creat(ofile,0666);
else (void) lseek(optf, 0L, 2);
if(optf < 0) pmesg("cannot create %s\n",ofile);
break;
case 'o':
if(newchar() == 'g') outgame();
else if(ch == 'b') outboard();
else if(ch == 'p') outposit();
else {
pmesg("what?");
goto ask;
}
break;
case 'r':
newchar();
/*
* r: set rdif
* rm: set rdmin
* rf: read pos from file
* rt: read pos from terminal
*/
if(ch == 'f') readfile();
else if(ch == 't') readpos();
else if(ch == 'm') {
newchar();
rdmin = rnum();
pmesg("rdmin = %d\n",rdmin);
}
else {
rdif = rnum();
pmesg("rdif = %d\n",rdif);
if(mvnr == 1)rdifmin = rdif;
else if(rdif<rdifmin)rdifmin = rdif;
}
break;
case 's':
newchar();
prbwait = rnum();
if(prbwait>30) prbwait = 30;
pmesg("sleep after prbord for %d seconds\n",
prbwait);
break;
case 't':
newchar();
if(digit()){
timemax = rnum();
pmesg("allowed time per move: %d sec\n",timemax);
}
pmesg("time used:\n");
pmesg(" W %4d sec\n",timew);
pmesg(" B %4d sec\n",timeb);
break;
case 'c':
/* this does not count for a move */
crown(me);
break;
case 'd':
pbundef(); /* force printing new stones */
newchar();
skipspaces();
if(!ch){
disp = 1;
break;
}
if((i = readstone()) || (ch == '"')){
skipspaces();
check('"');
if(ch == ERRCHAR) goto ask;
sp = dsparr[i];
while(ch != '"'){
if(sp - dsparr[i] < 12) *sp++ = ch;
else {
pmesg("string too long\n");
goto fins;
}
if(!ch){
pmesg("bad string\n");
goto fins;
}
newchar();
}
newchar();
check(0);
fins:
*sp++ = 0;
break;
} else if(ch == 'e'){
newchar();
i = rnum();
for(ct=0; ct++!=i; ) if(!emparr[ct]){
pmesg("we dont have such empty fields\n");
goto ask;
}
sp = dsparr[0];
sp2 = emparr[i];
while(*sp++ = *sp2++);
} else {
i = 4*rnum();
for(ct=0; ct++!=i; ) if(!fularr[ct]){
pmesg("this set of stones is not available\n");
goto ask;
}
for(ct=0; ct<4; ct++){
sp = dsparr[ct+1];
sp2 = fularr[i+ct];
while(*sp++ = *sp2++);
}
}
break;
case 'u':
if(newchar() == '\0') prsteval();
else optu = rnum();
break;
case 'v':
newchar();
i = rnum();
check(',');
if(ch != ERRCHAR){
ct = rnum();
check(0);
}
if(ch == ERRCHAR) goto ask;
setstrat(i,ct);
break;
case 'e':
pmesg("I win\n");
reset();
case '=':
remise();
break;
case 'i':
if(disp) home();
prinfo();
prall++;
break;
case 'x':
error("the game is over");
case '?':
switch(newchar()){
case 'f':
if(newchar() != 'p') goto deflt;
i = fplevel;
break;
case 'r':
i = rdif;
break;
case 's':
i = prbwait;
break;
deflt:
default:
pmesg("unknown param\n");
goto ask;
}
pmesg("%c: %d\n",ch,i);
break;
default:
if(ch)pmesg("unknown command\n");
goto ask;
}
return;
ask:
return;
}
int *
readmove(color) int color; {
register int *mp1; /* essential ! */
register int *mp2,*ump,*ump0,ct,f1,f2;
int umove[22];
listmoves:
mpf = moves;
move(me);
if(possct == 0){
pmesg("you lose\n");
reset();
} else if(possct == 1 && !optg){
pmesg(" forced:\n");
prmove(mpf);
/* return(mpf); */
}
ask:
if(!optg) pmesg("?");
rdlin();
dirt++;
newchar();
skipspaces();
/* read options */
if(ch == '!'){
rdcomd(ach);
if(mp1 = youmv){
youmv = 0;
return(mp1);
}
if(!mpf) goto listmoves; /* the position has changed */
goto ask;
}
/* if line does not start with a digit and (optg) the ignore */
if(!digit()) if(optg) goto ask;
/* read actual moves */
ump0 = ump = &umove[0];
while(ch){
if(ump-ump0 >= 22) ump--;
if((*ump++ = readnum()) == 0) {
if(optg) goto ask; /* ignore bad lines */
pmesg("bad field\n");
goto ask;
}
switch(ump - ump0){
case 1:
if(ch == '.') {
do newchar();
while(ch == '.' || ch == ' ' || ch == '\t');
ump--;
}
else if(ch)
check(captmax ? 'x' : '-');
break;
case 2:
if(!captmax) check(0);
else if(ch) check('(');
break;
default:
if(ch == ',') {
newchar();
break;
}
check(')');
if(ch == ERRCHAR) goto ask;
check(0);
}
if(ch == ERRCHAR) goto ask; /* some error occurred */
}
if(ump == ump0) {
if(possct == 1) return(mpf);
else goto ask;
}
captct = (ump - ump0) - 2;
if(captct > 0){
if(captct != captmax){
pmesg("incorrect number of captured stones\n");
goto ask;
}
} else if(captct == -1) {
/* incomplete move, see whether it is to or from */
if(bord[umove[0]] == EMPTY){ /* to */
umove[1] = umove[0];
umove[0] = -1;
} else umove[1] = -1; /* from */
captct = 0;
}
/* now determine which move he selected from the list
created by 'move(c);'
*/
ump = 0;
for(mp1 = mpf; mp1 < mp; mp1 += ct){
ump0 = &umove[0];
mp2 = mp1;
f1 = *mp1++;
f2 = *mp1++;
ct = *mp1++;
if(((f1 & 0177) ^ *ump0++) > 0) continue;
if(((f2 & 0177) ^ *ump0++) > 0) continue;
if(captct) while(ct--)
if((*mp1++ & 0177) != *ump0++) continue;
if(ump){
pmesg("ambiguous move\n");
goto ask;
} else ump = mp2;
}
if(!ump) {
pmesg("illegal move\n");
goto ask;
}
if(!optg) prmove(ump);
return(ump);
}
/* read w, z, W, Z, wd, bk and return index (0 by default) */
readstone(){
int c;
switch(ch|040){
case 'w':
c = 1;
break;
case 'b':
case 'z':
c = 2;
break;
default:
return(0);
}
if(ch & 040){
newchar();
if(ch == 'd' || ch == 'k') goto dam;
} else {
dam:
newchar();
c += 2;
}
return(c);
}
readcol(){
switch(ch){
case 'w':
newchar();
return(WHITE);
case 'z':
case 'b':
newchar();
return(BLACK);
default:
return(0);
}
}
/*
* Read position; each line looks like
* w: 31-48,49,50
* the description ends with a dot.
*/
int rdbord[66];
readpos(){
register int i,j;
int c;
rdbord[0] = -1; /* remember that readpos was executed */
for(i=1; i<66; i++) rdbord[i] = EMPTY;
do {
rdlin();
if(newchar() == '.') break;
if(!(i = readstone())){
pmesg("bad colour, ");
goto bad;
}
c = valstone[i];
check(':');
if(ch == ERRCHAR) goto bad;
nxt:
if(!(i = readnum())){
pmesg("bad field, ");
goto bad;
}
if(ch == '-'){
newchar();
if(!(j = readnum())){
pmesg("bad 2nd field, ");
goto bad;
}
} else j = i;
while(i <= j) rdbord[i++] = c;
if(ch){
if(ch == '.') break;
check(',');
if(ch == ERRCHAR){
pmesg("bad separator, ");
goto bad;
}
goto nxt;
}
} while(1);
for(i=6; i<60; i++)
if(bord[i] != EDGE) bord[i] = rdbord[i];
mpf = 0;
prbord();
return;
bad:
pmesg("old board retained\n");
return;
}
readfile(){
int f,f0;
/* ach points to the f of 'rf' */
newchar();
skipspaces();
ach--;
f0 = dup(0);
(void) close(0);
f = open(ach,0);
if(f < 0) pmesg("cannot open %s\n",ach);
else if(f) error("f nonzero");
else {
readpos();
(void) close(f);
}
if(f = dup(f0)) error("df nonzero");
(void) close(f0);
}