home *** CD-ROM | disk | FTP | other *** search
- C REV. 23
- INTEGER FUNCTION LTEXT(N)
- LTEXT=IDISK(4,1,1,N)
- RETURN
- END
- C
- INTEGER FUNCTION STEXT(N)
- STEXT=IDISK(5,1,1,N)
- RETURN
- END
- C
- INTEGER FUNCTION TRAVEL(M,N)
- TRAVEL=IDISK(8,3,M,N)
- RETURN
- END
- C
- INTEGER FUNCTION IDISK(ILUN,IDIM,ISUB1,ISUB2)
- INTEGER BUF(64)
- DATA ILAST,NLAST/2*0/
- K=64/IDIM
- J=ISUB2-1
- NREC=1+J/K
- IF (ILAST .EQ. ILUN .AND. NLAST .EQ. NREC) GO TO 1
- ILAST=ILUN
- NLAST=NREC
- READ(ILUN,REC=NREC) BUF
- 1 IT=MOD(J,K)*IDIM+ISUB1
- IDISK=BUF(IT)
- RETURN
- END
- C
- INTEGER FUNCTION RTEXT(N)
- RTEXT=IDISK(10,1,1,N)
- RETURN
- END
- C
- INTEGER FUNCTION VOCAB2(ID,INIT)
- INTEGER TABSIZ
- REAL ID,ATAB
- COMMON /VOCCOM/ TABSIZ
- C
- C WRITE(3,100)ID,INIT
- C 100 FORMAT(1X,'VOCAB(',A4,',',I3,')')
- DO 1 I=1,TABSIZ
- IK=KTAB(I)
- IF (IK .EQ. -1) GO TO 2
- IF (INIT .GE. 0 .AND. IK/1000 .NE. INIT) GO TO 1
- IF (ATAB(I) .EQ. ID) GO TO 3
- 1 CONTINUE
- CALL BUG(21)
- C
- 2 VOCAB2=-1
- IF (INIT .LT. 0) RETURN
- WRITE(3,100) ID
- 100 FORMAT(1X,'KEYWORD = ',A4)
- CALL BUG(5)
- C
- 3 VOCAB2=IK
- IF (INIT .GE. 0) VOCAB2=MOD(VOCAB2,1000)
- RETURN
- END
- SUBROUTINE CARRY(OBJECT,WHERE)
- INTEGER ATLOC,LINK,PLACE,FIXED,HOLDNG,OBJECT,WHERE,TEMP
- DIMENSION ATLOC(150),LINK(200),PLACE(100),FIXED(100)
- COMMON /PLACOM/ ATLOC,LINK,PLACE,FIXED,HOLDNG
- C
- IF (OBJECT .GT. 100) GO TO 5
- IF (PLACE(OBJECT) .EQ. -1) RETURN
- PLACE(OBJECT)=-1
- HOLDNG=HOLDNG+1
- 5 IF (ATLOC(WHERE) .NE. OBJECT) GO TO 6
- ATLOC(WHERE)=LINK(OBJECT)
- RETURN
- 6 TEMP=ATLOC(WHERE)
- 7 IF (LINK(TEMP) .EQ. OBJECT) GO TO 8
- TEMP=LINK(TEMP)
- GO TO 7
- 8 LINK(TEMP)=LINK(OBJECT)
- RETURN
- END
- C
- SUBROUTINE DROP(OBJECT,WHERE)
- INTEGER ATLOC,LINK,PLACE,FIXED,HOLDNG,OBJECT,WHERE
- DIMENSION ATLOC(150),LINK(200),PLACE(100),FIXED(100)
- COMMON /PLACOM/ ATLOC,LINK,PLACE,FIXED,HOLDNG
- C
- IF (OBJECT .GT. 100) GO TO 1
- IF (PLACE(OBJECT) .EQ. -1) HOLDNG=HOLDNG-1
- PLACE(OBJECT)=WHERE
- GO TO 2
- 1 FIXED(OBJECT-100)=WHERE
- 2 IF (WHERE .LE. 0) RETURN
- LINK(OBJECT)=ATLOC(WHERE)
- ATLOC(WHERE)=OBJECT
- RETURN
- END
- C
- INTEGER FUNCTION PUT(OBJECT,WHERE,PVAL)
- INTEGER OBJECT,WHERE,PVAL
- CALL MOVE(OBJECT,WHERE)
- PUT=-1-PVAL
- RETURN
- END
- C
- SUBROUTINE MOVE(OBJECT,WHERE)
- INTEGER ATLOC,LINK,PLACE,FIXED,OBJECT,WHERE,FROM,HOLDNG
- DIMENSION ATLOC(150),LINK(200),PLACE(100),FIXED(100)
- COMMON /PLACOM/ ATLOC,LINK,PLACE,FIXED,HOLDNG
- C
- IF (OBJECT .GT. 100) GO TO 1
- FROM=PLACE(OBJECT)
- GO TO 2
- 1 FROM=FIXED(OBJECT-100)
- 2 IF (FROM .GT. 0 .AND. FROM .LE. 300) CALL CARRY(OBJECT,FROM)
- CALL DROP(OBJECT,WHERE)
- RETURN
- END
- C
- SUBROUTINE JUGGLE(OBJECT)
- INTEGER ATLOC,LINK,PLACE,FIXED,HOLDNG,OBJECT
- DIMENSION ATLOC(150),LINK(200),PLACE(100),FIXED(100)
- COMMON /PLACOM/ ATLOC,LINK,PLACE,FIXED
- C
- I=PLACE(OBJECT)
- J=FIXED(OBJECT)
- CALL MOVE(OBJECT,I)
- CALL MOVE(OBJECT+100,J)
- RETURN
- END
- C
- SUBROUTINE DSTROY(OBJECT)
- INTEGER OBJECT
- CALL MOVE(OBJECT,0)
- RETURN
- END
- C
- INTEGER FUNCTION VOCAB(ID,INIT)
- INTEGER KTAB,TABSIZ
- REAL ID,ATAB
- DIMENSION KTAB(300),ATAB(300)
- COMMON /VOCCOM/ KTAB,ATAB,TABSIZ
- C
- DO 1 I=1,TABSIZ
- IF (KTAB(I) .EQ. -1) GO TO 2
- IF (INIT .GE. 0 .AND. KTAB(I)/1000 .NE. INIT) GO TO 1
- IF (ATAB(I) .EQ. ID) GO TO 3
- 1 CONTINUE
- CALL BUG(21)
- C
- 2 VOCAB=-1
- IF (INIT .LT. 0) RETURN
- WRITE(3,100) ID
- 100 FORMAT(1X,'KEYWORD = ',A4)
- CALL BUG(5)
- C
- 3 VOCAB=KTAB(I)
- IF (INIT .GE. 0) VOCAB=MOD(VOCAB,1000)
- RETURN
- END
- C
- SUBROUTINE A5TOA1(A,B,C,CHARS,LENG)
- LOGICAL FLG
- REAL A,B,C,D
- LOGICAL I,J,K,M
- LOGICAL CHARS(20),TEST(4),BLANK
- EQUIVALENCE (D,TEST(1))
- DATA BLANK/' '/
- C
- DO 9 I=1,20
- 9 CHARS(I)=BLANK
- C
- D=A
- DO 1 I=1,4
- 1 CHARS(I)=TEST(I)
- C
- D=B
- DO 2 I=1,4
- 2 CHARS(I+4)=TEST(I)
- C
- D=C
- J=9
- IF (TEST(1) .GE. 65) J=10
- M=1
- K=J+3
- DO 3 I=J,K
- CHARS(I)=TEST(M)
- 3 M=M+1
- C
- DO 10 I=1,19
- 12 IF (CHARS(I) .NE. BLANK .OR. CHARS(I+1) .NE. BLANK)GOTO 10
- FLG=.FALSE.
- J=I+1
- DO 11 K=J,20
- IF (CHARS(K) .NE. BLANK) FLG=.TRUE.
- 11 CHARS(K-1)=CHARS(K)
- CHARS(20)=BLANK
- IF (FLG) GO TO 12
- 10 CONTINUE
- C
- DO 4 I=1,20
- LENG=21-I
- IF (CHARS(LENG) .EQ. BLANK) GO TO 4
- RETURN
- 4 CONTINUE
- CALL BUG(99)
- END
- INTEGER FUNCTION RAN(RANGE)
- C SINCE THE RAN FUNCTION IN LIB40 SEEMS TO BE A REAL LOSE, WE'LL USE ONE OF
- C OUR OWN. IT'S BEEN RUN THROUGH MANY OF THE TESTS IN KNUTH VOL. 2 AND
- C SEEMS TO BE QUITE RELIABLE. RAN RETURNS A VALUE UNIFORMLY SELECTED
- C BETWEEN 0 AND RANGE-1. NOTE RESEMBLANCE TO ALG USED IN WIZARD.
- INTEGER RANGE,D,R,T
- DATA R/0/
- D=1
- IF(R.NE.0)GOTO 1
- WRITE(3,3)
- 3 FORMAT(1X,'Type 3 digits, please. ')
- READ(3,4) D
- 4 FORMAT(I3)
- R=3
- D=1000+D
- 1 DO 2 T=1,D
- 2 R=R * 81
- RAN=RANGE * (FLOAT(IABS(R))/32768.)
- RETURN
- END
- SUBROUTINE BUG(NUM)
- C THE FOLLOWING CONDITIONS ARE CURRENTLY CONSIDERED FATAL BUGS. NUMBERS < 20
- C ARE DETECTED WHILE READING THE DATABASE; THE OTHERS OCCUR AT "RUN TIME".
- C 0 MESSAGE LINE > 70 CHARACTERS
- C 1 NULL LINE IN MESSAGE
- C 2 TOO MANY WORDS OF MESSAGES
- C 3 TOO MANY TRAVEL OPTIONS
- C 4 TOO MANY VOCABULARY WORDS
- C 5 REQUIRED VOCABULARY WORD NOT FOUND
- C 6 TOO MANY RTEXT OR MTEXT MESSAGES
- C 7 TOO MANY HINTS
- C 8 LOCATION HAS COND BIT BEING SET TWICE
- C 9 INVALID SECTION NUMBER IN DATABASE
- C 20 SPECIAL TRAVEL (500>L>300) EXCEEDS GOTO LIST
- C 21 RAN OFF END OF VOCABULARY TABLE
- C 22 VOCABULARY TYPE (N/1000) NOT BETWEEN 0 AND 3
- C 23 INTRANSITIVE ACTION VERB EXCEEDS GOTO LIST
- C 24 TRANSITIVE ACTION VERB EXCEEDS GOTO LIST
- C 25 CONDITIONAL TRAVEL ENTRY WITH NO ALTERNATIVE
- C 26 LOCATION HAS NO TRAVEL ENTRIES
- C 27 HINT NUMBER EXCEEDS GOTO LIST
- C 28 INVALID MONTH RETURNED BY DATE FUNCTION
- WRITE(3,1) NUM
- 1 FORMAT (' FATAL ERROR, SEE SOURCE CODE FOR INTERPRETATION.'/
- 1 ' PROBABLY CAUSE: ERRONEOUS INFO IN DATABASE.'/
- 2 ' ERROR CODE =',I2/)
- STOP
- END
- C I/O ROUTINES (SPEAK, PSPEAK, RSPEAK, GETIN, YES, A5TOA1)
- SUBROUTINE SPEAK(N)
- C PRINT THE MESSAGE IN RECORD N OF THE RANDOM ACCESS MESSAGE FILE.
- C PRECEDE IT WITH A BLANK LINE UNLESS BLKLIN IS FALSE.
- INTEGER*2 RTEXT,ASCVAR,N,OLDLOC,LOC2(2),ASC2,ASC3,OLDASC
- LOGICAL BLKLIN
- REAL LINES(15),HNULL,HBLANK,LINES2(15,2)
- COMMON /TXTCOM/ LINES,ASCVAR
- COMMON /BLKCOM/ BLKLIN
- DATA HNULL/'>$< '/,HBLANK/' '/,OLDASC/0/
- C
- ASCVAR=N
- IF(N.EQ.0)RETURN
- ASC3=(ASCVAR-1)/2+1
- ASC2=MOD((ASCVAR-1),2)+1
- IF (OLDASC.NE.ASC3) READ(6,REC=ASC3) LOC2,LINES2
- LOC=LOC2(ASC2)
- DO 10 IJ=1,15
- 10 LINES(IJ)=LINES2(IJ,ASC2)
- OLDASC=ASC3
- ASCVAR=ASCVAR+1
- IF(LINES(1).EQ.HNULL)RETURN
- IF(BLKLIN) WRITE(3,2)
- 1 OLDLOC = LOC
- DO 3 I2=1,15
- I=16-I2
- L = I
- IF(LINES(I) .NE. HBLANK) GO TO 5
- 3 CONTINUE
- 5 WRITE(3,2) (LINES(I),I=1,L)
- 2 FORMAT(1X,15A4)
- ASC3=(ASCVAR-1)/2+1
- ASC2=MOD((ASCVAR-1),2)+1
- IF (OLDASC.NE.ASC3) READ(6,REC=ASC3) LOC2,LINES2
- LOC=LOC2(ASC2)
- DO 11 IJ=1,15
- 11 LINES(IJ)=LINES2(IJ,ASC2)
- OLDASC=ASC3
- ASCVAR=ASCVAR+1
- IF(LOC .EQ. OLDLOC) GO TO 1
- RETURN
- END
- SUBROUTINE PSPEAK(MSG,SKIP)
- C FIND THE SKIP+1ST MESSAGE FROM MSG AND PRINT IT. MSG SHOULD BE THE INDEX OF
- C THE INVENTORY MESSAGE FOR OBJECT. (INVEN+N+1 MESSAGE IS PROP=N MESSAGE).
- INTEGER*2 RTEXT,PTEXT,ASCVAR
- INTEGER SKIP,OLDLOC,ASC2,ASC3,OLDASC,LOC2(2)
- LOGICAL I,IS1
- REAL LINES,LINES2(15,2)
- DIMENSION LINES(15),PTEXT(100)
- COMMON /TXTCOM/ LINES,ASCVAR
- COMMON /PTXCOM/ PTEXT
- DATA OLDASC/0/
- M=PTEXT(MSG)
- IF(SKIP.LT.0)GOTO 9
- IS1=SKIP+2
- OLDLOC=-1
- DO 3 I=1,IS1
- 1 ASC3=(M-1)/2+1
- ASC2=MOD((M-1),2)+1
- IF (OLDASC.NE.ASC3) READ(6,REC=ASC3) LOC2,LINES2
- LOC=LOC2(ASC2)
- DO 11 IJ=1,15
- 11 LINES(IJ)=LINES2(IJ,ASC2)
- OLDASC=ASC3
- M=M+1
- IF (OLDLOC .EQ. LOC) GO TO 1
- OLDLOC=LOC
- 3 CONTINUE
- M=M-1
- 9 CALL SPEAK(M)
- RETURN
- END
- SUBROUTINE RSPEAK(I)
- C PRINT THE I-TH "RANDOM" MESSAGE (SECTION 6 OF DATABASE).
- INTEGER*2 RTEXT,ASCVAR
- IF(I.NE.0)CALL SPEAK(RTEXT(I))
- RETURN
- END
- SUBROUTINE MSPEAK(I)
- C PRINT THE I-TH "MAGIC" MESSAGE (SECTION 12 OF DATABASE).
- INTEGER*2 MTEXT,ASCVAR
- DIMENSION MTEXT(35)
- COMMON /MTXCOM/ MTEXT
- IF(I.NE.0)CALL SPEAK(MTEXT(I))
- RETURN
- END
- SUBROUTINE GETIN(WORD1,WORD1X,WORD2,WORD2X)
- C GET A COMMAND FROM THE ADVENTURER. SNARF OUT THE FIRST WORD, PAD IT WITH
- C BLANKS, AND RETURN IT IN WORD1. CHARS 5 THRU 8 ARE RETURNED IN WORD1X, IN
- C CASE WE NEED TO PRINT OUT THE WHOLE WORD IN AN ERROR MESSAGE. ANY NUMBER OF
- C BLANKS MAY FOLLOW THE WORD. IF A SECOND WORD APPEARS, IT IS RETURNED IN
- C WORD2 (CHARS 5 THRU 8 IN WORD2X), ELSE WORD2 IS SET TO ZERO.
- INTEGER ST2
- REAL WORD1,WORD1X,WORD2,WORD2X,A1(2),A2(2)
- LOGICAL W1(8),W2(8),CR,BL
- INTEGER IBL(8)
- LOGICAL BLKLIN
- LOGICAL IL,LA,LZ
- LOGICAL*1 FRST(20)
- COMMON /BLKCOM/ BLKLIN
- EQUIVALENCE (A1(1),W1(1)), (A2(1),W2(1))
- EQUIVALENCE (W1(1),IBL(1)),(W2(1),IBL(5))
- EQUIVALENCE (IL,FRST(1))
- DATA LA,LZ/'A','Z'/
- DATA CR,BL/X'0D',' '/
- DO 99 IL=1,8
- 99 IBL(IL)=' '
- IF(BLKLIN) WRITE(3,1)
- 1 FORMAT(1X)
- WRITE(3,103)
- 103 FORMAT(1X,'->')
- 2 READ(3,3) FRST
- 3 FORMAT(20A1)
- DO 2000 I=1,20
- IF (FRST(I) .EQ. CR) FRST(I)=BL
- IF(LA .LE. FRST(I) .AND. FRST(I) .LE. LZ) FRST(I) =
- 2 FRST(I)+BL
- 2000 CONTINUE
- ST2 = 1
- IX1 = 0
- IX2 = 0
- I = 0
- 10 I = I + 1
- IF(I .GT. 20) GO TO 2
- IF(FRST(I) .EQ. BL) GO TO 10
- 15 IX1 = IX1 + 1
- IF (IX1 .LE. 8) W1(IX1)=FRST(I)
- I = I + 1
- IF(I .GT. 20) GO TO 500
- IF(FRST(I) .NE. BL) GO TO 15
- 20 I = I + 1
- IF(I .GT. 20) GO TO 500
- IF(FRST(I) .EQ. BL) GO TO 20
- ST2 = I
- 25 IX2 = IX2 + 1
- IF (IX2 .LE. 8) W2(IX2)=FRST(I)
- I = I + 1
- IF(I .GT. 20) GO TO 500
- IF(FRST(I) .NE. BL) GO TO 25
- 500 WORD1=A1(1)
- WORD1X=A1(2)
- WORD2 = 0.
- IF(IX2 .EQ. 0) RETURN
- WORD2=A2(1)
- WORD2X=A2(2)
- RETURN
- END
- LOGICAL FUNCTION YES(X,Y,Z)
- C CALL YESX (BELOW) WITH MESSAGES FROM SECTION 6.
- INTEGER X,Y,Z
- EXTERNAL RSPEAK
- LOGICAL YESX
- YES=YESX(X,Y,Z,RSPEAK)
- RETURN
- END
- LOGICAL FUNCTION YESM(X,Y,Z)
- C CALL YESX (BELOW) WITH MESSAGES FROM SECTION 12.
- INTEGER X,Y,Z
- EXTERNAL MSPEAK
- LOGICAL YESX
- YESM=YESX(X,Y,Z,MSPEAK)
- RETURN
- END
- LOGICAL FUNCTION YESX(X,Y,Z,SPK)
- C PRINT MESSAGE X, WAIT FOR YES/NO ANSWER. IF YES, PRINT Y AND LEAVE YEA
- C TRUE; IF NO, PRINT Z AND LEAVE YEA FALSE. SPK IS EITHER RSPEAK OR MSPEAK.
- INTEGER X,Y,Z
- REAL REPLY,JUNK1,JUNK2,JUNK3,HY1,HY2,HN1,HN2
- DATA HY1,HY2,HN1,HN2/'y ','yes ','n ','no '/
- 1 IF(X.NE.0)CALL SPK(X)
- CALL GETIN(REPLY,JUNK1,JUNK2,JUNK3)
- IF(REPLY.EQ.HY1.OR.REPLY.EQ.HY2)GOTO 10
- IF(REPLY.EQ.HN1.OR.REPLY.EQ.HN2)GOTO 20
- WRITE(3,9)
- 9 FORMAT(/' Please answer the question.')
- GOTO 1
- 10 YESX=.TRUE.
- IF(Y.NE.0)CALL SPK(Y)
- RETURN
- 20 YESX=.FALSE.
- IF(Z.NE.0)CALL SPK(Z)
- RETURN
- END
- REAL FUNCTION ATAB(I)
- REAL BUF(32)
- DATA N/0/
- J=1+(I-1)/32
- K=MOD(I,32)
- IF (K .EQ. 0) K=32
- IF (J .EQ. N) GO TO 1
- N=J
- READ(7,REC=N)BUF
- 1 ATAB=BUF(K)
- RETURN
- END
- C
- INTEGER FUNCTION KTAB(N)
- KTAB=IDISK(9,1,1,N)
- C WRITE(3,100)N,KTAB
- C 100 FORMAT(1X,'KTAB(',I3,')=',I4)
- RETURN
- END
-