%external %routine draughts ! DRAFT4.2 Author: Ken Chisholm. %external %routine %spec emas3(%string %name s,p, %integer %name f) %externalroutinespec emas3prompt %c (%stringname text) %INTEGERARRAY COMP,OPP(0:24) %OWNINTEGERARRAY CONSCOMP(0:24)='W',86,66,46,26,17,37,57,77,88,68, 48,28,1,1,1,1,1,1,1,1,1,1,1,1 %OWNINTEGERARRAY CONSOPP(0:24)='B',13,33,53,73,82,62,42,22,11,31, 51,71,1,1,1,1,1,1,1,1,1,1,1,1 %OWNINTEGERARRAY CENTSQ(1:8)=33,35,44,46,53,55,64,66 %INTEGERARRAY MIN,MAX(1:12) %OWNINTEGERARRAY MOVES(1:8)=-11,-22,9,18,11,22,-9,-18 %INTEGERARRAY NO OF BOARDS(1:24) %OWNINTEGERARRAY REPLY(1:8) %OWNINTEGER FEW=8, LESS=4 %OWNINTEGER SEARCH LIMIT=3,PLY NUMBER %OWNINTEGER PRINTB='P' %INTEGER BEST PIECE TO MOVE,BEST MOVE,BEST TAKE,%C VALUEB,I,P,M,PIECE,JMAN,JUMP,DIF,MODIF,PIECEWT,MOBWT,EXCHWT,%C CENTWT,ADVWT,MORE,NPCS,OLDPOS,NEWPOS,LASTPOS,COMPOS,NODES,MON %INTEGER NPOS,CRAMPWT,ADV2WT,AWIN,MAXNO,INDEX,J,K,PIECE ADV emas3("define", "1, boards", i) MAXNO=0 SELECT INPUT(1) %FOR I=1,1,24 %CYCLE READ(NO OF BOARDS(I)) %IF NO OF BOARDS(I)> MAXNO %THEN MAXNO =NO OF BOARDS(I) %REPEAT MAXNO=MAXNO+20 %BEGIN %INTEGERARRAY BOARDS(1:24,1:MAXNO,1:4) %ROUTINE TRANSLATE(%INTEGERARRAYNAME COMP,OPP,%INTEGERNAME PIECES,%C COL,CROWNS) %INTEGER I,J,K,PT,CP,KP PIECES=0;COL=0;CROWNS=0 %FOR I=10,20,70 %CYCLE %FOR J=0,11,11 %CYCLE %FOR K=1,2,7 %CYCLE PT=0;CP=0;KP=0 %FOR P=1,1,12 %CYCLE %IF COMP(P)=(I+J+K)%THENSTART PT=1;CP=1 %IF COMP(P+12)=2 %THEN KP=1 %FINISH %IF OPP(P)=(I+J+K) %THENSTART PT=1;CP=0 %IF OPP(P+12)=2 %THEN KP=1 %FINISH %REPEAT PIECES=PIECES<<1+PT COL=COL<<1+CP CROWNS=CROWNS<<1+KP %REPEAT %REPEAT %REPEAT %END %INTEGER%FN MOD(%INTEGER N) %RESULT=N %IF N>=0 %RESULT=-N %END %ROUTINE READ BINARY(%INTEGERNAME N) %INTEGER S N=0 SKIP SYMBOL %WHILE NEXT SYMBOL=' ' %OR NEXT SYMBOL=NL %CYCLE READ SYMBOL(S) N=N<<1+(S-'0') %UNLESS NEXT SYMBOL='0' %OR NEXT SYMBOL='1' %THENRETURN %REPEAT %END %INTEGERFN NUMBER OF PIECES(%INTEGERARRAYNAME COMP,OPP) %INTEGER I,PCS PCS=0 %FOR I=1,1,12 %CYCLE %IF COMP(I)#0 %THEN PCS=PCS+1 %IF OPP(I)#0 %THEN PCS=PCS+1 %REPEAT %RESULT=PCS %END ! ! PLAYING FNS. ! %INTEGERFN CROWNED(%INTEGER PIECE,%INTEGERARRAYNAME COMP) %INTEGER POS POS=COMP(PIECE) %IF COMP(0)='W' %THENSTART %IF POS=11 %OR POS=31 %OR POS=51 %OR POS=71 %THEN %RESULT=2 %RESULT=1 %FINISH !BLACK PIECE. %IF POS=28 %OR POS=48 %OR POS=68 %OR POS=88 %THEN %RESULT=2 %RESULT =1 %END %INTEGERFN COND OF(%INTEGER POS,%INTEGERARRAYNAME COMP,OPP) %INTEGER I ! ON THE BOARD? %IF POS<11 %OR POS>88 %THEN %RESULT=-1 %FOR I=19,10,79 %CYCLE %IF POS=I %OR POS=I+1 %THEN %RESULT=-1 %REPEAT %FOR I=1,1,12 %CYCLE %IF POS=COMP(I) %OR POS=OPP(I) %THEN %RESULT=2 %REPEAT %RESULT=0 ; ! OKAY. %END %ROUTINE WRITE BINARY (%INTEGER N) %INTEGER I SPACE %FOR I=31,-1,0 %CYCLE PRINT SYMBOL(N>>I&1+'0') %REPEAT %END %INTEGERFN SIGN(%INTEGER N) %IF N<0 %THEN %RESULT= -1 %IF N>0 %THEN %RESULT=1 %RESULT=0 %END %INTEGERFN PARITY(%INTEGER N) %RESULT=N&1 %END %INTEGERFN APPLICABLE MOVE(%INTEGER MOVE,P,%INTEGERARRAYNAME COMP,OPP) %INTEGER I,T %IF COMP(P)=0 %THEN %RESULT=-1 %IF COMP(0)='W' %AND MOVE>4 %AND COMP(P+12)=1 %THEN %RESULT=-1 %IF COMP(0)='B' %AND MOVE<5 %AND COMP(P+12)=1 %THEN %RESULT=-1 %IF PARITY(MOVE)=1 %THENSTART %IF COND OF(COMP(P)+MOVES(MOVE),COMP,OPP)=0 %THEN %RESULT=0 %RESULT=-1 %FINISH ! TAKE MOVE. %IF COND OF(COMP(P)+MOVES(MOVE),COMP,OPP)#0 %THEN %RESULT=-1 T=COMP(P)+MOVES(MOVE-1) %FOR I=1,1,12 %CYCLE %IF T=OPP(I) %THEN %RESULT=I %REPEAT %RESULT=-1 %END %INTEGERFNSPEC IF SEEN BOARD(%INTEGERARRAYNAME COMP,OPP) ! ! EVALUATION FUNCTION. ! %INTEGERFN VALUE OF POSITION(%INTEGERARRAYNAME COMP,OPP) %INTEGER V1,V2,V3,V4,V5,V6,V8,V9,P,M,J,B1,B2,APEX,PCS,PC ADV,PC DIFF %IF COMP(0)='W' %THENC V1=IF SEEN BOARD(COMP,OPP) %ELSEC V1=IF SEEN BOARD(OPP,COMP) %IF INDEX#0 %THENSTART %IF COMP(0)='W' %THEN V1=V1-PLY NUMBER %ELSE V1=V1+PLY NUMBER %RESULT=V1 %FINISH V1=0 ; !PIECE COUNT. V2=0;V3=0;V4=0 %FOR P=1,1,12 %CYCLE I=P+12 %IF COMP(I)=1 %THEN V1=V1+1 %IF COMP(I)=2 %THEN V2=V2+2 %IF OPP(I)=1 %THEN V3=V3+1 %IF OPP(I)=2 %THEN V4=V4+2 %REPEAT V1=V1+V2-(V3+V4) ! EXCHANGE. PCS=NUMBER OF PIECES(COMP,OPP) PC ADV=PIECE ADV %IF COMP(0)='B' %THEN PC ADV=-PC ADV PC DIFF=NPCS-PCS V9=PC DIFF*SIGN(PC ADV) V8=0;! GUARD. %IF COMP(0)='W' %THEN B1=28 %AND B2=68 %AND APEX=57 %ELSE B1=31 %ANDC B2=71 %AND APEX=42 %IF V4=0 %THENSTART %IF COMP(12)=B1 %THEN V8=V8+3 %IF COMP(10)=B2 %THEN V8=V8+3 %IF COMP(7)=APEX %THEN V8=V8+4 %FINISH %IF V2=0 %THENSTART B1=59-B1;B2=149-B2;APEX=99-APEX %IF OPP(10)=B1 %THEN V8=V8-3 %IF OPP(12)=B2 %THEN V8=V8-3 %IF OPP(7)=APEX %THEN V8=V8-4 %FINISH ! MOBILITY. V2=0;V3=0 %FOR P=1,1,12 %CYCLE %FOR M=1,1,8 %CYCLE %IF APPLICABLE MOVE(M,P,COMP,OPP)>=0 %THENC V2=V2+PARITY(M+1)+1 %IF APPLICABLE MOVE(M,P,OPP,COMP)>=0 %THENC V3=V3+(PARITY(M+1)+1) %REPEAT %REPEAT %IF V2=0 %THENSTART %IF COMP(0)='W' %THEN %RESULT= -100000 + PLY NUMBER %RESULT=100000 - PLY NUMBER %FINISH V2=V2-V3 V3=0; ! CENTER CONTROL %FOR P=1,1,12 %CYCLE %FOR M=1,1,8 %CYCLE %IF COMP(P)=CENTSQ(M) %THEN V3=V3+COMP(P+12) %IF OPP(P)=CENTSQ(M) %THEN V3=V3-OPP(P+12) %REPEAT %REPEAT V4=0; ! ADVANCEMENT. %FOR P=1,1,12 %CYCLE %FOR M=1,1,8 %CYCLE %IF APPLICABLE MOVE(M,P,COMP,OPP)>=0 %THENSTART COMP(P)=COMP(P)+MOVES(M) %IF CROWNED(P,COMP)=2 %AND COMP(P+12)=1 %THEN V4=V4+1 %ANDC COMP(P)=COMP(P)-MOVES(M) %ANDEXIT COMP(P)=COMP(P)-MOVES(M) %FINISH %REPEAT %FOR M=1,1,8 %CYCLE %IF APPLICABLE MOVE(M,P,OPP,COMP)>=0 %THENSTART OPP(P)=OPP(P)+MOVES(M) %IF CROWNED(P,OPP)=2 %AND OPP(P+12)=1 %THEN V4=V4-1 %ANDC OPP(P)=OPP(P)-MOVES(M) %ANDEXIT OPP(P)=OPP(P)-MOVES(M) %FINISH %REPEAT %REPEAT V5=0; ! CRAMP. %FOR P=1,1,12 %CYCLE %FOR M=1,2,7 %CYCLE %IF APPLICABLE MOVE(M,P,OPP,COMP)>=0 %THENSTART OPP(P)=OPP(P)+MOVES(M) %FOR I=1,1,12 %CYCLE %FOR J=2,2,8 %CYCLE %IF APPLICABLE MOVE(J,I,COMP,OPP)>=0 %THEN V5=V5+OPP(P+12) %ANDEXIT %REPEAT %REPEAT OPP(P)=OPP(P)-MOVES(M) %FINISH %IF APPLICABLE MOVE(M,P,COMP,OPP)>=0 %THENSTART COMP(P)=COMP(P)+MOVES(M) %FOR I=1,1,12 %CYCLE %FOR J=2,2,8 %CYCLE %IF APPLICABLE MOVE(J,I,OPP,COMP)>=0 %THEN V5=V5-COMP(P+12)%ANDEXIT %REPEAT %REPEAT COMP(P)=COMP(P)-MOVES(M) %FINISH %REPEAT %REPEAT ! V6 - ADV2. V6=0 %FOR P=1,1,12 %CYCLE %IF COMP(P+12)=1 %THENSTART %FOR M=1,2,7 %CYCLE %IF APPLICABLE MOVE(M,P,COMP,OPP) >=0 %THENSTART COMP(P)=COMP(P)+MOVES(M) %FOR J=1,2,7 %CYCLE %IF APPLICABLE MOVE(J,P,COMP,OPP)>=0 %THENSTART COMP(P)=COMP(P)+MOVES(J) %IF CROWNED(P,COMP)=2 %THEN V6=V6+1 %ANDC COMP(P)=COMP(P)-MOVES(J) %ANDEXIT COMP(P)=COMP(P)-MOVES(J) %FINISH %REPEAT COMP(P)=COMP(P)-MOVES(M) %FINISH %REPEAT %FINISH %REPEAT %FOR P=1,1,12 %CYCLE %IF OPP(P+12)=1 %THENSTART %FOR M=1,2,7 %CYCLE %IF APPLICABLE MOVE(M,P,OPP,COMP)>=0 %THENSTART OPP(P)=OPP(P)+MOVES(M) %FOR J=1,2,7 %CYCLE %IF APPLICABLE MOVE(J,P,OPP,COMP)>=0 %THENSTART OPP(P)=OPP(P)+MOVES(J) %IF CROWNED(P,OPP)=2 %THEN V6=V6-1 %ANDC OPP(P)=OPP(P)-MOVES(J) %AND %EXIT OPP(P)=OPP(P)-MOVES(J) %FINISH %REPEAT OPP(P)=OPP(P)-MOVES(M) %FINISH %REPEAT %FINISH %REPEAT V1=PIECEWT*V1+MOBWT*V2+CENTWT*V3+ADVWT*V4+CRAMPWT*V5+ADV2WT*V6 V1=V1+V8 + EXCHWT*V9 - PLY NUMBER %IF COMP(0)='B' %THEN V1 =-V1 %RESULT=V1 %END %ROUTINESPEC PRINT BOARD %ROUTINE EXPLAIN POS PRINT STRING(" The method of communicating moves is very similar to the Algebraic Notation sometimes used in chess.");NEWLINE PRINT STRING("Examples of valid move types:- A3-B4 G3-H4P (Prints the board after my reply)");NEWLINE PRINT STRING("P (Just prints the board)");NEWLINE PRINT STRING("A3-C5, (To type in C5-A7 multiple jump moves)");NEWLINE PRINT STRING("I QUIT (To resign or stop the game.)"); NEWLINE PRINT STRING("Here is the board as initially set up - ") PRINT BOARD %END %ROUTINE SAY PLEASE PRINT STRING( "Please re-type your move ") NEWLINE %END %ROUTINE PRINT BOARD %INTEGER I,J,POS,COL,ROW %INTEGERARRAY A(1:64) %INTEGERMAP BOARD(%INTEGER I,J) %RESULT==A(8*(I-1)+J) %END ! WIPE BOARD. %FOR I=1,1,64 %CYCLE A(I)=' ' %REPEAT %FOR I=1,2,7 %CYCLE %FOR J=1,2,7 %CYCLE BOARD(I,J)='%' BOARD(I+1,J+1)='%' %REPEAT %REPEAT %FOR I=1,1,12 %CYCLE %IF COMP(I)#0 %THENSTART POS=COMP(I) ROW=POS//10 COL=POS-10*ROW %IF COMP(I+12)=1 %THEN BOARD(ROW,COL)='C'%ELSE BOARD(ROW,COL)='K' %FINISH %IF OPP(I)#0 %THENSTART POS=OPP(I) ROW=POS//10 COL=POS-10*ROW %IF OPP(I+12)=1 %THEN BOARD(ROW,COL)='o'%ELSE BOARD(ROW,COL)='=' %FINISH %REPEAT NEWLINE;PRINT STRING(" A B C D E F G H") %FOR I=8,-1,1 %CYCLE NEWLINE WRITE(I,1) %FOR J=1,1,8 %CYCLE SPACE PRINT SYMBOL(BOARD(J,I)) %REPEAT WRITE(I,1) %REPEAT NEWLINE;PRINT STRING( " A B C D E F G H");NEWLINE %END %ROUTINE TROUT(%INTEGER OLDPOS,NEWPOS,MODE) ! TRANSLATES AND OUTPUTS MOVES. %INTEGER X,Y,S1,S2,T1,T2 X=OLDPOS//10 Y=OLDPOS-10*X S1=X+'A'-1 S2=Y+'0' X=NEWPOS//10 Y=NEWPOS-10*X T1=X+'A'-1 T2=Y+'0' %IF MODE =1 %THENSTART PRINT STRING( "DRAFT4's move is ") PRINT SYMBOL(S1);PRINT SYMBOL(S2);PRINT SYMBOL('-') PRINT SYMBOL(T1);PRINT SYMBOL(T2) %FINISHELSESTART SPACE;PRINT SYMBOL(',');SPACE;PRINT SYMBOL(S1);PRINT SYMBOL(S2) PRINT SYMBOL('-');PRINT SYMBOL(T1);PRINT SYMBOL(T2) %FINISH %END %ROUTINE TAKE(%INTEGER T,P,MV,%INTEGERARRAYNAME COMP,OPP,%INTEGERC MODE,TAKES) %INTEGER M,APP %IF MODE='P' %THEN TROUT(COMP(P),COMP(P)+MOVES(MV) ,TAKES+1) COMP(P)=COMP(P)+MOVES(MV);OPP(T)=0; OPP(T+12)=0 %IF COMP(P+12)=1 %THENSTART COMP(P+12)=CROWNED(P,COMP) %IF COMP(P+12)=2 %THEN %RETURN %FINISH %FOR M=2,2,8 %CYCLE APP=APPLICABLE MOVE(M,P,COMP ,OPP) %IF APP>0 %THEN TAKE(APP,P,M,COMP,OPP,MODE,TAKES+1) %ANDRETURN %REPEAT %END %ROUTINE MAKE MOVE(%INTEGER M,P,T,%INTEGERARRAYNAME COMP,OPP,%C %INTEGER MODE) %IF T=0 %THENSTART %IF MODE='P'%THEN TROUT(COMP(P),COMP(P)+MOVES(M),1) COMP(P)=COMP(P)+MOVES(M) %UNLESS COMP(P+12)=2 %THEN COMP(P+12)=CROWNED(P,COMP) %RETURN %FINISH ! TAKE MOVE. TAKE(T,P,M,COMP,OPP,MODE,0) %END %INTEGERFN CAN TAKE(%INTEGERARRAYNAME OPP,COMP) %INTEGER P,M %FOR P=1,1,12 %CYCLE %FOR M=2,2,8 %CYCLE %IF APPLICABLE MOVE(M,P,OPP,COMP)>0 %THEN %RESULT='T' %REPEAT %REPEAT %RESULT='F' %END %INTEGERFN TRY POSSIBLE MOVES(%INTEGER PLY,DEPTH,%INTEGERARRAYNAMEC COMP,OPP) %INTEGERARRAY TCOMP,TOPP(0:24) %INTEGER APT,P,M,VALUE,TAKEFLAG,I,FOR,MUST TAKE %INTEGERFN PURSUIT VALUE(%INTEGER M) %IF PLY=1 %THEN %RESULT=1 %RESULT=PARITY(M) %END NODES =NODES+1 FOR=COMP(0); ! CONSIDER MOVES FOR COMP (='W') OR OPP (='B'). MUST TAKE=CAN TAKE(COMP,OPP) ! Principle of hot pursuit. %IF (DEPTH>=SEARCH LIMIT %AND MUST TAKE='F') %OR PLY>12 %THENC PLY NUMBER=PLY-1 %AND %RESULT=VALUE OF POSITION(COMP,OPP) MIN(PLY)=100000;MAX(PLY)=-100000;TAKE FLAG=0 %IF MUST TAKE='T' %THEN TAKE FLAG=1 %FOR P=1,1,12 %CYCLE %FOR M=1,1,8 %CYCLE %IF PARITY(M)=1 %AND TAKEFLAG=1 %THEN APT=-1 %ELSEC APT=APPLICABLE MOVE(M,P,COMP,OPP) %UNLESS APT<0 %THENSTART ! COPY COMP->TCOMP,OPP->TOPP. %FOR I=0,1,24 %CYCLE TCOMP(I)=COMP(I) TOPP(I)=OPP(I) %REPEAT MAKE MOVE(M,P,APT,TCOMP,TOPP,'Q') VALUE=TRY POSSIBLE MOVES(PLY+1,DEPTH+ PURSUIT VALUE(M),TOPP,TCOMP) %IF VALUE >MAX(PLY) %AND FOR='W' %THENSTART MAX(PLY)=VALUE %IF PLY=1 %THENSTART BEST MOVE=M BEST PIECE TO MOVE=P BEST TAKE=APT %FINISH %FINISH %IF VALUE=MIN(PLY-1) %AND FOR='W' %THENC %RESULT=MAX(PLY) %REPEAT %REPEAT ! mini-maxing. %IF FOR='W' %THEN %RESULT=MAX(PLY) %RESULT=MIN(PLY) %END %INTEGERFN POSITION OF(%INTEGER S1,S2) %RESULT=10*(S1-'A'+1) +(S2-'0') %END %ROUTINE READ REPLY(%INTEGERNAME S) READ SYMBOL(S) S = S-32 %IF S>='a' SKIP SYMBOL %WHILE NEXT SYMBOL#NL SKIP SYMBOL %END %ROUTINE READ BOARD %INTEGER P,S1,S2,S3,POS %FOR P=1,1,24 %CYCLE COMP(P)=0 OPP(P)=0 %REPEAT PRINT STRING("Where are your pieces?");NEWLINE %FOR P=1,1,12 %CYCLE SKIP SYMBOL %WHILE NEXT SYMBOL=' '%OR NEXT SYMBOL=NL READ SYMBOL(S1);%IF S1='*' %THENEXIT S1=S1-32 %IF S1>='a' %IF S1='M' %THEN MON='M' %ANDEXIT READ SYMBOL(S2);READ SYMBOL(S3) s2=s2-32 %if s2>='a'; s3=s3-32 %if s3>='a' POS=POSITION OF(S1,S2);OPP(P)=POS %IF S3=' ' %THEN OPP(P+12)=1 %ELSE OPP(P+12)=2 %REPEAT SKIP SYMBOL PRINT STRING("Where are my pieces?");NEWLINE %FOR P=1,1,12 %CYCLE SKIP SYMBOL %WHILE NEXT SYMBOL=' '%OR NEXT SYMBOL=NL READ SYMBOL(S1);%IF S1='*' %THENEXIT READ SYMBOL(S2);READ SYMBOL(S3) s1=s1-32 %if s1>='a' s2=s2-32 %if s2>='a'; s3=s3-32 %if s3>='a' POS=POSITION OF(S1,S2);COMP(P)=POS %IF S3=' ' %THEN COMP(P+12)=1 %ELSE COMP(P+12)=2 %REPEAT SKIP SYMBOL %END %INTEGERFN PIECE COUNT(%INTEGER B) %INTEGER P P=0 %CYCLE %IF B=0 %THEN %RESULT=P %IF B&1 =1 %THEN P=P+1 B=B>>1 %REPEAT %END %ROUTINE SAY SEEN PRINT STRING("Partial board recognised") %AND NEWLINE %IF MON='M' %END ! ! ROTE LEARNING FUNCTIONS. ! %INTEGERFN PARTIAL BOARD MATCH(%INTEGER PCS,COL,CRS) %INTEGER I,SIDE1PCS,SIDE1COL,SIDE1CRS,SIDE2PCS,SIDE2COL,SIDE2CRS,A,B,J %INTEGER NSIDE1PCS,NSIDE2PCS ! SPLIT BOARD INTO TWO HALVES SIDE1PCS=PCS&16_FFFF0000;NSIDE1PCS=PIECE COUNT(SIDE1PCS) SIDE2PCS=PCS &16_FFFF;NSIDE2PCS=PIECE COUNT(SIDE2PCS) SIDE1COL=COL&16_FFFF0000; ! SIDE 1 COLOURS SIDE2COL=COL &16_FFFF; ! SIDE2 COLOURS SIDE1CRS=CRS&16_FFFF0000; ! SIDE 1 CROWNS SIDE2CRS=CRS &16_FFFF; ! SIDE 2 CROWNS %IF NSIDE1PCS=0 %OR NSIDE2PCS=0 %THEN %RESULT=-120000;!ONE HALF EMPTY %IF SIDE1PCS=SIDE1COL %THEN A=100000 %AND -> LOOK AT OTHER HALF %FOR I=1,1,NO OF BOARDS(NSIDE1PCS) %CYCLE %IF SIDE1PCS=BOARDS(NSIDE1PCS,I,1) %ANDC SIDE1COL=BOARDS(NSIDE1PCS,I,2) %ANDC SIDE1CRS=BOARDS(NSIDE1PCS,I,3) %THEN A=BOARDS(NSIDE1PCS,I,4) %C %AND -> LOOK AT OTHER HALF %REPEAT %RESULT=-120000 ; ! NO PARTIAL MATCH FOUND, (IMPOSSIBLE VALUE). LOOK AT OTHER HALF: %IF SIDE2PCS=SIDE2COL %THENSTART ! ONE HALF OF THE BOARD ONLY HAS FRIENDLY PIECES ON IT B=100000 %IF SIGN(A)=SIGN(B) %THEN%RESULT=(A+B)//2 %RESULT=-120000 %FINISH %FOR J=1,1,NO OF BOARDS(NSIDE2PCS) %CYCLE %IF SIDE2PCS=BOARDS(NSIDE2PCS,J,1) %ANDC SIDE2COL=BOARDS(NSIDE2PCS,J,2) %ANDC SIDE2CRS=BOARDS(NSIDE2PCS,J,3) %THENSTART ! CHECK FOR CONFLICTING HALF BOARD VALUES B=BOARDS(NSIDE2PCS,J,4) %IF SIGN(A)=SIGN(B) %THEN %RESULT=(A+B)//2 %RESULT=-120000 %FINISH %REPEAT %RESULT=-120000;! NO PARTIAL BOARD MATCH FOUND, (IMPOSSIBLE VALUE) %END %INTEGERFN IF SEEN BOARD(%INTEGERARRAYNAME COMP,OPP) %INTEGER I,PCS,PCS1,COL1,CR1,PCS2,COL2,CR2 PCS=NUMBER OF PIECES(COMP,OPP) %IF PCS=0 %THEN INDEX=0 %AND %RESULT=-120000 %IF NO OF BOARDS(PCS)=0 %THEN INDEX =0 %AND %RESULT=-120000 TRANSLATE(COMP,OPP,PCS1,COL1,CR1) TRANSLATE(OPP,COMP,PCS2,COL2,CR2) %IF PCS<=6 %THENSTART I=PARTIAL BOARD MATCH(PCS1,COL1,CR1) %IF I#-120000 %THEN SAY SEEN %AND INDEX=-1 %AND %RESULT=I %FINISH %FOR I=1,1,NO OF BOARDS(PCS) %CYCLE %IF BOARDS(PCS,I,1)=PCS1 %AND BOARDS(PCS,I,2)=COL1 %ANDC BOARDS(PCS,I,3)=CR1 %THENSTART %IF MON='M' %THEN PRINT STRING("Board Recognised")%AND NEWLINE INDEX=I;%RESULT=BOARDS(PCS,I,4) %FINISH %IF BOARDS(PCS,I,1)=PCS2 %AND BOARDS(PCS,I,2)=COL2 %ANDC BOARDS(PCS,I,3)=CR2 %THENSTART %IF MON='M' %THEN PRINT STRING("Board Recognised") %AND NEWLINE INDEX=I ; %RESULT=- BOARDS(PCS,I,4) %FINISH %REPEAT INDEX=0 %RESULT=-120000 %END %ROUTINE REMEMBER BOARD %INTEGER PCS,PIECES,COLOURS,CROWNS,VALUE PCS=NUMBER OF PIECES(COMP,OPP) VALUE = IF SEEN BOARD(COMP,OPP) %IF INDEX=-1 %THEN %RETURN; ! PARTIAL BOARD MATCH FOUND %IF VALUE = VALUEB %OR VALUE=-VALUEB %THEN %RETURN TRANSLATE(COMP,OPP,PIECES,COLOURS,CROWNS) %IF INDEX=0 %THEN NO OF BOARDS(PCS)=NO OF BOARDS(PCS)+1 %ANDC INDEX=NO OF BOARDS(PCS) %IF INDEX>MAXNO %THEN NO OF BOARDS(PCS)=NO OF BOARDS(PCS)-1 %AND%RETURN BOARDS(PCS,INDEX,1)=PIECES BOARDS(PCS,INDEX,2)=COLOURS BOARDS(PCS,INDEX,3)=CROWNS BOARDS(PCS,INDEX,4)=VALUEB %IF INDEX# NO OF BOARDS(PCS) %AND MON='M' %THENC PRINT STRING("* Updating Board Evaluation *") %AND NEWLINE %END ! ! ** MAIN PROGRAM ** ! ! READING IN STORED BOARDS. %FOR I=1,1,24 %CYCLE %IF NO OF BOARDS(I)#0 %THENSTART %FOR J=1,1,NO OF BOARDS(I) %CYCLE %FOR K=1,1,3 %CYCLE READ BINARY(BOARDS(I,J,K)) %REPEAT READ(BOARDS(I,J,4)) %REPEAT %FINISH %REPEAT SELECT INPUT(0) START: PIECEWT=1000;MOBWT=6;EXCHWT=8 CENTWT=4;ADVWT=550;CRAMPWT=8;ADV2WT=50 AWIN=0 MON='Q' NEWLINE PRINT STRING( "The Draughts Program , DRAFT4.2L") NEWLINES(2) ! Setting up the pieces. %FOR P=0,1,24 %CYCLE COMP(P)=CONSCOMP(P) OPP(P)=CONSOPP(P) %REPEAT PRINT STRING( "Have you played me before?");NEWLINE emas3prompt(":") READ REPLY(REPLY(1)) %IF REPLY(1)='N' %THEN EXPLAIN POS PRINT STRING( "Do you want to start?");NEWLINE emas3prompt(":") READ REPLY(REPLY(1)) %IF REPLY(1)='R' %THENSTART READ BOARD PRINT STRING("Is it your move?");NEWLINE READ REPLY(REPLY(1)) %IF REPLY(1)='Y' %THEN -> READ MOVE %ELSE -> COMP MOVE %FINISH %IF REPLY(1)='N'%THENSTART PRINT STRING("Think of a number");NEWLINE READ(I);SKIP SYMBOL I=I&3 PRINT STRING( "DRAFT4's opening move is ") %IF I=0 %THEN PRINT STRING("D6-C5") %AND COMP(3)=35 %IF I=1 %THEN PRINT STRING("B6-C5") %AND COMP(4)=35 %IF I=2 %OR I=3 %THEN PRINT STRING("F6-E5")%AND COMP(2)=55 NEWLINE %FINISH READ MOVE: %IF PRINTB='P'%THEN PRINT BOARD emas3prompt(":") %FOR I=1,1,8 %CYCLE READ SYMBOL(REPLY(I)) reply(i)=reply(i)-32 %if reply(i)>='a' %IF REPLY(I)=NL %THENEXIT %REPEAT REPLY(I)=' ' %AND I=I+1 %UNTIL I=9 %IF REPLY(1)='M' %THEN MON='M' %AND -> READ MOVE %IF REPLY(1)='Q' %THEN MON='Q' %AND -> READ MOVE %IF REPLY(1)='P' %THEN PRINT BOARD %AND -> READ MOVE TRANS: %IF REPLY(1)='I'%THEN -> STOP %IF REPLY(6)=','%THEN MORE='M'%ELSE MORE=' ' OLDPOS=POSITION OF(REPLY(1),REPLY(2)) NEWPOS=POSITION OF(REPLY(4),REPLY(5)) ! ! MOVE VERIFICATION. ! %IF COND OF(OLDPOS,COMP,OPP)=-1 %THENSTART PRINT STRING( "The square ");PRINT SYMBOL(REPLY(1)) PRINT SYMBOL(REPLY(2)) PRINT STRING(" does not exist!"); NEWLINE SAY PLEASE -> READ MOVE %FINISH M=COND OF(NEWPOS,COMP,OPP) %IF M=-1 %THENSTART PRINT STRING( "You cannot move to square ") PRINT SYMBOL(REPLY(4));PRINT SYMBOL(REPLY(5)) PRINT STRING(". It does not exist!");NEWLINE SAY PLEASE -> READ MOVE %FINISH %IF M=2 %THENSTART PRINT STRING( "You cannot move to square ") PRINT SYMBOL(REPLY(4));PRINT SYMBOL(REPLY(5)) NEWLINE PRINT STRING( "It is already occupied!");NEWLINE SAY PLEASE -> READ MOVE %FINISH %FOR P=1,1,12 %CYCLE %IF OLDPOS=OPP(P)%THENEXIT %REPEAT %UNLESS OLDPOS=OPP(P)%THENSTART PRINT STRING( "You do not have a piece on square ") PRINT SYMBOL(REPLY(1));PRINT SYMBOL(REPLY(2)) NEWLINE SAY PLEASE -> READ MOVE %FINISH PIECE=P DIF=NEWPOS-OLDPOS MODIF=MOD(DIF) %IF MODIF<12 %AND CAN TAKE(OPP,COMP)='T'%THENSTART PRINT STRING( "You MUST take the piece that I am offering you ") SAY PLEASE -> READ MOVE %FINISH %IF MODIF<12 %AND MORE='M'%THENSTART PRINT STRING("That's not part of a multiple jump move");NEWLINE SAY PLEASE -> READ MOVE %FINISH %IF (DIF=-11 %OR DIF=-22 %OR DIF=9 %OR DIF=18)%ANDC OPP(PIECE+12)=1 %THENSTART PRINT STRING("You cannot move that piece backwards!");NEWLINE SAY PLEASE -> READ MOVE %FINISH %UNLESS MODIF=11 %OR MODIF=9 %OR MODIF=22 %OR MODIF=18 %THENSTART PRINT STRING( "That move does not exist in my rule book!");NEWLINE SAY PLEASE -> READ MOVE %FINISH %IF MODIF>11 %THENSTART JUMP=DIF//2 COMPOS=OLDPOS+JUMP %FOR I=1,1,12 %CYCLE %IF COMPOS=COMP(I)%THENEXIT %REPEAT %UNLESS COMPOS=COMP(I)%THENSTART PRINT STRING("You cannot do that.You are not jumping one of my pieces ") SAY PLEASE -> READ MOVE %FINISHELSE JMAN=I %FINISHELSE JMAN=0 OPP(PIECE)=OPP(PIECE)+DIF %UNLESS OPP(PIECE+12)=2 %THEN OPP(PIECE+12)=CROWNED(PIECE,OPP) COMP(JMAN)=0 %AND COMP(JMAN+12)=0 %UNLESS JMAN=0 %IF MORE='M'%THENSTART LASTPOS=NEWPOS READ AGAIN: emas3prompt("&") %FOR I=1,1,8 %CYCLE READ SYMBOL(REPLY(I)) reply(i)=reply(i)-32 %if reply(i)>='a' %IF REPLY(I)=NL %THENEXIT %REPEAT %IF REPLY(1)='.'%THEN -> COMP MOVE REPLY(I)=' '%AND I=I+1 %UNTIL I=9 OLDPOS=POSITION OF(REPLY(1),REPLY(2)) NEWPOS=POSITION OF(REPLY(4),REPLY(5)) DIF=NEWPOS-OLDPOS DIF=MOD(DIF) %IF DIF>11 %AND OLDPOS=LASTPOS %THEN -> TRANS PRINT STRING("That's not part of a multiple jump");NEWLINE PRINT STRING("Please re-type that part");NEWLINE -> READ AGAIN %FINISH COMP MOVE: ! COMPUTER MAKES MOVE. NPCS=0 NPOS=0 %FOR P=1,1,12 %CYCLE %IF COMP(P)#0 %THEN NPCS=NPCS+1 %IF OPP(P)#0 %THEN NPOS=NPOS+1 %REPEAT %IF NPCS=0 %THENSTART PRINT STRING( " I have no pieces left so you have won") ;NEWLINE -> STOP %FINISH ! PIECE ADVANTAGE (FOR COMPUTER). PIECE ADV=NPCS - NPOS NPCS=NPCS+NPOS %IF NPCS<=FEW %THEN SEARCH LIMIT=SEARCH LIMIT+1 %AND FEW=FEW-LESS I=0 %FOR P=1,1,12 %CYCLE %FOR M=1,1,8 %CYCLE %IF APPLICABLE MOVE(M,P,COMP,OPP)>=0 %THEN I=1 %ANDEXIT %REPEAT %REPEAT %IF I=0 %THENSTART PRINT STRING("I cannot move any of my pieces so you win") NEWLINE -> STOP %FINISH NODES=0 ! ! FIND BEST POSSIBLE MOVE. VALUEB=TRY POSSIBLE MOVES(1,1,COMP,OPP) ! REMEMBER BOARD %IF VALUEB<=-99900 %THENSTART PRINT STRING("I resign");NEWLINE -> STOP %FINISH %IF MON='M' %THENSTART PRINT STRING("Nodes considered = ");WRITE(NODES,3);NEWLINE PRINT STRING("Value of board = ");WRITE(VALUEB,3);NEWLINE %IF PLY NUMBER>3 %THEN PRINT STRING("Depth of search = ") %ANDC WRITE(PLY NUMBER,1) %AND NEWLINE %FINISH MAKE MOVE(BEST MOVE,BEST PIECE TO MOVE,BEST TAKE,COMP,OPP,'P') NEWLINE NPOS=0 %FOR P=1,1,12 %CYCLE %IF OPP(P)#0 %THEN NPOS=1 %ANDEXIT %REPEAT %IF NPOS=0 %THENSTART PRINT STRING( "You have no pieces left so I win");NEWLINE -> STOP %FINISH I=0 %FOR P=1,1,12 %CYCLE %FOR M=1,1,8 %CYCLE %IF APPLICABLE MOVE(M,P,OPP,COMP)>=0 %THEN I=1 %ANDEXIT %REPEAT %REPEAT %IF I=0 %THENSTART PRINT STRING("You cannot move any of your pieces so I win") NEWLINE -> STOP %FINISH %IF VALUEB>=99900 %AND AWIN=0 %THENSTART PRINT STRING("He-He! I am going to win!");NEWLINE AWIN=1 %FINISH -> READ MOVE STOP: NEWLINE PRINT STRING( "The final board position is -");NEWLINE PRINT BOARD PRINT STRING("Play again ?"); NEWLINE READ REPLY(I) %IF I='Y' %THEN -> START ! ! STORING REMEMBERED BOARDS. ! !OPENOUTPUT(1,"BOARDS.DAT") !SELECT OUTPUT(1) !%FOR I=1,1,24 %CYCLE ! WRITE(NO OF BOARDS(I),5);NEWLINE !%REPEAT !%FOR I=1,1,24 %CYCLE ! NEWLINE ! %IF NO OF BOARDS(I)#0 %THENSTART ! %FOR J=1,1,NO OF BOARDS(I) %CYCLE ! %FOR K=1,1,3 %CYCLE ! WRITE BINARY(BOARDS(I,J,K)) ! %IF K=2 %THEN NEWLINE ! %REPEAT ! WRITE(BOARDS(I,J,4),18) ! NEWLINE ! %REPEAT ! %FINISH !%REPEAT %end %END %endoffile