PROGRAM WarFinal(Input,Output,InFile,OutFile);

{JOSHUA DAVIS-Programmer      Design:    3/19/93   Note:                     }
{Strategic Battle Simulator   First Run: 3/26/93   The Const section defines }
{AP Computer Science          1000 Lines:4/05/93   many game characteristics.}
{Final Project                Coding:    4/16/93   Prices are independent of }
{Mr. Tom Bailey-Teacher       Updated:   4/23/93   the actual power derived. }

USES
     CRT;

CONST
     Extended=False;                          {toggles extended board display}
     Assassins=True;                    {toggles possibility of assassination}
     Saboteurs=True;                         {toggles possibility of sabotage}
     Engineers=True;                                     {toggles engineering}
     Ys=10;                                           {vertical size of board}
     Hv=5000;                                            {criterion for heavy}
     Md=2500;                                           {criterion for medium}
     Ic=20;                                                {cost per infantry}
     Cc=40;                                                 {cost per cavalry}
     Ac=30;                                                 {cost per archery}
     Bc=100;                                              {cost per ballistic}
     Ec=70;                                                {cost per engineer}
     Sc=70;                                                     {cost per spy}
     Oc=150;                                                {cost per officer}
     Ind=4;                                                {initial divisions}
     Inm=0;                                                    {initial money}
     Ino=2;                                                 {initial officers}
     Ini=400;                                  {initial infantry per division}
     Inc=50;                                    {initial cavalry per division}
     Ina=50;                                    {initial archery per division}
     Inb=0;                                  {initial ballistics per division}
     Ine=0;                                   {initial engineers per division}
     Ins=0;                                       {initial spies per division}
     Io=2;                                              {infantry power ratio}
     Co=3;                                               {cavalry power ratio}
     Ao=2;                                               {archery power ratio}
     Bo=10;                                           {ballistics power ratio}
     So=200;                                                 {spy power ratio}
     Oo=3;                                               {officer power ratio}
     Fo=2;                                   {archery forest power adaptation}
     Vo=1.5;                                          {victory interest ratio}
     Rb=2;                               {base for randomly-generated numbers}
     Ss=Rb+0.8;                                {criterion for a secret strike}
     As=Rb+1.1;                                  {criterion for assassination}
     Cd=0.70;                                                   {chaos effect}
     Tr=5;                                     {rows per terrain in 'WarTerr'}
     Blanks='                    ';                         {blanks out names}

TYPE
     DivRec=RECORD
            Iy,Ca,Ar,Ba,Si,En,Sp:Real;
            Mo:Integer;
            Ge:Boolean;
            END;
     PlayerType=RECORD
                Nam:ARRAY [1..20] OF Char;
                Str,Dvs:Integer;
                Mon,Off:Real;
                Inv:ARRAY [1..10] OF DivRec;
                END;
     ControlType=RECORD
                 D,M,T:Integer;
                 I,C,A,B,S,E,P:Real;
                 Gen:Boolean;
                 END;
     PlayerArray=ARRAY [1..20] OF PlayerType;
     ControlArray=ARRAY [1..10,1..Ys] OF ControlType;
     CFile=FILE OF PlayerType;

VAR
     Play:PlayerArray;
     Cont:ControlArray;
     CrX,CrY,PlCnt,Selector,P,One,Two,Att:Integer;
     VicOne,VicTwo,Exit,Dead:Boolean;
     Answer,Ans:Char;

PROCEDURE Initialize(VAR Play:PlayerArray;VAR Exit:Boolean);
          VAR
            I,J,K:Integer;
          BEGIN
            Exit:=False;
            FOR I:=1 TO 20 DO BEGIN
             Play[I].Nam:=Blanks;
             Play[I].Str:=0;
             Play[I].Dvs:=0;
             Play[I].Mon:=0;
             Play[I].Off:=0;
             FOR K:=1 TO 10 DO BEGIN
              Play[I].Inv[K].Iy:=0;
              Play[I].Inv[K].Ca:=0;
              Play[I].Inv[K].Ar:=0;
              Play[I].Inv[K].Ba:=0;
              Play[I].Inv[K].Si:=0;
              Play[I].Inv[K].Mo:=0;
              Play[I].Inv[K].En:=0;
              Play[I].Inv[K].Sp:=0;
              Play[I].Inv[K].Ge:=False;
             END;
            END;
          END;

PROCEDURE Help;
          BEGIN
            ClrScr;
            Writeln('The Help section has not been written.  Writing it');
            Writeln('is an easy process, however, and so it will be done');
            Writeln('as the final program touches are added.  The pro-');
            Writeln('grammer apologizes for this temporary inconvenience.');
          END;

PROCEDURE ArmyList(VAR Play:PlayerArray;PlCnt:Integer);
          VAR
            I,J:Integer;
            Size:Real;
          BEGIN
            ClrScr;
            Writeln(' # COMMANDER            STRIKERS SIZE');
            Writeln;
            FOR I:=1 TO PlCnt DO BEGIN
             IF Play[I].Dvs<>0 THEN BEGIN
              Write(I:2,' ');
              FOR J:=1 TO 20 DO Write(Play[I].Nam[J]);
              Write(' ');
              IF Play[I].Off>=10 THEN Write(Play[I].Off:2:0,'       ')
               ELSE Write(Play[I].Off:1:0,'        ');
              Size:=0;
              FOR J:=1 TO 10 DO Size:=Size+(Play[I].Inv[J].Si);
              Writeln(Size:1:0);
             END;
            END;
            Readln;
          END;

PROCEDURE Create(VAR Play:PlayerArray;VAR PlCnt:Integer);
          VAR
            I,J:Integer;
          BEGIN
            ClrScr;
            Writeln('What do you wish to name your new commander?');
            Writeln('You may use up to twenty characters.');
            I:=0;
            PlCnt:=PlCnt+1;
            WHILE (NOT EOLN) AND (I<20) DO BEGIN
             I:=I+1;
             Read(Play[PlCnt].Nam[I]);
            END;
            Readln;
            Play[PlCnt].Str:=I;
            Play[PlCnt].Mon:=Inm;
            Play[PlCnt].Dvs:=Ind;
            Play[PlCnt].Off:=Ino;
            FOR J:=1 TO Ind DO BEGIN
             Play[PlCnt].Inv[J].Iy:=Ini;
             Play[PlCnt].Inv[J].Ca:=Inc;
             Play[PlCnt].Inv[J].Ar:=Ina;
             Play[PlCnt].Inv[J].Ba:=Inb;
             Play[PlCnt].Inv[J].En:=Ine;
             Play[PlCnt].Inv[J].Sp:=Ins;
             Play[PlCnt].Inv[J].Si:=(Play[PlCnt].Inv[J].Iy)*Io+
              (Play[PlCnt].Inv[J].Ca)*Co+(Play[PlCnt].Inv[J].Ar)*Ao+
              (Play[PlCnt].Inv[J].Ba)*Bo;
             Play[PlCnt].Inv[J].Mo:=3;
             IF (2*(Play[PlCnt].Inv[J].Ca))>=(Play[PlCnt].Inv[J].Iy)
              THEN Play[PlCnt].Inv[J].Mo:=(Play[PlCnt].Inv[J].Mo)+1;
             IF (Play[PlCnt].Inv[J].Ca)>=(Play[PlCnt].Inv[J].Iy)
              THEN Play[PlCnt].Inv[J].Mo:=(Play[PlCnt].Inv[J].Mo)+1;
             IF (10*(Play[PlCnt].Inv[J].Ba))>(Play[PlCnt].Inv[J].Iy)
              THEN Play[PlCnt].Inv[J].Mo:=(Play[PlCnt].Inv[J].Mo)-1;
            END;
            Play[PlCnt].Inv[1].Ge:=True;
            Writeln('Your beginning-level army has been created.');
            Writeln('You will have a chance to customize it before combat.');
            Readln;
          END;

PROCEDURE Rename(VAR Play:PlayerArray;PlCnt:Integer);
          VAR
            I,J:Integer;
            Ans:Char;
          BEGIN
            ClrScr;
            Writeln('Which commander do you wish to rename? Type #.');
            Readln(I);
            Write('This is ');
            FOR J:=1 to 20 DO Write(Play[I].Nam[J]);
            Writeln;
            IF Play[I].Dvs=0 THEN BEGIN
             Writeln('You cannot rename a non-entity.');
             Readln;
            END
             ELSE BEGIN
              Writeln('Are you sure you want to change it? Type Y or N.');
              Readln(Ans);
              IF Ans='Y' THEN BEGIN
               Writeln('Type name. You may use up to twenty characters.');
               Play[I].Nam:=Blanks;
               J:=0;
               Writeln('Enter new name.');
               WHILE (NOT EOLN) AND (J<20) DO BEGIN
                J:=J+1;
                Read(Play[I].Nam[J]);
               END;
               Readln;
               Play[I].Str:=J;
               Writeln('Name changed.');
               Readln;
              END;
             END;
          END;

PROCEDURE Menu;
          BEGIN
            Write('In your quest for domination of');
            Writeln(' Europe you have these options:');
            Writeln('[1] EXPLANATION');
            Writeln('[2] VIEW ARMIES');
            Writeln('[3] CREATE AN ARMY');
            Writeln('[4] RENAME A COMMANDER');
            Writeln('[5] GO TO WAR');
            Writeln('[6] SAVE CHANGES');
            Writeln('[7] QUIT PROGRAM');
          END;

PROCEDURE InputArrays(VAR Play:PlayerArray;VAR PlCnt:Integer);
          VAR
            InFile:CFile;
          BEGIN
            Assign(InFile,'WarBin');
            Reset(InFile);
            PlCnt:=0;
            WHILE NOT EOF(InFile) DO BEGIN
             PlCnt:=PlCnt+1;
             Read(InFile,Play[PlCnt]);
            END;
            Close(InFile);
          END;

PROCEDURE WriteFile(VAR Play:PlayerArray;PlCnt:Integer);
          VAR
            OutFile:CFile;
            J:Integer;
          BEGIN
            Assign(OutFile,'WarBin');
            Rewrite(OutFile);
            FOR J:=1 TO PlCnt DO
             IF Play[J].Dvs<>0 THEN Write(OutFile,Play[J]);
            Close(OutFile);
          END;

PROCEDURE DivDisp(VAR Cont:ControlType);
          BEGIN
            Writeln('Size       ',Cont.S:1:0);
            Writeln('Movement   ',Cont.M);
            Writeln('Infantry   ',Cont.I:1:0);
            Writeln('Cavalry    ',Cont.C:1:0);
            Writeln('Archery    ',Cont.A:1:0);
            Writeln('Ballistics ',Cont.B:1:0);
            Writeln('Engineers  ',Cont.E:1:0);
            Writeln('Spies      ',Cont.P:1:0);
            Write('Commander  ');
            IF (Cont.Gen) THEN Writeln('Present')
             ELSE Writeln('Absent');
            Readln;
          END;

PROCEDURE Shift(VAR From,At:ControlType);
          BEGIN
            At.D:=From.D;
            At.M:=From.M;
            At.S:=From.S;
            At.I:=From.I;
            At.C:=From.C;
            At.A:=From.A;
            At.B:=From.B;
            At.E:=From.E;
            At.P:=From.P;
            At.Gen:=From.Gen;
            From.D:=0;
            From.M:=0;
            From.S:=0;
            From.I:=0;
            From.C:=0;
            From.A:=0;
            From.B:=0;
            From.E:=0;
            From.P:=0;
            From.Gen:=False;
          END;

PROCEDURE ClearControl(VAR Cont:ControlArray);
          VAR
            X,Y,CrX,CrY:Integer;
          BEGIN
            FOR CrX:=1 TO 10 DO
             FOR CrY:=1 TO Ys DO Cont[CrX,CrY].T:=0;
            CrX:=1;
            CrY:=1;
            Cont[CrX,CrY].D:=0;
            Cont[CrX,CrY].M:=0;
            Cont[CrX,CrY].T:=0;
            Cont[CrX,CrY].S:=0;
            Cont[CrX,CrY].I:=0;
            Cont[CrX,CrY].C:=0;
            Cont[CrX,CrY].A:=0;
            Cont[CrX,CrY].B:=0;
            Cont[CrX,CrY].E:=0;
            Cont[CrX,CrY].P:=0;
            Cont[CrX,CrY].Gen:=False;
            FOR X:=1 TO 10 DO
             FOR Y:=1 TO YS DO Shift(Cont[CrX,CrY],Cont[X,Y]);
          END;

PROCEDURE Format;
          BEGIN
            GotoXY(1,22);
            Write('                                       ');
            Writeln('                                       ');
            Write('                                       ');
            Writeln('                                       ');
            Write('                                       ');
            Writeln('                                       ');
            GotoXY(1,22);
          END;

PROCEDURE Display(VAR Cont:ControlArray);
          VAR
            X,Y:Integer;
          BEGIN
            GotoXY(1,1);
            Write('    ');
            FOR X:=1 TO 10 DO Write(X,'   ');
            Writeln;
            FOR Y:=1 TO Ys DO BEGIN
             Write(Y:2,' ');
             FOR X:=1 TO 10 DO BEGIN
              IF Cont[X,Y].T>1 THEN Write(Chr(30),Chr(30),Chr(30),' ')
               ELSE IF Cont[X,Y].T<0
                THEN Write(Chr(176),Chr(176),Chr(176),' ')
                ELSE BEGIN
                 IF Cont[X,Y].D>10 THEN Write('2')
                  ELSE IF Cont[X,Y].D>0 THEN Write('1')
                   ELSE IF Cont[X,Y].T=1 THEN Write(Chr(5))
                    ELSE Write(' ');
                 IF Cont[X,Y].I>0 THEN Write('I')
                  ELSE IF Cont[X,Y].T=1 THEN Write(Chr(5))
                   ELSE Write(' ');
                 IF Cont[X,Y].C>0 THEN Write('C ')
                  ELSE IF Cont[X,Y].T=1 THEN Write(Chr(5),' ')
                   ELSE Write('  ');
                END;
             END;
             Writeln;
             Write('   ');
             FOR X:=1 TO 10 DO BEGIN
              IF Cont[X,Y].T>1 THEN Write(Chr(30),Chr(30),Chr(30),' ')
               ELSE IF Cont[X,Y].T<0
                THEN Write(Chr(176),Chr(176),Chr(176),' ')
                ELSE BEGIN
                 IF Cont[X,Y].S>Hv THEN Write('H')
                  ELSE IF Cont[X,Y].S>Md THEN Write('M')
                   ELSE IF Cont[X,Y].S>0 THEN Write('L')
                    ELSE IF Cont[X,Y].T=1 THEN Write(Chr(5))
                     ELSE Write(' ');
                 IF Cont[X,Y].A>0 THEN Write('A')
                  ELSE IF Cont[X,Y].T=1 THEN Write(Chr(5))
                   ELSE Write(' ');
                 IF Cont[X,Y].B>0 THEN Write('B ')
                  ELSE IF Cont[X,Y].T=1 THEN Write(Chr(5),' ')
                   ELSE Write('  ');
                END;
             END;
             Writeln;
             IF Extended THEN Writeln;               {lengthens board display}
            END;
            Format;
          END;

PROCEDURE DispDist(VAR Play:PlayerType);
          VAR
            I,J:Integer;
          BEGIN
            Write('     ');
            FOR J:=1 TO 10 DO Write(J,'     ');
            Writeln;
            Write('I');
            FOR J:=1 TO 10 DO Write(Play.Inv[J].Iy:5:0,' ');
            Writeln;
            Write('C');
            FOR J:=1 TO 10 DO Write(Play.Inv[J].Ca:5:0,' ');
            Writeln;
            Write('A');
            FOR J:=1 TO 10 DO Write(Play.Inv[J].Ar:5:0,' ');
            Writeln;
            Write('B');
            FOR J:=1 TO 10 DO Write(Play.Inv[J].Ba:5:0,' ');
            Writeln;
            Write('E');
            FOR J:=1 TO 10 DO Write(Play.Inv[J].En:5:0,' ');
            Writeln;
            Write('S');
            FOR J:=1 TO 10 DO Write(Play.Inv[J].Sp:5:0,' ');
            Writeln;
          END;

PROCEDURE Distribute(VAR Play:PlayerType;VAR Ti,Tc,Ta,Tb,Te,Ts:Real);
          VAR
            D,K,T,Divs:Integer;
            S,Q:Real;
            Acc:Boolean;
          BEGIN
            Divs:=1;
            Writeln('Distribute forces into divisions.');
            REPEAT
             DispDist(Play);
             Write('Remaining: I:',Ti:1:0,' C: ',Tc:1:0,' A: ',Ta:1:0);
             Writeln(' B: ',Tb:1:0,' E: ',Te:1:0,' S: ',Ts:1:0);
             Writeln('To which division do you wish to add?');
             Readln(D);
             IF (D>Divs) AND (D<=10) THEN BEGIN
              Divs:=Divs+1;
              D:=Divs;
             END;
             Writeln('Add: [1] INFANTRY   [2] CAVALRY   [3] ARCHERY   ');
             Writeln('     [4] BALLISTICS [5] ENGINEERS [6] SPIES');
             Readln(T);
             Writeln('How many do you wish to add?');
             Readln(Q);
             CASE T OF
              1: IF Q<=Ti THEN BEGIN
                  Ti:=Ti-Q;
                  Play.Inv[D].Iy:=(Play.Inv[D].Iy)+Q;
                 END;
              2: IF Q<=Tc THEN BEGIN
                  Tc:=Tc-Q;
                  Play.Inv[D].Ca:=(Play.Inv[D].Ca)+Q;
                 END;
              3: IF Q<=Ta THEN BEGIN
                  Ta:=Ta-Q;
                  Play.Inv[D].Ar:=(Play.Inv[D].Ar)+Q;
                 END;
              4: IF Q<=Tb THEN BEGIN
                  Tb:=Tb-Q;
                  Play.Inv[D].Ba:=(Play.Inv[D].Ba)+Q;
                 END;
              5: IF Q<=Te THEN BEGIN
                  Te:=Te-Q;
                  Play.Inv[D].En:=(Play.Inv[D].En)+Q;
                 END;
              6: IF Q<=Ts THEN BEGIN
                  Ts:=Ts-Q;
                  Play.Inv[D].Sp:=(Play.Inv[D].Sp)+Q;
                 END;
             END;
            UNTIL ((Ti=0) AND (Tc=0) AND (Ta=0)
                   AND (Tb=0) AND (Te=0) AND (Ts=0));
            DispDist(Play);
            Play.Dvs:=Divs;
            Acc:=False;
            REPEAT
             Writeln('In which division will your commander be positioned?');
             Readln(D);
             IF (D>=1) AND (D<=Divs) THEN Play.Inv[D].Ge:=True;
             IF (D>=1) AND (D<=Divs) THEN Acc:=True;
            UNTIL Acc;
            Writeln('All forces have been distributed.');
            FOR K:=1 TO (Play.Dvs) DO BEGIN
             Play.Inv[K].Mo:=3;
             IF (2*(Play.Inv[K].Ca))>=(Play.Inv[K].Iy)
              THEN Play.Inv[K].Mo:=(Play.Inv[K].Mo)+1;
             IF (Play.Inv[K].Ca)>=(Play.Inv[K].Iy)
              THEN Play.Inv[K].Mo:=(Play.Inv[K].Mo)+1;
             IF (10*(Play.Inv[K].Ba))>(Play.Inv[K].Iy)
              THEN Play.Inv[K].Mo:=(Play.Inv[K].Mo)-1;
            END;
            FOR K:=1 TO (Play.Dvs) DO BEGIN
             S:=0;
             S:=S+Io*(Play.Inv[K].Iy);
             S:=S+Co*(Play.Inv[K].Ca);
             S:=S+Ao*(Play.Inv[K].Ar);
             S:=S+Bo*(Play.Inv[K].Ba);
             Play.Inv[K].Si:=S;
            END;
          END;

PROCEDURE Rolls(VAR J,K,L,M,N:Real);                {generates random numbers}
          BEGIN
            J:=((Random(100))/100)+Rb;
            K:=((Random(100))/100)+Rb;
            L:=((Random(100))/100)+Rb;
            M:=((Random(100))/100)+Rb;
            N:=((Random(100))/100)+Rb;
          END;

PROCEDURE SetTerr(VAR Cont:ControlArray;VAR InText:Text);
          VAR
            A,B,C,D:Integer;
          BEGIN
            Readln(InText);
            FOR C:=1 TO (Tr-1) DO BEGIN
             WHILE NOT EOLN(InText) DO BEGIN
              Read(InText,A,B);
              IF Cont[A,B].D=0 THEN Read(InText,Cont[A,B].T)
               ELSE Read(InText,D);
             END;
             Readln(InText);
            END;
          END;

PROCEDURE Terrain(VAR Cont:ControlArray);
          VAR
            InText:Text;
            L,M,N,O,Mode:Integer;
            Ch:Char;
          BEGIN
            REPEAT
             Writeln('What is your preferred terrain for this battle?');
             Writeln('[1] NONE   [2] PLAYERS CHOOSE   [3] RANDOM');
             Readln(Mode);
            UNTIL ((Mode>=1) AND (Mode<=3));
            IF ((Mode=2) OR (Mode=3)) THEN BEGIN
             Assign(InText,'WarTerr.Pas');
             Reset(InText);
            END;
            CASE Mode OF
             2: BEGIN
                 M:=0;
                 Writeln('Select terrain of your choice:');
                 Writeln('[0] NONE');
                 WHILE NOT EOF(InText) DO BEGIN
                  M:=M+1;
                  Write('[',M,'] ');
                  WHILE NOT EOLN(InText) DO BEGIN
                   Read(InText,Ch);
                   Write(Ch);
                  END;
                  FOR L:=1 TO Tr DO Readln(InText);
                  Writeln;
                 END;
                 REPEAT
                  Writeln('Enter choice of terrain.');
                  Readln(L);
                 UNTIL ((L>=0) AND (L<=M));
                 IF L>0 THEN BEGIN
                  Writeln('Preparing terrain scenario...');
                  Reset(InText);
                  FOR N:=1 TO (L-1) DO
                   FOR O:=1 TO Tr DO Readln(InText);
                  SetTerr(Cont,InText);
                 END;
                END;
             3: BEGIN
                 Writeln('Randomly selecting terrain scenario...');
                 L:=0;
                 M:=0;                                   {the algorithm is to}
                 O:=1;                                   {roll for each entry}
                 WHILE NOT EOF(InText) DO BEGIN          {and whichever rolls}
                  FOR N:=1 TO Tr DO Readln(InText);      {highest is selected}
                  L:=L+1;
                  N:=Random(100);
                  IF N>M THEN O:=L;
                  IF N>M THEN M:=N;
                 END;
                 Reset(InText);
                 FOR L:=1 TO (O-1) DO
                  FOR M:=1 TO Tr DO Readln(InText);
                 SetTerr(Cont,InText);
                END;
            END;
            IF ((Mode=2) OR (Mode=3)) THEN Close(InText);
          END;

PROCEDURE Start(VAR Cont:ControlArray;VAR Play:PlayerArray;
                VAR One,Two:Integer;PlCnt:Integer;VAR Ans:Char);
          VAR
            I,J,K:Integer;
            AnsR:Char;
            Ti,Tc,Ta,Tb,Te,Ts,A,B,C,D,E:Real;
            Given:Boolean;
          BEGIN
            ClrScr;
            REPEAT
             Writeln('Which army will take position 1? Type list #.');
             Readln(One);
             Writeln('Which army will take position 2? Type list #.');
             Readln(Two);
            UNTIL ((One>0) AND (Two>0) AND (One<=PlCnt) AND (Two<=PlCnt)
             AND (Play[One].Dvs<>0) AND (Play[Two].Dvs<>0) AND (One<>Two));
            Write('This will engage ');
            FOR I:=1 TO Play[One].Str DO Write(Play[One].Nam[I]);
            Write(' and ');
            FOR I:=1 TO Play[Two].Str DO Write(Play[Two].Nam[I]);
            Writeln('.');
            Writeln('Engage these two forces? Type Y or N.');
            Readln(Ans);
            IF ((Play[One].Dvs=0) OR (Play[Two].Dvs=0)) THEN Ans:='N';
            IF (Ans='Y') THEN BEGIN
             Writeln('Player 1, do you wish to redistribute? Type Y or N.');
             Readln(AnsR);
             IF AnsR='Y' THEN BEGIN
              Ti:=0;
              Tc:=0;
              Ta:=0;
              Tb:=0;
              Te:=0;
              Ts:=0;
              FOR J:=1 TO (Play[One].Dvs) DO BEGIN
               Ti:=Ti+(Play[One].Inv[J].Iy);
               Tc:=Tc+(Play[One].Inv[J].Ca);
               Ta:=Ta+(Play[One].Inv[J].Ar);
               Tb:=Tb+(Play[One].Inv[J].Ba);
               Te:=Te+(Play[One].Inv[J].En);
               Ts:=Ts+(Play[One].Inv[J].Sp);
               Play[One].Inv[J].Iy:=0;
               Play[One].Inv[J].Ca:=0;
               Play[One].Inv[J].Ar:=0;
               Play[One].Inv[J].Ba:=0;
               Play[One].Inv[J].Si:=0;
               Play[One].Inv[J].Mo:=0;
               Play[One].Inv[J].En:=0;
               Play[One].Inv[J].Sp:=0;
               Play[One].Inv[J].Ge:=False;
              END;
              Distribute(Play[One],Ti,Tc,Ta,Tb,Te,Ts);
             END;
             Writeln('Player 2, do you wish to redistribute? Type Y or N.');
             Readln(AnsR);
             IF AnsR='Y' THEN BEGIN
              Ti:=0;
              Tc:=0;
              Ta:=0;
              Tb:=0;
              Te:=0;
              Ts:=0;
              FOR J:=1 TO (Play[Two].Dvs) DO BEGIN
               Ti:=Ti+(Play[Two].Inv[J].Iy);
               Tc:=Tc+(Play[Two].Inv[J].Ca);
               Ta:=Ta+(Play[Two].Inv[J].Ar);
               Tb:=Tb+(Play[Two].Inv[J].Ba);
               Te:=Te+(Play[Two].Inv[J].En);
               Ts:=Ts+(Play[Two].Inv[J].Sp);
               Play[Two].Inv[J].Iy:=0;
               Play[Two].Inv[J].Ca:=0;
               Play[Two].Inv[J].Ar:=0;
               Play[Two].Inv[J].Ba:=0;
               Play[Two].Inv[J].Si:=0;
               Play[Two].Inv[J].Mo:=0;
               Play[Two].Inv[J].En:=0;
               Play[Two].Inv[J].Sp:=0;
               Play[Two].Inv[J].Ge:=False;
              END;
              Distribute(Play[Two],Ti,Tc,Ta,Tb,Te,Ts);
             END;
             FOR I:=1 TO (Play[One].Dvs) DO BEGIN
              Cont[I,1].D:=I;
              Cont[I,1].S:=Play[One].Inv[I].Si;
              Cont[I,1].M:=Play[One].Inv[I].Mo;
              Cont[I,1].I:=Play[One].Inv[I].Iy;
              Cont[I,1].C:=Play[One].Inv[I].Ca;
              Cont[I,1].A:=Play[One].Inv[I].Ar;
              Cont[I,1].B:=Play[One].Inv[I].Ba;
              Cont[I,1].E:=Play[One].Inv[I].En;
              Cont[I,1].P:=Play[One].Inv[I].Sp;
              Cont[I,1].Gen:=Play[One].Inv[I].Ge;
             END;
             FOR I:=1 TO (Play[Two].Dvs) DO BEGIN
              Cont[11-I,Ys].D:=I+10;
              Cont[11-I,Ys].S:=Play[Two].Inv[I].Si;
              Cont[11-I,Ys].M:=Play[Two].Inv[I].Mo;
              Cont[11-I,Ys].I:=Play[Two].Inv[I].Iy;
              Cont[11-I,Ys].C:=Play[Two].Inv[I].Ca;
              Cont[11-I,Ys].A:=Play[Two].Inv[I].Ar;
              Cont[11-I,Ys].B:=Play[Two].Inv[I].Ba;
              Cont[11-I,Ys].E:=Play[Two].Inv[I].En;
              Cont[11-I,Ys].P:=Play[Two].Inv[I].Sp;
              Cont[11-I,Ys].Gen:=Play[Two].Inv[I].Ge;
             END;
             Terrain(Cont);
             Writeln('Battlefield prepared for combat.');
             Readln;
            END;
          END;

PROCEDURE Spoils(VAR Play:PlayerArray;VOne,Dead:Boolean;One,Two:Integer);
          VAR
            I,J,A,Vic,Los,Ans,Per:Integer;
            Ti,Tc,Ta,Tb,Te,Ts,Enem,Qty:Real;
            Done:Boolean;
          BEGIN
            ClrScr;
            IF VOne THEN Vic:=One
             ELSE Vic:=Two;
            IF VOne THEN Los:=Two
             ELSE Los:=One;
            Writeln('Congratulations on your epic conquest.');
            IF Dead THEN BEGIN
             IF (Play[Vic].Off>0) THEN Play[Vic].Off:=(Play[Vic].Off)-1
              ELSE IF (Play[Vic].Mon<=Oc) THEN Play[Vic].Mon:=0
               ELSE Play[Vic].Mon:=(Play[Vic].Mon)-Oc;
             Play[Vic].Nam:=Blanks;
             Writeln('Your supreme commander was killed.');
             Write('Name a new commander. ');
             Writeln('You may use up to twenty characters.');
             A:=0;
             WHILE (NOT EOLN) AND (A<20) DO BEGIN
              A:=A+1;
              Read(Play[Vic].Nam[A]);
             END;
            END;
            Enem:=0;
            FOR I:=1 TO (Play[Los].Dvs) DO Enem:=Enem+(Play[Los].Inv[I].Si);
            Play[Vic].Mon:=(Play[Vic].Mon)+(Vo*0.5*Enem)+(Play[Los].Mon);
            Ti:=0;
            Tc:=0;
            Ta:=0;
            Tb:=0;
            Te:=0;
            Ts:=0;
            FOR J:=1 TO (Play[Vic].Dvs) DO BEGIN
             Ti:=Ti+(Play[Vic].Inv[J].Iy);
             Tc:=Tc+(Play[Vic].Inv[J].Ca);
             Ta:=Ta+(Play[Vic].Inv[J].Ar);
             Tb:=Tb+(Play[Vic].Inv[J].Ba);
             Te:=Te+(Play[Vic].Inv[J].En);
             Ts:=Ts+(Play[Vic].Inv[J].Sp);
             Play[Vic].Inv[J].Iy:=0;
             Play[Vic].Inv[J].Ca:=0;
             Play[Vic].Inv[J].Ar:=0;
             Play[Vic].Inv[J].Ba:=0;
             Play[Vic].Inv[J].Si:=0;
             Play[Vic].Inv[J].Mo:=0;
             Play[Vic].Inv[J].En:=0;
             Play[Vic].Inv[J].Sp:=0;
             Play[Vic].Inv[J].Ge:=False;
            END;
            Ti:=Round(Ti*Vo*0.8);
            Play[Los].Nam:=Blanks;
            Play[Los].Dvs:=0;
            Play[Los].Mon:=0;
            Play[Los].Str:=0;
            Play[Los].Off:=0;
            FOR J:=1 TO 10 DO BEGIN
             Play[Los].Inv[J].Iy:=0;
             Play[Los].Inv[J].Ca:=0;
             Play[Los].Inv[J].Ar:=0;
             Play[Los].Inv[J].Ba:=0;
             Play[Los].Inv[J].Mo:=0;
             Play[Los].Inv[J].Si:=0;
             Play[Los].Inv[J].En:=0;
             Play[Los].Inv[J].Sp:=0;
             Play[Los].Inv[J].Ge:=False;
            END;
            Done:=False;
            IF VicOne THEN Write('Player 1 (Army ',One)
             ELSE Write('Player 2 (Army ',Two);
            Writeln('), you may now spend some money!');
            REPEAT
             Writeln;
             Writeln('Remaining gold:',Play[Vic].Mon:1:0);
             Writeln('Remaining in army:');
             Writeln('I: ',Ti:1:0,'   C: ',Tc:1:0,'   A: ',Ta:1:0);
             Writeln('B: ',Tb:1:0,'   E: ',Te:1:0,'   S: ',Ts:1:0);
             Writeln('Increase spending in which category?');
             Writeln('[1] INFANTRY     [2] CAVALRY       [3] ARCHERY');
             Writeln('[4] BALLISTICS   [5] ENGINEERING   [6] INTELLIGENCE');
             Writeln('[7] LEADERSHIP   [8] NONE (STOP)');
             Readln(Ans);
             CASE Ans OF
              1: Per:=Ic;
              2: Per:=Cc;
              3: Per:=Ac;
              4: Per:=Bc;
              5: Per:=Ec;
              6: Per:=Sc;
              7: Per:=Oc;
              8: Done:=True;
             END;
             IF (Ans>=1) AND (Ans<=7) THEN BEGIN
              Writeln('The cost is ',Per,' gold per unit. Order how many?');
              Readln(Qty);
              IF (Qty*Per)>(Play[Vic].Mon)
               THEN Writeln('Your funds are insufficient for this order.')
               ELSE BEGIN
                Play[Vic].Mon:=(Play[Vic].Mon)-(Qty*Per);
                CASE Ans OF
                 1: Ti:=Ti+Qty;
                 2: Tc:=Tc+Qty;
                 3: Ta:=Ta+Qty;
                 4: Tb:=Tb+Qty;
                 5: Te:=Te+Qty;
                 6: Ts:=Ts+Qty;
                 7: Play[Vic].Off:=(Play[Vic].Off)+Qty;
                END;
               END;
             END;
            UNTIL Done;
            Distribute(Play[Vic],Ti,Tc,Ta,Tb,Te,Ts);
          END;

PROCEDURE CalcMAndS(VAR Cont:ControlType);     {updates move and size in cont}
          BEGIN
            Cont.S:=Io*(Cont.I);
            Cont.S:=(Cont.S)+(Co*(Cont.C));
            Cont.S:=(Cont.S)+(Ao*(Cont.A));
            Cont.S:=(Cont.S)+(Bo*(Cont.B));
            Cont.M:=3;
            IF (2*(Cont.C))>=(Cont.I) THEN Cont.M:=(Cont.M)+1;
            IF (Cont.C)>=(Cont.I) THEN Cont.M:=(Cont.M)+1;
            IF (10*(Cont.B))>(Cont.I) THEN Cont.M:=(Cont.M)-1;
          END;

PROCEDURE Damage(VAR Def:ControlType;VAR Att:ControlType;Terr:Real);
          VAR
            J,K,L,M,N:Real;
            V:Real;
          BEGIN                            {non-strike damage calculated here}
            Rolls(J,K,L,M,N);
            IF (Att.I)>0 THEN
             V:=Round((0.20*Io*J*Def.I)/(N*Io)+
                      (0.10*Co*K*Def.C)/(N*Io)+
                 Terr*(0.10*Ao*L*Def.A)/(N*Io)+
                      (0.10*Bo*M*Def.B)/(N*Io));
            IF ((Att.I)-V)>0 THEN Att.I:=(Att.I)-V
             ELSE Att.I:=0;
            Rolls(J,K,L,M,N);
            IF (Def.I)>0 THEN
             V:=Round((0.20*Io*J*Att.I)/(N*Io)+
                      (0.10*Co*K*Att.C)/(N*Io)+
                 Terr*(0.10*Ao*L*Att.A)/(N*Io)+
                      (0.10*Bo*M*Att.B)/(N*Io));
            IF ((Def.I)-V)>0 THEN Def.I:=(Def.I)-V
             ELSE Def.I:=0;
            Rolls(J,K,L,M,N);
            IF (Att.C)>0 THEN
             V:=Round((0.10*Io*J*Def.I)/(N*Co)+
                      (0.20*Co*K*Def.C)/(N*Co)+
                 Terr*(0.20*Ao*L*Def.A)/(N*Co));
            IF ((Att.C)-V)>0 THEN Att.C:=(Att.C)-V
             ELSE Att.C:=0;
            Rolls(J,K,L,M,N);
            IF (Def.C)>0 THEN
             V:=Round((0.10*Io*J*Att.I)/(N*Co)+
                      (0.20*Co*K*Att.C)/(N*Co)+
                 Terr*(0.20*Ao*L*Att.A)/(N*Co));
            IF ((Def.C)-V)>0 THEN Def.C:=(Def.C)-V
             ELSE Def.C:=0;
            Rolls(J,K,L,M,N);
            IF (Att.A)>0 THEN
             V:=Round((0.15*Io*J*Def.I)/(N*Ao*Terr)+
                 Terr*(0.15*Ao*K*Def.A)/(N*Ao*Terr)+
                      (0.20*Bo*L*Def.B)/(N*Ao*Terr));
            IF ((Att.A)-V)>0 THEN Att.A:=(Att.A)-V
             ELSE Att.A:=0;
            Rolls(J,K,L,M,N);
            IF (Def.A)>0 THEN
             V:=Round((0.15*Io*J*Att.I)/(N*Ao*Terr)+
                 Terr*(0.15*Ao*K*Att.A)/(N*Ao*Terr)+
                      (0.20*Bo*L*Att.B)/(N*Ao*Terr));
            IF ((Def.A)-V)>0 THEN Def.A:=(Def.A)-V
             ELSE Def.A:=0;
            Rolls(J,K,L,M,N);
            IF (Att.B)>0 THEN
             V:=Round((0.30*Io*J*Def.I)/(N*Bo)+
                      (0.20*Bo*K*Def.B)/(N*Bo));
            IF ((Att.B)-V)>0 THEN Att.B:=(Att.B)-V
             ELSE Att.B:=0;
            Rolls(J,K,L,M,N);
            IF (Def.B)>0 THEN
             V:=Round((0.30*Io*J*Att.I)/(N*Bo)+
                      (0.20*Bo*K*Att.B)/(N*Bo));
            IF ((Def.B)-V)>0 THEN Def.B:=(Def.B)-V
             ELSE Def.B:=0;
            Rolls(J,K,L,M,N);                  {damage on engineers and spies}
            IF (Att.E)>0 THEN
             V:=Round((0.10*Co*J*Def.C)/N+
                 Terr*(0.10*Ao*K*Def.A)/N);
            IF ((Att.E)-V)>0 THEN Att.E:=(Att.E)-V
             ELSE Att.E:=0;
            Rolls(J,K,L,M,N);
            IF (Def.E)>0 THEN
             V:=Round((0.10*Co*J*Att.C)/N+
                 Terr*(0.10*Ao*K*Att.A)/N);
            IF ((Def.E)-V)>0 THEN Def.E:=(Def.E)-V
             ELSE Def.E:=0;
            Rolls(J,K,L,M,N);
            IF (Att.P)>0 THEN
             V:=Round((0.10*Co*J*Def.C)/N+
                 Terr*(0.10*Ao*K*Def.A)/N+
                      (0.10*So*L*Def.P)/(N*So));
            IF ((Att.P)-V)>0 THEN Att.P:=(Att.P)-V
             ELSE Att.P:=0;
            Rolls(J,K,L,M,N);
            IF (Def.P)>0 THEN
             V:=Round((0.10*Co*J*Att.C)/N+
                 Terr*(0.10*Ao*K*Att.A)/N+
                      (0.10*So*L*Att.P)/(N*So));
            IF ((Def.P)-V)>0 THEN Def.P:=(Def.P)-V
             ELSE Def.P:=0;
          END;

PROCEDURE DetDivs(VAR P:PlayerArray);
          VAR
            A,B,K:Integer;
            S:Real;
          BEGIN
            Writeln('#MDO');
            Read(A);
            Readln(P[A].Mon,P[A].Dvs,P[A].Off);
            FOR B:=1 TO (P[A].Dvs) DO BEGIN
             Writeln(B,' ICABEP');
             Read(P[A].Inv[B].Iy,P[A].Inv[B].Ca,P[A].Inv[B].Ar);
             Readln(P[A].Inv[B].Ba,P[A].Inv[B].En,P[A].Inv[B].Sp);
            END;
            FOR K:=1 TO (P[A].Dvs) DO BEGIN
             P[A].Inv[K].Mo:=3;
             IF (2*(P[A].Inv[K].Ca))>=(P[A].Inv[K].Iy)
              THEN P[A].Inv[K].Mo:=(P[A].Inv[K].Mo)+1;
             IF (P[A].Inv[K].Ca)>=(P[A].Inv[K].Iy)
              THEN P[A].Inv[K].Mo:=(P[A].Inv[K].Mo)+1;
             IF (10*(P[A].Inv[K].Ba))>(P[A].Inv[K].Iy)
              THEN P[A].Inv[K].Mo:=(P[A].Inv[K].Mo)-1;
            END;
            FOR K:=1 TO (P[A].Dvs) DO BEGIN
             S:=0;
             S:=S+Io*(P[A].Inv[K].Iy);
             S:=S+Co*(P[A].Inv[K].Ca);
             S:=S+Ao*(P[A].Inv[K].Ar);
             S:=S+Bo*(P[A].Inv[K].Ba);
             P[A].Inv[K].Si:=S;
            END;
            Writeln('Redefinition complete.');
          END;

PROCEDURE SubChaos(VAR C:ControlArray;High:Boolean);
          VAR
            A,B:Integer;
          BEGIN
            Writeln('Chaos ensues!');
            FOR A:=1 TO 10 DO
               FOR B:=1 TO Ys DO
                IF ((High) AND ((C[A,B].D)>=11))
                 OR ((NOT High) AND ((C[A,B].D)<=10)) THEN BEGIN
                 C[A,B].I:=Round((C[A,B].I)*Cd);
                 C[A,B].C:=Round((C[A,B].C)*Cd);
                 C[A,B].A:=Round((C[A,B].A)*Cd);
                 C[A,B].B:=Round((C[A,B].B)*Cd);
                 C[A,B].E:=Round((C[A,B].E)*Cd);
                 C[A,B].P:=Round((C[A,B].P)*Cd);
                 CalcMAndS(C[A,B]);
                 IF ((Cd=0) OR ((C[A,B].S)=0)) THEN C[A,B].D:=0;
                END;
          END;

PROCEDURE Chaos(VAR C:ControlArray;Offs:Real;X,Y:Integer;Dead:Boolean);
          VAR
            A,B,Count:Integer;
            High:Boolean;
          BEGIN
            High:=False;
            IF ((C[X,Y].D)>=11) THEN High:=True;
            IF Dead THEN BEGIN                           {if commander killed}
             FOR A:=1 TO 10 DO
              FOR B:=1 TO Ys DO
               IF ((High) AND ((C[A,B].D)>=11))
                OR ((NOT High) AND ((C[A,B].D)<=10)) THEN Count:=Count+1;
             IF (Offs<Count) THEN SubChaos(C,High);
            END
             ELSE SubChaos(C,High);                        {if officer killed}
          END;

PROCEDURE Combat(VAR Cont:ControlArray;X,Y,ToX,ToY:Integer;
                 VAR AttO,DefO:Real);
          VAR
            A,B,C,D,E,J,K,Q,R,S,T,U,V,Terr:Real;
            Strike,Dd:Boolean;
          BEGIN
            IF (Cont[ToX,ToY].T=1) THEN Terr:=Fo
             ELSE Terr:=1;
            Strike:=False;
            J:=Cont[X,Y].S;
            K:=Cont[ToX,ToY].S;
            Rolls(A,B,C,D,E);                       {determines secret strike}
            IF (10*(Cont[X,Y].S))<=(Cont[ToX,ToY].S)
             THEN IF (A+(Cont[X,Y].M)/10)>(Ss) THEN BEGIN
              Strike:=True;
              Writeln('SECRET STRIKE!');             {secret strike damage is}
              Rolls(A,B,C,D,E);                   {calculated in this section}
              IF (Cont[ToX,ToY].I)>0 THEN
              Q:=Round((0.20*Io*A*Cont[X,Y].I)/(E*Io)+
                       (0.10*Co*B*Cont[X,Y].C)/(E*Io)+
                  Terr*(0.10*Ao*C*Cont[X,Y].A)/(E*Io)+
                       (0.10*Bo*D*Cont[X,Y].B)/(E*Io));
              Rolls(A,B,C,D,E);
              IF (Cont[ToX,ToY].C)>0 THEN
              R:=Round((0.10*Io*A*Cont[X,Y].I)/(E*Co)+
                       (0.20*Co*B*Cont[X,Y].C)/(E*Co)+
                  Terr*(0.20*Ao*C*Cont[X,Y].A)/(E*Co));
              Rolls(A,B,C,D,E);
              IF (Cont[ToX,ToY].A)>0 THEN
              S:=Round((0.15*Io*A*Cont[X,Y].I)/(E*Ao*Terr)+
                  Terr*(0.15*Ao*C*Cont[X,Y].A)/(E*Ao*Terr)+
                       (0.20*Co*D*Cont[X,Y].B)/(E*Ao*Terr));
              Rolls(A,B,C,D,E);
              IF (Cont[ToX,ToY].B)>0 THEN
              T:=Round((0.30*Io*A*Cont[X,Y].I)/(E*Bo)+
                       (0.20*Bo*D*Cont[X,Y].B)/(E*Bo));
              Rolls(A,B,C,D,E);
              IF (Cont[ToX,ToY].E)>0 THEN      {strike on engineers and spies}
              U:=Round((0.10*Co*A*Cont[X,Y].C)/E+
                  Terr*(0.10*Ao*B*Cont[X,Y].A)/E);
              Rolls(A,B,C,D,E);
              IF (Cont[ToX,ToY].P)>0 THEN
              V:=Round((0.10*Co*A*Cont[X,Y].C)/E+
                  Terr*(0.10*Ao*B*Cont[X,Y].A)/E+
                       (0.10*So*C*Cont[X,Y].P)/(E*So));
              IF (Cont[ToX,ToY].I)<=Q THEN Cont[ToX,ToY].I:=0   {damage taken}
               ELSE Cont[ToX,ToY].I:=(Cont[ToX,ToY].I)-Q;
              IF (Cont[ToX,ToY].C)<=R THEN Cont[ToX,ToY].C:=0
               ELSE Cont[ToX,ToY].C:=(Cont[ToX,ToY].C)-R;
              IF (Cont[ToX,ToY].A)<=S THEN Cont[ToX,ToY].A:=0
               ELSE Cont[ToX,ToY].A:=(Cont[ToX,ToY].A)-S;
              IF (Cont[ToX,ToY].B)<=T THEN Cont[ToX,ToY].B:=0
               ELSE Cont[ToX,ToY].B:=(Cont[ToX,ToY].B)-T;
              IF (Cont[ToX,ToY].E)<=U THEN Cont[ToX,ToY].E:=0
               ELSE Cont[ToX,ToY].E:=(Cont[ToX,ToY].E)-U;
              IF (Cont[ToX,ToY].P)<=V THEN Cont[ToX,ToY].P:=0
               ELSE Cont[ToX,ToY].P:=(Cont[ToX,ToY].P)-V;
             END;
            IF (NOT Strike)
             THEN IF (2*(Cont[X,Y].S))<=(Cont[ToX,ToY].S) THEN BEGIN
               Writeln('SURPRISE ATTACK!');
               Damage(Cont[X,Y],Cont[ToX,ToY],Terr);
             END
              ELSE Damage(Cont[ToX,ToY],Cont[X,Y],Terr);
            CalcMAndS(Cont[X,Y]);
            CalcMAndS(Cont[ToX,ToY]);
            Writeln('BATTLE REPORT...');
            Write('Attacker retains: ',Round((Cont[X,Y].S)*100/J));
            Writeln('% integrity.');
            Write('Defender retains: ',Round((Cont[ToX,ToY].S)*100/K));
            Writeln('% integrity.');
            Dd:=False;
            IF (Cont[X,Y].S)=0 THEN BEGIN
             Writeln('Attacker destroyed!');
             IF (Cont[X,Y].Gen) THEN BEGIN
              Cont[X,Y].Gen:=False;
              Dd:=True;
              Writeln('ATTACKING SUPREME COMMANDER KILLED!');
              Chaos(Cont,AttO,X,Y,Dd);
             END;
            END;
            IF (Cont[ToX,ToY].S)=0 THEN BEGIN
             Writeln('Defender destroyed!');
             IF (Cont[ToX,ToY].Gen) THEN BEGIN
              Cont[X,Y].Gen:=False;
              Dd:=True;
              Writeln('DEFENDING SUPREME COMMANDER KILLED!');
              Chaos(Cont,DefO,ToX,ToY,Dd);
             END;
            END;
            IF (Cont[X,Y].S)=0 THEN Cont[X,Y].D:=0;
            IF (Cont[ToX,ToY].S)=0 THEN Cont[ToX,ToY].D:=0;
            Readln;
          END;

PROCEDURE Merge(VAR From,Into:ControlType);
          BEGIN
            Into.I:=(Into.I)+(From.I);
            Into.C:=(Into.C)+(From.C);
            Into.A:=(Into.A)+(From.A);
            Into.B:=(Into.B)+(From.B);
            Into.E:=(Into.E)+(From.E);
            Into.P:=(Into.P)+(From.P);
            IF (From.Gen) THEN Into.Gen:=True;
            From.I:=0;
            From.C:=0;
            From.A:=0;
            From.B:=0;
            From.M:=0;
            From.D:=0;
            From.S:=0;
            From.E:=0;
            From.P:=0;
            From.Gen:=False;
            CalcMAndS(Into);
          END;

PROCEDURE Recon(VAR C:ControlArray;AX,AY,DX,DY:Integer;VAR Play:PlayerType);
          VAR
            D,E,F,G,H,Sp,CtrSp,Field,Prob,Old,Des:Real;
            I:Integer;
            Dd:Boolean;
          BEGIN
            Sp:=C[AX,AY].P;
            CtrSp:=C[DX,DY].P;
            IF (So*Sp)>=(C[DX,DY].S) THEN BEGIN
             Writeln('RECONNAISSANCE SUCCESSFUL!');
             DivDisp(C[DX,DY]);
             IF (Assassins) AND (2*Sp>=CtrSp) THEN BEGIN
              Rolls(D,E,F,G,H);
              IF (D+(So*Sp/(C[DX,DY].S)))>As THEN BEGIN
               Field:=Play.Off;
               Dd:=False;
               IF (C[DX,DY].Gen) THEN BEGIN
                Prob:=Rb+1-(1/(Field+1));
                IF (Prob=Rb) THEN Prob:=Rb+0.5;
                IF (E>=Prob) THEN BEGIN
                 Write('SUPREME COMMANDER ');
                 FOR I:=1 TO (Play.Str) DO Write(Play.Nam[I]);
                 Writeln(' ASSASSINATED!');
                 C[DX,DY].Gen:=False;
                 Dd:=True;
                 Chaos(C,Play.Off,DX,DY,Dd);
                END
                 ELSE IF (Field>0) THEN BEGIN
                  Writeln('Strike Leader assassinated!');
                  Play.Off:=(Play.Off)-1;
                  IF (Oo*Play.Off)<(Play.Dvs) THEN Chaos(C,Play.Off,DX,DY,Dd);
                 END
               END
                ELSE IF (Field>0) THEN BEGIN
                 Writeln('Strike Leader assassinated!');
                 Play.Off:=(Play.Off)-1;
                 IF (Oo*Play.Off)<(Play.Dvs) THEN Chaos(C,Play.Off,DX,DY,Dd);
                END;
              END;
             END;
             Old:=C[DX,DY].B;
             IF (Saboteurs) AND (Sp>=Old) AND (Old>0) THEN BEGIN
              Des:=Round(Sp/4);
              C[DX,DY].B:=Old-Des;
              IF (Old>(C[DX,DY].B))
               THEN Writeln(Des:1:0,' ballistic machines sabotaged!');
             END;
            END
             ELSE Writeln('Reconnaissance ineffective.');
            Readln;
          END;

PROCEDURE Turn(VAR Cont:ControlArray;VAR Play:PlayerArray;
               VAR Dead,VicOne,VicTwo:Boolean;Att,Def,P:Integer);
          VAR
            I,J,CrX,CrY,Choice,A,B,ToX,ToY,C,D,E:Integer;
            Valid,Found,Fight,Ends:Boolean;
          BEGIN
            FOR I:=(1+P) TO ((Play[Att].Dvs)+P) DO BEGIN
             CrX:=0;
             FOR A:=1 TO 10 DO
              FOR B:=1 TO YS DO BEGIN
               IF Cont[A,B].D=I THEN CrX:=A;
               IF Cont[A,B].D=I THEN CrY:=B;
              END;
             IF CrX<>0 THEN BEGIN
              REPEAT
               Format;
               Writeln('Division ready for movement at ',CrX,',',CrY,'.');
               Writeln('[1] MOVE   [2] CHECK A DIVISION   [3] SKIP');
               Readln(Choice);
               IF Choice=2 THEN BEGIN
                ClrScr;
                Writeln('What division X,Y do you wish to check?');
                Readln(D);
                Readln(E);
                IF (D>10) OR (D<1) OR (E>YS) OR (E<1)
                 THEN Writeln('Invalid coordinate.')
                 ELSE BEGIN
                  FOR J:=1 TO (Play[Att].Str) DO Write(Play[Att].Nam[J]);
                  Writeln;
                  IF ((Att=One) AND (Cont[D,E].D<=10) AND (Cont[D,E].D>0))
                   OR ((Att=Two) AND (Cont[D,E].D>10))
                   THEN DivDisp(Cont[D,E])
                   ELSE Writeln('You may check only your own divisions.');
                  Display(Cont);
                 END;
               END;
              UNTIL (Choice=1) OR (Choice=3);
              IF Choice=1 THEN BEGIN
               Ends:=False;
               FOR J:=1 TO (Cont[CrX,CrY].M) DO BEGIN
                IF (Cont[CrX,CrY].D)=0 THEN Ends:=True;
                IF (NOT Ends) THEN BEGIN
                 Valid:=False;
                 REPEAT
                  Format;
                  Write('You have ',1-J+Cont[CrX,CrY].M,' moves left.');
                  Writeln(' To what new X,Y do you wish to move?');
                  Readln(ToX);
                  Readln(ToY);
                  IF (ToY<=Ys) AND (ToY>=1) AND (ToX<=10) AND (ToX>=1)
                   AND (Abs(ToY-CrY)<=1) AND (Abs(ToX-CrX)<=1)
                   THEN Valid:=True;
                  IF (NOT Valid) THEN BEGIN
                   Format;
                   Writeln('Invalid movement.');
                   Readln;
                  END;
                 UNTIL Valid;
                 IF Cont[ToX,ToY].T>1 THEN BEGIN
                  IF ((Cont[CrX,CrY].E>0) AND Engineers) THEN BEGIN
                   Format;
                   Writeln('Engineers labor to clear path.');
                   Readln;
                   Ends:=True;
                   IF ((Cont[CrX,CrY].E)>((Cont[ToX,ToY].T)-1))
                    THEN Cont[ToX,ToY].T:=0
                    ELSE Cont[ToX,ToY].T:=
                     (Cont[ToX,ToY].T)-(Round(Cont[CrX,CrY].E));
                   Display(Cont);
                  END
                   ELSE BEGIN
                    Format;
                    Writeln('Mountains block your progress.');
                    Readln;
                   END;
                 END
                  ELSE IF Cont[ToX,ToY].T<0 THEN BEGIN
                   IF ((Cont[CrX,CrY].E>0) AND Engineers) THEN BEGIN
                    Format;
                    Writeln('Engineers labor to clear path.');
                    Readln;
                    Ends:=True;
                    IF ((Cont[CrX,CrY].E)>(-1*(Cont[ToX,ToY].T)))
                     THEN Cont[ToX,ToY].T:=0
                     ELSE Cont[ToX,ToY].T:=
                      (Cont[ToX,ToY].T)+(Round(Cont[CrX,CrY].E));
                    Display(Cont);
                   END
                    ELSE BEGIN
                     Format;
                     Writeln('Water blocks your progress.');
                     Readln;
                    END;
                  END
                   ELSE BEGIN
                    Fight:=False;
                    IF Cont[ToX,ToY].D=0 THEN BEGIN
                     Shift(Cont[CrX,CrY],Cont[ToX,ToY]);
                     CrX:=ToX;
                     CrY:=ToY;
                    END;
                    IF (Cont[ToX,ToY].D)<>(Cont[CrX,CrY].D) THEN BEGIN
                     IF (((Cont[ToX,ToY].D)<=10) AND ((Cont[CrX,CRY].D)<=10))
                      OR (((Cont[ToX,ToY].D)>10) AND ((Cont[CrX,CrY].D)>10))
                      THEN BEGIN
                       Merge(Cont[CrX,CrY],Cont[ToX,ToY]);
                       Fight:=True;
                      END;
                     IF (((Cont[ToX,ToY].D)<=10) AND ((Cont[CrX,CRY].D)>10))
                      OR (((Cont[ToX,ToY].D)>10) AND ((Cont[CrX,CrY].D)<=10))
                      THEN IF (NOT Fight) THEN BEGIN
                       ClrScr;
                       Writeln('ENCOUNTER!');
                       IF (Cont[CrX,CrY].P)>0 THEN BEGIN
                        REPEAT
                         Writeln('[1] ATTACK   [2] ATTEMPT RECONNAISSANCE');
                         Readln(C);
                        UNTIL (C=1) OR (C=2);
                        IF C=2 THEN BEGIN
                         Fight:=True;
                         Recon(Cont,CrX,CrY,ToX,ToY,Play[Def]);
                        END;
                       END;
                       IF (NOT Fight)
                        THEN Combat(Cont,CrX,CrY,ToX,ToY,
                             Play[Att].Off,Play[Att].Off);
                      END;
                    END;
                    Display(Cont);
                   END;
                END;                            {if attacker dies within turn}
               END;                                                 {for move}
              END;                                                 {if choice}
             END;                                          {if division alive}
             VicOne:=True;                   {this section tests for a victor}
             VicTwo:=True;
             A:=1;
             B:=1;
             WHILE (VicOne OR VicTwo) AND (A<=10) DO BEGIN
              WHILE (VicOne OR VicTwo) AND (B<=YS) DO BEGIN
               IF Cont[A,B].D>10 THEN VicOne:=False
                ELSE IF Cont[A,B].D>0 THEN VicTwo:=False;
               B:=B+1;
              END;
              B:=1;
              A:=A+1;
             END;                                                    {while a}
             IF (VicOne OR VicTwo) THEN BEGIN
              Dead:=True;
              FOR A:=1 TO 10 DO
               FOR B:=1 TO 10 DO
                IF (Cont[A,B].Gen) THEN Dead:=False;
             END;
            END;                                           {for all divisions}
          END;                                                     {procedure}

PROCEDURE Analyze(VAR Play:PlayerArray);
          VAR
            A,B,C,D:Char;
          BEGIN
            Readln(A,B,C,D);
            IF (B='D') AND (C='I') AND (A='E') AND (D='T') THEN DetDivs(Play)
             ELSE Writeln('Access denied.');
            Readln;
          END;

BEGIN                                                               {WarFinal}
     ClrScr;
     Randomize;
     Writeln('Preparing for simulation...');
     PlCnt:=0;
     Initialize(Play,Exit);
     InputArrays(Play,PlCnt);
     Write('Welcome to Josh''s final project,');
     Writeln(' a medieval war simulation called...');
     Writeln('DANCE CONTEST');
     Writeln;
     REPEAT
      Menu;
      Readln(Selector);
      VicOne:=False;
      VicTwo:=False;
      CASE Selector OF
       1: Help;
       2: ArmyList(Play,PlCnt);
       3: BEGIN
           IF PlCnt<20 THEN Create(Play,PlCnt)
            ELSE Writeln('Only twenty armies may exist simultaneously.');
          END;
       4: Rename(Play,PlCnt);
       5: IF PlCnt>=2 THEN BEGIN
           ClearControl(Cont);
           Start(Cont,Play,One,Two,PlCnt,Ans);
           IF Ans='Y' THEN BEGIN
            ClrScr;
            Display(Cont);
            REPEAT
             Turn(Cont,Play,Dead,VicOne,VicTwo,One,Two,0);
             IF NOT VicOne THEN Turn(Cont,Play,Dead,VicOne,VicTwo,Two,One,10);
            UNTIL (VicOne) OR (VicTwo);
            Spoils(Play,VicOne,Dead,One,Two);
           END;
          END;
       6: BEGIN
           Writeln('Are you sure you want to save? Type Y or N.');
           Readln(Answer);
           IF Answer='Y' THEN WriteFile(Play,PlCnt);
          END;
       7: BEGIN
           Writeln('Are you sure you want to quit? Type Y or N.');
           Readln(Answer);
           IF Answer='Y' THEN Exit:=True;
          END;
       666: Analyze(Play);                   {used by programmer in debugging}
      END;                                                              {case}
      ClrScr;
     UNTIL Exit;
END.