FORTRAN Computer Games


Guess

A simple number guessing game. The source code of “Guess” appeared in David H. Ahl’s BASIC Computer Games (1978):

In program GUESS, the computer chooses a random integer between 0 and any limit you set. You must then try to guess the number the computer has chosen using the clues provided by the computer.

You should be able to guess the number in one less than the number of digits needed to represent the number in binary notation -- i.e., in base 2.

Gameplay

 THIS IS A NUMBER GUESSING GAME. I WILL THINK
 OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.
 THEN YOU HAVE TO GUESS WHAT IT IS.

 WHAT LIMIT DO YOU WANT?
100
 I AM THINKING OF A NUMBER BETWEEN 1 AND      100 ...
 NOW YOU TRY TO GUESS WHAT IT IS.
50
 TOO HIGH. TRY A SMALLER ANSWER.
25
 THAT'S IT! YOU GOT IT IN  2 TRIES.
 VERY GOOD.

Functions & Subroutines

The program requires three procedures that are not part of the ANSI/ISO FORTRAN 77 language standard:

RESULT = TIME()
Returns timestamp in seconds (INTEGER). Required for the initialisation of the pseudo-random number generator.
RESULT = RAND(I)
Returns the next random number (REAL).
CALL SRAND(SEED)
Initialises the pseudo-random number generator with given seed value (INTEGER).

Most modern compilers provide these through extensions.

Program Listing

Save the program source as guess.f.

C     ******************************************************************
C
C     GUESS
C
C     ORIGINALLY WRITTEN BY WALT KOETKE IN FOCAL, AND PORTED TO BASIC BY
C     DAVID H. AHL. CONVERTED TO FORTRAN BY PHILIPP ENGEL.
C
C     ******************************************************************
      PROGRAM GUESS
      INTEGER INPUT
      INTEGER IATTEM, IGUESS, ILIMIT, IMAX, ISECRE

      CALL SRAND(TIME())

      PRINT 100
      ILIMIT = INPUT()
      IMAX = INT(LOG(REAL(ILIMIT)) / LOG(2.0)) + 1

      PRINT 200, ILIMIT
      ISECRE = 1 + INT(RAND(0) * ILIMIT)
      IGUESS = 0
      IATTEM = 0

   10 CONTINUE
      IATTEM = IATTEM + 1
      IGUESS = INPUT()
      IF (IGUESS .LT. ISECRE) PRINT 300
      IF (IGUESS .GT. ISECRE) PRINT 400
      IF (IGUESS .NE. ISECRE) GOTO 10

      PRINT 500, CHAR(39), IATTEM

      IF (IATTEM .LT. IMAX) THEN
        PRINT 600
      ELSE IF (IATTEM .EQ. IMAX) THEN
        PRINT 700
      ELSE
        PRINT 800, IMAX
      END IF

  100 FORMAT (' THIS IS A NUMBER GUESSING GAME. I WILL THINK',/,
     &' OF A NUMBER BETWEEN 1 AND ANY LIMIT YOU WANT.',/,
     &' THEN YOU HAVE TO GUESS WHAT IT IS.',/,/,
     &' WHAT LIMIT DO YOU WANT?')
  200 FORMAT (' I AM THINKING OF A NUMBER BETWEEN 1 AND ',I8,' ...',/,
     &' NOW YOU TRY TO GUESS WHAT IT IS.')
  300 FORMAT (' TOO LOW. TRY A BIGGER ANSWER.')
  400 FORMAT (' TOO HIGH. TRY A SMALLER ANSWER.')
  500 FORMAT (' THAT',A,'S IT! YOU GOT IT IN ',I2,' TRIES.')
  600 FORMAT (' VERY GOOD.')
  700 FORMAT (' GOOD.')
  800 FORMAT (' YOU SHOULD HAVE BEEN ABLE TO GET IT IN ONLY ',I3,'.')
      END
C     ******************************************************************
      INTEGER FUNCTION INPUT()
C
C     RETURNS A POSITIVE INTEGER GREATER THAN 1 FROM USER INPUT.
C
      INTEGER ISTAT

   10 CONTINUE
      READ (*, 100, IOSTAT=ISTAT) INPUT
  100 FORMAT (I8)
      IF (ISTAT .NE. 0 .OR. INPUT .LE. 1) THEN
        PRINT 200
        GOTO 10
      END IF
  200 FORMAT (' INVALID INPUT. TRY AGAIN:')
      END

Build Instructions

UNIXFlang/F18$ flang -o guess guess.f
GNU Fortran$ gfortran -o guess guess.f
Intel Fortran Compiler$ ifort -o guess guess.f
Win32Digital/Compaq Visual Fortran> fl32.exe guess.f /Fe=guess.exe

References


Home