%EXTERNALROUTINE MANGAME(%STRING (63)S)
      !!
      %DYNAMICROUTINESPEC PROMPT(%STRING (18)S)
      %DYNAMICROUTINESPEC DEFINE(%STRING (63)S)
      %DYNAMICINTEGERFNSPEC RAND INT;  ! RETURNS 0<=R<=20
      !!
      %ROUTINESPEC ECONOMY ON SALES(%INTEGER C)
      %ROUTINESPEC ECONOMY STATE(%INTEGER EC)
      %INTEGERFNSPEC SALESF(%INTEGER PRICE, AREA, DELTAC)
      %ROUTINESPEC ORDERS INTERDEPENDANCE(%INTEGER AREA)
      %INTEGERFNSPEC MARKETING EFFECT(%INTEGER EC)
      %ROUTINESPEC CHANGE NPROD
      %INTEGERFNSPEC GET LOAN LIMIT(%RECORDNAME F)
      %ROUTINESPEC BANCRUPT(%RECORDNAME F)
      %INTEGERFNSPEC ASK FOR LOAN(%RECORDNAME F)
      %ROUTINESPEC GET CASH FIGURES(%RECORDNAME F)
      %INTEGERFNSPEC ASSETS(%RECORDNAME F)
      %ROUTINESPEC SET SALES(%INTEGER FIRM)
      %INTEGERFNSPEC CALC COSTS(%RECORDNAME F)
      %ROUTINESPEC READ VARIABLES(%INTEGER FIRM)
      %ROUTINESPEC PRINT POSITION(%INTEGER FIRM)
      %ROUTINESPEC SET MACHINE POSITION(%INTEGER FIRM)
      !!
      %OWNINTEGERARRAY SAL CON(0:2)=80000, 130000, 280000
      %OWNINTEGERARRAY SAL GRD(0:2)=250, 1500, 4000
      !!
      %OWNINTEGERARRAY DELIV(0:3)=1, 2, 2, 3
      !* (OWN AREA, COMPETETOR, COMMON)*2
      %OWNREAL VARBC1=27.9449
      %OWNINTEGER VARBC2=371390
      %OWNREAL FIXEDC1=1.7942
      %OWNINTEGER FIXEDC2=1503216
      !!
      %INTEGERARRAY ORDERS, SALES, ADD SALES, MARKETI, PRICE(1:2, 1:3)
      %INTEGERARRAY SALESI, MARKET(1:2, 1:3)
      %INTEGERARRAY TORDERS, TSALES(1:3)
      !!
      %RECORDFORMAT FIRMRC(%INTEGER FIXED, VARB, CASH, PROFIT, %C
        EXTRAP, NPROD, PROD, PRODC, NPRODC, SELL, STOCK, TORD, LOAN, %C
        NO, DEL, MT)
      %RECORDARRAY FIRMA(1:2)(FIRMRC)
      %RECORDNAME F(FIRMRC)
      !!
      %INTEGER ECONOMY, TM, TCM, TP, I, J, PERIOD, AREA, FIRM
      %INTEGER DELTAC, DELTAC2, SI, MT, ORD, FLAG, BFLAG
      %INTEGERNAME MKT
      !!
      %CYCLE FIRM=1, 1, 2
         F==FIRMA(FIRM);  F=0
         %CYCLE AREA=1, 1, 3
            TORDERS(AREA)=0;  TSALES(AREA)=0
            MARKET(FIRM, AREA)=750000; ! THIS IS INITIAL 'GOOD WILL'
            MARKETI(FIRM, AREA)=150000
                                       ! INITIAL MARKETING
            PRICE(FIRM, AREA)=50;      ! INITIAL PRICE
            ORDERS(FIRM, AREA)=0
            SALES(FIRM, AREA)=0
            SALESI(FIRM, AREA)=0
         %REPEAT
         MARKET(FIRM, FIRM)=1000000
         F_NO=FIRM
         F_CASH=10000000
         F_NPROD=230321
         F_PROD=237180
         F_LOAN=2000000
      %REPEAT
      !*
      %IF S#'' %START
         DEFINE('ST1,'.S)
      %FINISH
      ECONOMY=RAND INT-10
      ECONOMY STATE(ECONOMY)
      PERIOD=0
      TCM=3*500000
      !!
      %WHILE 0=0 %CYCLE
         BFLAG=0
         CHANGE NPROD
         PERIOD=PERIOD+1
RECAL:   READ VARIABLES(1)
         %RETURNIF FLAG<0
         SET MACHINE POSITION(2)
         TM=0;  TP=0;  FIRMA(1)_TORD=0;  FIRMA(2)_TORD=0
         !*
         !****** INITIAL COSTS CALCULATION **************
         %CYCLE FIRM=1, 1, 2
            F==FIRMA(FIRM)
            J=CALC COSTS(F)
            TP=GET LOAN LIMIT(F)-F_LOAN
            %IF TP<0 %START
               %IF FIRM#2 %START;       ! NOT MACHINE
                  PRINTSTRING("#");  WRITE(-TP, 1)
                  PRINTSTRING(' OF YOUR LOAN MUST BE REPAID!
')
               %FINISH
               F_CASH=F_CASH+TP;  F_LOAN=F_LOAN+TP
            %FINISH
            MT=0
            %CYCLE AREA=1, 1, 3;  MT=MT+MARKETI(FIRM, AREA)
            %REPEAT
            F_MT=MT
            I=0
            %IF F_PRODC+MT>F_CASH %START
               I=ASK FOR LOAN(F)
               F_CASH=F_CASH+I
               F_LOAN=F_LOAN+I
               %IF F_CASH-F_PRODC-F_MT<0 %START
                  %IF BFLAG#0 %START
                     -> RECAL
                  %FINISH
                  BANCRUPT(F)
                  %IF F_NO=2 %THENRETURN; ! MACHINE HAS HAD IT
                  BFLAG=1
                  ->RECAL
               %FINISH
            %FINISH
            F_CASH=F_CASH-F_PRODC-MT
         %REPEAT
         !*
         !***** CALCULATION OF ORDERS ********************************
         !*
         %CYCLE AREA=1, 1, 3
            TM=0;  TP=0;  TORDERS(AREA)=0;  TSALES(AREA)=0
            %CYCLE FIRM=1, 1, 2
               F==FIRMA(FIRM)
               MKT==MARKET(FIRM, AREA)
               MKT=MKT*3//4+MARKETI(FIRM, AREA)
               DELTAC2=MARKETING EFFECT(MKT)
               ORD=SALESF(PRICE(FIRM, AREA), AREA, DELTAC2)
               ORDERS(FIRM, AREA)=ORD
            %REPEAT
            ORDERS INTERDEPENDANCE(AREA)
         %REPEAT
         %CYCLE FIRM=1, 1, 2
            F==FIRMA(FIRM)
            F_DEL=0;                   ! DELIVERY COSTS
            %CYCLE AREA=1, 1, 3
               J=ORDERS(FIRM, AREA)
               F_TORD=J+F_TORD
               %IF AREA=FIRM %THEN F_DEL=F_DEL+J*DELIV(0) %ELSE %C
                 F_DEL=F_DEL+J*DELIV(AREA)
            %REPEAT
         %REPEAT
         !*
         !******************************** END OF ORDERS CALCUL ***
         !*
         %CYCLE FIRM=1, 1, 2
            F==FIRMA(FIRM)
            SET SALES(FIRM)
            SI=0
            %CYCLE AREA=1, 1, 3
               SI=SI+SALESI(FIRM, AREA)
            %REPEAT
            GET CASH FIGURES(F)
         %REPEAT
         %IF FLAG#0 %THEN PRINT POSITION(1)
         %IF S#'' %START
            SELECT OUTPUT(1)
            NEWPAGE
            PRINTSTRING('PERIOD ');  WRITE(PERIOD,2);  NEWLINES(2)
            ECONOMY STATE(ECONOMY)
            PRINT POSITION(1)
            PRINT POSITION(2)
            SELECT OUTPUT(0)
         %FINISH
         ECONOMY=ECONOMY+(RAND INT-10)//5
         ECONOMY STATE(ECONOMY)
         ECONOMY ON SALES(ECONOMY)
      %REPEAT
      !!


      %INTEGERFN SALESF(%INTEGER PRICE, AREA, DELTAC)
         %INTEGER I, X, N
         I=0
         %IF AREA=3 %THEN N=2 %ELSE N=1
         %IF PRICE>60 %THEN I=2 %ELSESTART
            %IF PRICE>40 %THEN I=1
         %FINISH
         X=(SAL CON(I)+DELTAC-SAL GRD(I)*PRICE)*N
         %RESULT =X %IF X>0
         %RESULT =0
      %END
      !!


      %ROUTINE ECONOMY ON SALES(%INTEGER EC)
         %INTEGER I, X
         X=200*EC
         %CYCLE I=0, 1, 2
            SAL CON(I)=SAL CON(I)+X
         %REPEAT
      %END
      !!


      %ROUTINE ECONOMY STATE(%INTEGER EC)
         PRINTSTRING('THE ECONOMY IS ')
         %IF EC>=8 %THEN PRINTSTRING('IN A BOOM') %ELSESTART
            %IF EC>0 %THEN PRINTSTRING('EXPANDING') %ELSESTART
               %IF EC=0 %THEN PRINTSTRING('STATIC') %ELSESTART
                  PRINTSTRING('IN A ')
                  %IF EC>-8 %THEN PRINTSTRING('RECESSION') %ELSESTART
                     PRINTSTRING('SLUMP')
                  %FINISH ;  %FINISH ;  %FINISH ;  %FINISH
         NEWLINE
      %END
      !!


      %ROUTINE ORDERS INTERDEPENDANCE(%INTEGER AREA)
         %INTEGER FIRM, DIFF, PLUSMI, DIFFP
         %INTEGERNAME A, B
         A==ORDERS(1, AREA);  B==ORDERS(2, AREA)
         DIFF=A-B
         DIFFP=PRICE(1, AREA)-PRICE(2, AREA)
         %IF ECONOMY<-10 %THEN ECONOMY=-10
         PLUSMI=-DIFF*DIFFP*3//(11+ECONOMY)
         %IF DIFFP>0 %THEN PLUSMI=-PLUSMI
         A=A+PLUSMI;  B=B-PLUSMI
         A=0 %IF A<0;  B=0 %IF B<0
      %END
      !!


      %INTEGERFN MARKETING EFFECT(%INTEGER EC)
         %RESULT =EC//150-10000
         !*
         !* NOTE: M=   0 => -10000 UNITS
         !*       M=1.5M => +0 UNITS
         !*       M=  3M => +10000 UNITS
         !*
      %END
      !!


      %ROUTINE CHANGE NPROD
         %INTEGER FIRM
         %RECORDNAME F(FIRMRC)
         %CYCLE FIRM=1, 1, 2
            F==FIRMA(FIRM)
            F_PROD=F_NPROD
         %REPEAT
      %END
      !!


      %INTEGERFN GET LOAN LIMIT(%RECORDNAME F)
         %RECORDSPEC F(FIRMRC)
         %RESULT =ASSETS(F)//3
      %END
      !!


      %ROUTINE BANCRUPT(%RECORDNAME F)
         %RECORDSPEC F(FIRMRC)
         %IF F_NO=2 %START
            PRINTSTRING('FIRM 2 IS BUST!
YOU ARE THE WINNER
')
         %FINISHELSESTART
            PRINTSTRING('YOU HAVE EXTREME CASH FLOW PROBLEMS,
WHAT ARE YOU GOING TO DO?
')
         %FINISH
      %END
      !!


      %INTEGERFN ASK FOR LOAN(%RECORDNAME F)
         %RECORDSPEC F(FIRMRC)
         %INTEGER DIFF, NEW
         DIFF=F_PRODC+F_MT-F_CASH
         NEW=GET LOAN LIMIT(F)
         %IF NEW>DIFF %THEN NEW=DIFF
         %IF F_NO#2 %START
            PRINTSTRING('THE COMPANY IS SHORT OF #')
            WRITE(DIFF, 1)
            PRINTSTRING( %C
              ' FOR PRODUCTION COSTS,
Do you wish to apply for a  loan?
')
            PROMPT('Y OR N:')
            READSYMBOL(I) %UNTIL I#' ' %AND I#NL
            %IF 'a'<=I<='z' %THEN I=I-'a'+'A'
            %IF I='N' %THEN NEW=0 %ELSE %START
               PRINTSTRING("Loan of #");WRITE(NEW, 1); PRINTSTRING %C
               (" granted
")
           %FINISH
         %FINISH
         %RESULT =NEW
      %END
      !!


      %ROUTINE GET CASH FIGURES(%RECORDNAME F)
         %RECORDSPEC F(FIRMRC)
         %INTEGER INTEREST
         INTEREST=F_LOAN*12//100
         F_PROFIT=SI-F_DEL-INTEREST-F_PRODC-5*F_PRODC//100
         F_CASH=F_CASH+SI-F_DEL
         F_LOAN=F_LOAN+INTEREST
         F_EXTRAP=0;                    ! PRODUCTION IMPLEMENTED
      %END
      !!


      %INTEGERFN ASSETS(%RECORDNAME F)
         %REAL R, R2, R3
         %RECORDSPEC F(FIRMRC)
         %INTEGER X, Y
         X=F_CASH+F_NPROD*20
         R = F_STOCK; R2 = F_PRODC; R = R*R2; R2 = F_PROD
         R3 = R/R2
         Y = INT PT(R3)
         %RESULT =X+Y-F_LOAN
      %END
      !!


      %ROUTINE SET SALES(%INTEGER FIRM)
         %RECORDNAME F(FIRMRC)
         %INTEGER ST, MST, I, N, X, NSTK, SUB
         F==FIRMA(FIRM)
         MST=F_TORD-F_STOCK
         SUB=0
         ST=F_PROD-MST
         %IF ST<0 %START ;             ! OOPS
            SUB=-ST
            NSTK=0;                    ! NO STOCK LEFT
         %FINISHELSE NSTK=ST
         %CYCLE I=1, 1, 3
            %IF I=3 %THEN N=2 %ELSE N=4
            X=ORDERS(FIRM, I)-SUB//N
            %IF X<0 %THEN X=0
            SALES(FIRM, I)=X
            SALESI(FIRM, I)=X*PRICE(FIRM, I)
            TSALES(I)=TSALES(I)+X
            TORDERS(I)=TORDERS(I)+ORDERS(FIRM, I)
         %REPEAT
         F_STOCK=NSTK;                 ! UPDATE STOCK LEVEL
      %END


      %INTEGERFN CALC COSTS(%RECORDNAME F)
         %RECORDSPEC F(FIRMRC)
         %INTEGER X, Y, Z
         X=INT PT(FIXEDC1*F_PROD)+FIXEDC2
         Y=INT PT(VARBC1*F_PROD)+VARBC2
         F_FIXED=X;  F_VARB=Y;  F_PRODC=X+Y
         F_NPROD=INT PT(F_PROD*95/100)+F_EXTRAP
         F_NPRODC=INT PT((FIXEDC1+VARBC1)*F_NPROD)+FIXEDC2+VARBC2
         %RESULT =X+Y
      %END


      %ROUTINE READ VARIABLES(%INTEGER FIRM)
         %INTEGER I, N, X
         %RECORDNAME F2(FIRMRC)
         %SWITCH SW COM(0:12)
         %OWNBYTEINTEGERARRAY COMS(0:12)= %C
         'B', 'P', 'C', 'S', 'Q', 'M', 'D', '?', 'A',
         'E', 'R', 'F', 'X'
         %RECORDNAME F(FIRMRC)
         !!


         %ROUTINE ANNOUNCE
            %INTEGER I, X
            PRINTSTRING('POSITION:-
')
            %CYCLE I=1, 1, 2
               F2==FIRMA(I)
               PRINTSTRING('FIRM');  WRITE(I, 1)
               PRINTSTRING(' BALANCE:');  WRITE(ASSETS(F2), 8)
               NEWLINE
            %REPEAT
         %END
         !!
         F==FIRMA(FIRM)
LOOP:
         PROMPT('Instructions?')
         READSYMBOL(I) %UNTIL I#' ' %AND I#NL
         %IF 'a' <= I <= 'z' %THEN I = I-'a'+'A'
         %CYCLE N=0, 1, 12
            ->SW COM(N) %IF COMS(N)=I
         %REPEAT
SW COM(7):                             ! ERROR
         PRINTSTRING('PLEASE REPLY:-
B - BUY NEW PRODUCTION
M - SET MARKETING EXPENDITURE
P - SET PRICE LEVELS
D - DISPLAY POSITION AT END OF PERIOD
C - CONTINUE TO NEXT STAGE
S - SELL PRODUCTION
E - EXAMINE THE COMPANY STATE.')
         PRINTSTRING('
R - REPAY (PART OF) LOAN.
A - ANNOUNCE GENERAL POSITION (ALL FIRMS).
F - FULL FINANCIAL POSITION.
Q - STOP GAME.
')
         %IF I#NL %START
            READSYMBOL(I) %UNTIL I=NL
         %FINISH
         ->LOOP
         !!
SW COM(2):                             ! CALCULATE/CONTINUE
         FLAG=0
         %RETURN
SW COM(6):                             ! DISPLAY RESULTS
         FLAG=1
         %RETURN
         !!
SW COM(1):                             ! PRICES
         PROMPT('IN EACH AREA?')
         %CYCLE I=1, 1, 3
            READ(PRICE(FIRM, I))
         %REPEAT
         ->LOOP
         !!
SW COM(5):                             ! MARKETING
         PROMPT('IN EACH AREA?')
         %CYCLE I=1, 1, 3
            READ(N)
            MARKETI(FIRM, I)=N
         %REPEAT
         ->LOOP
         !!
SW COM(4):                             ! FINISH GAME
         PRINTSTRING('FINAL ')
         ANNOUNCE
         FLAG=-1
         %RETURN
SW COM(8):                             ! ANNOUNCE
         ANNOUNCE
         ->LOOP
         !!
         !!
SW COM(0):                             ! NEW PRODUCTION
         PROMPT('NO. OF UNITS?')
         READ(F_EXTRAP)
         ->CHT %IF F_EXTRAP<=0
         PRINTSTRING('AT A COST OF #');  WRITE(F_EXTRAP*20, 1)
         NEWLINE
         F_CASH=F_CASH-F_EXTRAP*20
         ->LOOP
SW COM(3):                             ! SELL
         PROMPT('NO. TO GO?')
         READ(X)
         %IF X>=F_PROD %OR X<=0 %START
CHT:        PRINTSTRING('CHEAT!
')
            ->LOOP
         %FINISH
         F_SELL=X
         F_PROD=F_PROD-X
         F_NPROD=F_NPROD-X
         I=CALC COSTS(F);               ! RECALCULATE COSTS
         F_CASH=F_CASH+X*15
         PRINTSTRING("#");  WRITE(X*15, 1);  PRINTSTRING( %C
           ' ADDED TO CASH BALANCE
')
         ->LOOP
SW COM(9):                             ! EXAMINE COMPANY STATE
         PRINT POSITION(F_NO)
         ->LOOP
         !!
SW COM(10):                            ! REPAY LOAN
         PRINTSTRING('CURRENT LOAN (AND INTEREST) STANDS AT:')
         WRITE(F_LOAN, 1)
         NEWLINE
         PROMPT('REPAY #');  READ(X)
         ->CHT %IF X<0
         F_LOAN=F_LOAN-X
         F_CASH=F_CASH-X
         ->LOOP
         !!
SW COM(12):                             ! BRIANS SPECIAL
         F==FIRMA(2)
SW COM(11):                            ! FULL FINANCIAL POSITION
         PRINTSTRING( 'PLANT:        ');  WRITE(F_PROD*20, 11)
         PRINTSTRING('
STOCK:        ');  WRITE(F_STOCK, 11)
         PRINTSTRING('
CASH:         ');  WRITE(F_CASH, 11)
         PRINTSTRING('
BALANCE:      ');  WRITE(ASSETS(F), 11)
         PRINTSTRING('

LOANS (INC INT)');  WRITE(F_LOAN, 10)
         PRINTSTRING('
BORROW LIMIT:  ');  WRITE(GET LOAN LIMIT(F)+F_LOAN, 10)
         NEWLINE
         F==FIRMA(FIRM)
         ->LOOP
         !!
      %END


      %ROUTINE PRINT POSITION(%INTEGER FIRM)


         %ROUTINE DASH
            %INTEGER I
            NEWLINE
            %CYCLE I=1, 1, 72;  PRINTSYMBOL('-');  %REPEAT
            NEWLINE
         %END
         !!


         %ROUTINE PUT(%INTEGERARRAYNAME DETAILS)
            %INTEGER AREA, SUM, N
            SUM=0
            %CYCLE AREA=1, 1, 3
               N=DETAILS(FIRM, AREA)
               SUM=SUM+N
               WRITE(N, 11)
            %REPEAT
            SPACES(5); WRITE(SUM, 10)
         %END
         %ROUTINE PUT2(%INTEGERARRAYNAME DETAILS)
            %INTEGER AREA, SUM, N
            SUM=0
            %CYCLE AREA=1, 1, 3
               N=DETAILS(AREA)
               SUM=SUM+N
               WRITE(N, 11)
            %REPEAT
            SPACES(5); WRITE(SUM, 10)
         %END
         !!
         %INTEGER AREA, I, J
         %RECORDNAME F(FIRMRC)
         F==FIRMA(FIRM)
         NEWLINES(3)
         PRINTSTRING('FIRM NO.');  WRITE(FIRM, 1)
         SPACES(17)
         PRINTSTRING('AREA 1      AREA 2      AREA 3        TOTALS
Area Orders:        ')
         PUT2(TORDERS);  NEWLINE
         PRINTSTRING('Area Sales:         ');  PUT2(TSALES);  NEWLINE
         %CYCLE I=1, 1, 2
            PRINTSTRING('Prices CO');  WRITE(I, 1);  SPACES(9)
            %CYCLE AREA=1, 1, 3
               WRITE(PRICE(I, AREA), 11)
            %REPEAT
            NEWLINE
         %REPEAT
         NEWLINE
         PRINTSTRING('Orders: (units)     ');  PUT(ORDERS)
         PRINTSTRING('
Sales: (units)      ');  PUT(SALES)
         PRINTSTRING('
Marketing: (Pounds) ');  PUT(MARKETI)
         PRINTSTRING('
Sales Income:       ');  PUT(SALESI)
         DASH
         PRINTSTRING('Production:');  WRITE(F_PROD, 8)
         PRINTSTRING('  Cost:');  WRITE(F_PRODC, 8)
         PRINTSTRING('  COST/UNIT:');  PRINT(F_PRODC/F_PROD, 3, 2)
         PRINTSTRING(' LOAN:');  WRITE(F_LOAN, 10)
         PRINTSTRING('
NEXT PERIOD:');  WRITE(F_NPROD, 7)
         PRINTSTRING('  COST:');  WRITE(F_NPRODC, 8)
         PRINTSTRING('  COST/UNIT:');  PRINT(F_NPRODC/F_NPROD, 3, 2)
         PRINTSTRING(' STOCK:');  WRITE(F_STOCK, 9)
         DASH
         PRINTSTRING('PROFIT WAS: ');  WRITE(F_PROFIT, 8)
         PRINTSTRING('  CASH=');  WRITE(F_CASH, 8)
         PRINTSTRING('  BALANCE:');  WRITE(ASSETS(F), 8)
         NEWLINE
      %END


      %ROUTINE SET MACHINE POSITION(%INTEGER FIRM)
         %RECORDNAME F(FIRMRC)
         %INTEGER A, B, C
         F==FIRMA(FIRM)
         %IF PERIOD=1 %START
            PRICE(FIRM, 2)=PRICE(FIRM, 2)-1
            PRICE(FIRM, 3)=PRICE(FIRM, 3)+1
         %FINISHELSESTART
         %IF F_STOCK>20000 %THEN B=F_STOCK//30000 %ELSE B=0
         %IF F_STOCK=0 %START
            C=ORDERS(FIRM, FIRM)-SALES(FIRM, FIRM)
            B=-C//5000
        %IF F_CASH-F_PRODC-F_MT>12000*20 %START; ! MAINT. ADE. CASH FL
               F_EXTRAP=12000;  F_CASH=F_CASH-12000*20
            %FINISH
         %FINISH
         %CYCLE A=1, 1, 3
            PRICE(FIRM, A)=PRICE(FIRM, A)-B
            MARKETI(FIRM, A)=4*SALES(FIRM, A)
         %REPEAT
         %FINISH
         %IF F_CASH>F_LOAN %THEN F_LOAN=0 %AND F_CASH=F_CASH-F_LOAN
      %END
%END
%ENDOFFILE