%EXTERNALROUTINE MASTMIND (%STRING (255) PSTZ) %EXTERNAL %ROUTINE %SPEC PROMPT (%STRING(255) ST) %EXTERNAL %LONG %REAL %FN %SPEC CPUTIME %EXTERNAL %LONG %REAL %FN %SPEC RANDOM REAL %CONST %STRING (1) SNL=" " %RECORDFORMAT RFM1 (%INTEGERARRAY SET(1:4), %INTEGER PTR) %RECORDFORMAT RFM2 (%INTEGERARRAY HOLE(1:4) ,%INTEGER BL,WH) %RECORDARRAY ROW (1:10) (RFM2) %RECORDARRAY BASE (1:1296) (RFM1) %OWNINTEGER PERSONSCORE,COMPSCORE,FIRSTP,LASTP,POSS,FAULTY %OWNINTEGER SRN,NF1,NF2,MATCH,CRITICAL,GWBW ! ! ********** ___ ROUTINE SECTION ___ ********** ! ! ***** THE ROUTINE MARK IS ONE OF THE MAIN GAME PLAYING ! FEATURES OF MASTERMIND,GIVING THE VITAL INFORMATION TO ! THE CODEBREAKER ABOUT THE COMPARISON BETWEEN THE TRIAL ! CODE AND THE HIDDEN CODE. MARKED AS FOLLOWS--- ! 1 BLACK -- 1 NUMBER IN CORRECT HOLE. ! 1 WHITE -- 1 NUMBER IN WRONG HOLE. ***** %ROUTINE MARK (%INTEGERARRAYNAME TEST1,TEST2,%INTEGERNAME NB,NW) %INTEGER I,J NB=0 NW=0 %CYCLE I=1,1,4 ; ! THE TEST FOR BLACKS. %IF TEST1(I)=TEST2(I) %THENSTART NB=NB+1 TEST1(I)=-1 TEST2(I)=-2 %FINISH %REPEAT %CYCLE I=1,1,4 ; ! THE TEST FOR WHITES. %CYCLE J=1,1,4 %EXITIF TEST1(I)=-1 %IF TEST1(I)=TEST2(J) %THENSTART NW=NW+1 TEST1(I)=-1 TEST2(J)=-2 %EXIT %FINISH %REPEAT %REPEAT %END ! ! ***** THE COMPUTER AS CODEMAKER ROUTINE, FORMS A CODE ! FROM A RANDOM FUNCTION OF TIME ***** %ROUTINE COMPCYPHER (%INTEGERNAME SCORE) %INTEGER ZX,K,I,NB,NW %INTEGERARRAY CODE,TRIAL,TEST (1:4) %REAL A !** TO GET A UNIQUE NEW CODE EVERY GAME ** A=CPU TIME ZX=INT PT (A)*30 %CYCLE I=1,1,ZX A=RANDOM REAL %REPEAT %CYCLE I=1,1,4 CODE(I)=INT PT (RANDOM REAL *6)+1 %REPEAT ! *************************** %CYCLE K=1,1,10 PROMPT('TRIAL CODE: ') %CYCLE I=1,1,4 READ (TRIAL(I)) TEST(I)=CODE(I) %REPEAT MARK (TEST,TRIAL,NB,NW) PRINT STRING ("No. of blacks=") ; WRITE (NB,1) ; NEWLINE PRINT STRING ("No. of whites=") ; WRITE (NW,1) ; NEWLINE %IF NB=4 %THENSTART PRINT STRING("You have solved code in ") ; WRITE(K,1) PRINT STRING (" moves") SCORE=K %RETURN %FINISH %IF K=10 %THENSTART PRINT STRING ("You have failed on ten moves ") PRINT STRING ("The real code was ") WRITE (CODE(1),1) WRITE (CODE(2),1) WRITE (CODE(3),1) WRITE (CODE(4),1) SCORE=11 %FINISH %REPEAT %END ! ! ! ***** OUTPUT ROUTINES ***** ! %ROUTINE STARS (%INTEGER N) %INTEGER I %CYCLE I=1,1,N PRINT SYMBOL ('*') %REPEAT NEWLINE %END ! ! %ROUTINE INFO ; ! PROPAGANDA. STARS(50) PRINT STRING(" peter j. turcan--artificial intelligence".SNL) PRINT STRING(" project--mastermind program".SNL) STARS(50) %END ! %ROUTINE GUESS (%INTEGER NUM) %INTEGER I,B,W NEWLINES(3) PRINT STRING ("This is my trial code--") %CYCLE I=1,1,4 WRITE (ROW(NUM)_HOLE(I) ,2) SPACES(2) %REPEAT NEWLINE PROMPT('NO. OF BLACKS:') ; READ(B) PROMPT('NO. OF WHITES:') ; READ(W) ROW(NUM)_BL=B ROW(NUM)_WH=W %END ! ! %ROUTINE COMPCODE (%INTEGER G) %INTEGER SCORE %IF G=1 %THENSTART PRINT STRING ("The computer will select a code of 4 numbers".SNL) PRINT STRING("from 1 to 6 and will place them in a secret order".SNL) PRINT STRING ("the computer will mark your trial codes as follows") PRINT STRING(SNL."1 black=1 number in correct position".SNL) PRINT STRING("1 white=1 number in code,but in wrong position") NEWLINE %FINISHELSE PRINT STRING(" the computer will form a code".SNL) COMPCYPHER(SCORE) PERSONSCORE =PERSONSCORE+SCORE %END ! %ROUTINE PLAYING CARD %INTEGER I PRINT STRING(SNL."Now you make up a code on this card".SNL) PRINTSTRING("Reply 1 to prompt when you have formed a code") NEWLINE STARS(24) PRINT STRING ("Holes 1 2 3 4 ".SNL) PRINT STRING ("Code ___ ___ ___ ___ ".SNL) STARS(24) NEWLINES(5) PROMPT('READY: ') READ (I) %END ! %ROUTINE SCORE NEWLINE PRINT STRING ("The computers score = ") ; WRITE(COMPSCORE,2) ;NEWLINE PRINT STRING (" your score = ") ; WRITE (PERSONSCORE,2) NEWLINE ! PROMPT FOR ANOTHER MATCH. %END ! %ROUTINE FAULTY MARKING PRINT STRING (SNL."You have not marked my trial codes correctly ".SNL) PRINT STRING("3 penalty points are added to your score".SNL) PRINT STRING("This round will be replayed.".SNL) PERSONSCORE=PERSONSCORE+3 %END ! ! ********** %ROUTINE FINALE NEWLINE %IF COMPSCORE>PERSONSCORE %THENSTART PRINT STRING ("You have won the game,well done".SNL) %FINISH %IF COMPSCORE=PERSONSCORE %THENSTART PRINT STRING ("The game is a draw".SNL) %FINISH %IF COMPSCORE=1 %AND B+W=4) %THENSTART R2H1=R1H3 R2H2=R1H2 R2H3=R1H1 R2H4=R1H1 %RETURN %FINISH %IF W>=3 %THENSTART R2H1=NF1 R2H2=R1H1 R2H3=R1H2 R2H4=R1H3 %RETURN %FINISH %IF W+B<=1 %THENSTART R2H1=NF1 R2H2=R1H1 R2H3=NF1 R2H4=NF2 %RETURN %FINISH %IF W=2 %AND (B=0 %OR B=1) %THENSTART R2H1=NF1 R2H2=R1H1 R2H3=R1H2 %IF B=1 %THEN R2H4=R1H2 %ELSE R2H4=NF1 %RETURN %FINISH %IF B=2 %AND W=1 %THENSTART R2H1=NF1 R2H2=R1H2 R2H3=R1H1 R2H4=R1H1 %RETURN %FINISH %IF W+B=2 %THENSTART R2H1=R1H1 R2H2=NF1 R2H3=R1H2 R2H4=NF2 %RETURN %FINISH ! **************************** %FINISH %IF SRN=2 %THENSTART R=R1H4 %CYCLE I=1 ,1,3 R=R+1 %IF R=7 %THEN R=1 ROW(2)_HOLE(I)=R %REPEAT R2H4=R %RETURN %FINISH %END ! ! %ROUTINE ONELEFT (%INTEGER N) %INTEGER I %CYCLE I=1,1,4 ROW(N)_HOLE(I)=BASE(FIRSTP)_SET(I) %REPEAT %END ! ********** %ROUTINE ONEFROMBASE (%INTEGER N) %INTEGER I,P,X P=(INT PT(RANDOM REAL *POSS)) * 2+4 X=FIRSTP %CYCLE I=1,1,P X=BASE(X)_PTR %IF X=0 %THEN X=FIRSTP %REPEAT %CYCLE I=1,1,4 ROW(N)_HOLE(I)=BASE(X)_SET(I) %REPEAT %END ! ********** ! ! ******** %ROUTINE FINDBESTROW (%INTEGER R) %INTEGERARRAY TESTA,TESTB (1:4) , SCORES(0:20) %REAL IC,MAXIC %INTEGER X,Y,I,NBB,NWW,S,RTT %REALFN CALCVAL %INTEGER I %REAL TOT TOT=0 %CYCLE I=0,1,20 %IF SCORES(I)>0 %THENSTART ! *************** INFORMATION CONTENT ********************* TOT=TOT+(SCORES(I)/POSS)*(1.4427099*LOG(POSS/SCORES(I))) ! ********************************************************* %FINISH %REPEAT %RESULT=TOT %END ! MAXIC=0 X=FIRSTP %CYCLE %CYCLE I=0,1,20 SCORES(I)=0 %REPEAT Y=FIRSTP %CYCLE COPY(BASE(X)_SET,TESTA) COPY(BASE(Y)_SET,TESTB) MARK(TESTA,TESTB,NBB,NWW) S=NBB*5 + NWW SCORES(S)=SCORES(S)+1 Y=BASE(Y)_PTR %EXITIF Y=0 %REPEAT IC=CALCVAL %IF IC>MAXIC %THEN MAXIC=IC %AND RTT=X X=BASE(X)_PTR %EXITIF X=0 %REPEAT COPY(BASE(RTT)_SET,ROW(R)_HOLE) %END ! ********** _ MAIN PROGRAM _ ********** ! %INTEGERARRAY TEST (1:4) %INTEGER GAME,RW CRITICAL=1 POSS=1296 FIRSTP=1 INFO GAME=1 INITIAL SET ! %CYCLE NEWLINES(3) ! COMPCODE(GAME) %UNLESS FAULTY=1 REPLAY FAULTY=0 NEWLINES(6) PLAYING CARD %CYCLE RW=1,1,10 %IF RW=1 %THEN FIRSTROW %IF RW=2 %THEN SECOND ROW %IF RW>2 %THENSTART %IF POSS>10 %THEN ONEFROMBASE(RW) %IF 1