program Chester;

uses crt, graph;

const
  Txt = $B800;

type
  LevType = 0..999;

var
  Axe : boolean;
  BuildBlock : boolean;
  C : char;
  DoubleMove : boolean;
  EnemTexture : char;
  Enemy, Enemy2, Enemy3 : boolean;
  EnemyDirect : integer;
  EX, EY : integer;
  E2X, E2Y : integer;
  E3X, E3Y : integer;
  KeyDirect : integer;
  KoolKey : boolean;
  KX : integer;
  KY : integer;
  Key : boolean;
  Level : LevType;
  Lives : shortint;
  Logic : boolean;
  Moves : integer;
  SFX : boolean;
  SoftColor : boolean;
  WallTexture : char;
  WildWall : boolean;
  X, Y : integer;

{*******************}
procedure HelpScreen;
begin
  clrscr;
  TextColor (5);
  writeln('Chester Help Screen');
  writeln;
  writeln('Left arrow - left');
  writeln('Right arrow - right');
  writeln('Up arrow - up');
  writeln('Down arrow - down');
  writeln('Any key - attract enemies');
  writeln;
  writeln('Make sure your numslock is off when playing Chester.');
  readln;
end;

{**************************************}
procedure EndCredits (Lives : shortint);

begin
  TextColor (2);
  TextBackGround (0);
  If (Lives = 0) then   begin     clrscr;
    writeln;
    writeln(' Thank you for playing the shareware version of Chester!');
  end;
  TextColor (4);
  writeln;
  writeln(' If you would like to purchase the registered version including');
  writeln(' 100 challenging puzzles, mazes, and death traps please');
  write(' e-mail Mike Hetman via ');
  TextColor (7);
  write('dh0412@atlas.ccm.edu');
  TextColor (4);
  writeln(', contact');
  TextColor (7);
  write(' http://www.ccm.edu/~dh0412');
  TextColor (4);
  writeln(' or dial via modem:');
  TextColor (7);
  writeln;
  writeln(' L.I.N.K.S. (Chester Support BBS) -- 201-983-8640');
  writeln;
  Delay(2000);
end;

{****************************************************************}
procedure IntroCredits (var Level : LevType; var Lives : shortint;
                        var SFX, SoftColor : boolean);

var
  KeytoCont : string;

begin
  Lives := 9;
  TextColor(8);
  TextBackground(0);
  clrscr;
  writeln(' мм мллмм');
  writeln(' мллп мллллллллп T h e A d v e n t u r e s o f');
  writeln(' лллн мллл л пп мм мм');
  writeln(' оллл олллн л лл лл');
  writeln(' лллл олллн л лллллм мллллм мллллл лллллл мллллм олнмлл');
  writeln(' лллл олллн л лл олн олн олнолл лл олн олноллп');
  writeln(' лллл оллп л лл лл ллллллп плллллм лл ллллллп олн');
  writeln(' олллллп л лл лл олн ллн лл олн олн');
  writeln(' ллллмм л ммл лл лл пллллл ллллллп лл пллллл олн');
  writeln(' пллллллллллллллп');
  writeln(' ппплллллппп v0.2b');
  TextColor(6);
  writeln(' 7/17/96');
  writeln;
  writeln;
  TextColor(4);
  writeln(' Code and original levels written by Mike Hetman');
  writeln(' Additional code by Jim Villanueva');
  EndCredits (Lives);
  TextColor(3);
  write('Hit enter to begin or type "h" for help: ');
  readln(KeytoCont);
  Level := 1;
  SFX := TRUE;
  SoftColor := FALSE;
  If KeytoCont = '%chester' then
    begin
      TextColor(2);
      write('please select level: ');
      readln (Level);
    end;
  If KeytoCont = '%whitecat' then
    begin
      TextColor(2);
      write('please select level: ');
      readln (Level);
      SFX := FALSE;
      SoftColor := TRUE;
  end;
  If KeytoCont = 'H' then HelpScreen;
  If KeytoCont = 'h' then HelpScreen;
  If KeytoCont = 'S' then SFX := FALSE;
  If KeytoCont = 's' then SFX := FALSE;
end;
{***********************************************************************}
procedure MakeLevel (var Axe : boolean; var BuildBlock : boolean;
                     var EnemTexture : char;
                     var Enemy, Enemy2, Enemy3 : boolean;
                     var EX, EY, E2X, E2Y, E3X, E3Y, KX, KY : integer;
                     var KoolKey : boolean;
var Level : LevType;
              var Key : boolean;
var Logic : boolean;
              var Moves : integer;
SoftColor : boolean;
              var WallTexture : char;
var WildWall : boolean;
              var X, Y : integer);

var
  Count : integer;
  ParWallText : char;
  ParEnemText : char;
  ParEnemy : char;
  ParEnX, ParEnY, ParEn2X, ParEn2Y, ParEn3X, ParEn3Y : integer;
  ParMoves : integer;
  ParColor1 : integer;
  ParColor2 : integer;
  ParKeyX : integer;
  ParKeyY : integer;
  Name : string;
  LevData : text;
  Line : char;
  Tempstr: string;

begin
  Axe := FALSE;
  Enemy := FALSE;
  Key := FALSE;
  BuildBlock := FALSE;
  Level := Level + 1;
  X := 4;
  Y := 3;
  TextBackground(Black);
  clrscr;
  str(Level, Tempstr);
  case length(Tempstr) of
    1: Tempstr := '00' + Tempstr;
    2: Tempstr := '0' + Tempstr   end;
  assign(LevData,'LEVEL.' + Tempstr);
  Reset (LevData);
  read (LevData,ParWallText);
  read (LevData,ParEnemText);
  read (LevData,ParEnemy);
  read (LevData,ParEnX);
  read (LevData,ParEnY);
  read (LevData,ParEn2X);
  read (LevData,ParEn2Y);
  read (LevData,ParEn3X);
  read (LevData,ParEn3Y);
  read (LevData,ParMoves);
  read (LevData,ParColor1);
  read (LevData,ParColor2);
  read (LevData,ParKeyX);
  read (LevData,ParKeyY);
  readln (LevData,Name);
  WallTexture := ParWallText;
  EnemTexture := ParEnemText;
  case ParEnemy of
    'L' : begin
        Enemy := FALSE;
        KoolKey := FALSE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := FALSE;
        DoubleMove := FALSE;
      end;
    'N' : begin
        Enemy := FALSE;
        KoolKey := FALSE;
        Logic := FALSE;
        WildWall := FALSE;
        BuildBlock := FALSE;
        DoubleMove := FALSE;
      end;
    '1' : begin
        Enemy := TRUE;
        KoolKey := FALSE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := FALSE;
        DoubleMove := FALSE;
      end;
    '2' : begin
        Enemy := TRUE;
        Enemy2 := TRUE;
        KoolKey := FALSE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := FALSE;
        DoubleMove := FALSE;
      end;
    '3' : begin
        Enemy := TRUE;
        Enemy2 := TRUE;
        Enemy3 := TRUE;
        KoolKey := FALSE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := FALSE;
        DoubleMove := FALSE;
      end;
    '4' : begin
        Enemy := TRUE;
        Enemy2 := TRUE;
        Enemy3 := TRUE;
        KoolKey := TRUE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := FALSE;
        DoubleMove := FALSE;
        end;
    'K' : begin
        Enemy := FALSE;
        KoolKey := TRUE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := FALSE;
        DoubleMove := FALSE;
      end;
    'C' : begin
        Enemy := TRUE;
        KoolKey := TRUE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := FALSE;
        DoubleMove := FALSE;
      end;
    'W' : begin
        Enemy := TRUE;
        KoolKey := TRUE;
        Logic := TRUE;
        WildWall := TRUE;
        BuildBlock := FALSE;
        DoubleMove := FALSE;
      end;
    'B' : begin
        Enemy := FALSE;
        KoolKey := FALSE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := TRUE;
        DoubleMove := FALSE;
      end;
    'T' : begin
        Enemy := TRUE;
        KoolKey := FALSE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := TRUE;
        DoubleMove := FALSE;
      end;
    'D' : begin         Enemy := TRUE;
        KoolKey := FALSE;
        Logic := TRUE;
        WildWall := FALSE;
        BuildBlock := FALSE;
        DoubleMove := TRUE;
      end;
  end;
  EX := ParEnX;
  EY := ParEnY;
  E2X := ParEn2X;
  E2Y := ParEn2Y;
  E3X := ParEn3X;
  E3Y := ParEn3Y;
  KX := ParKeyX;
  KY := ParKeyY;
  Moves := ParMoves;
  GotoXY (40,1);
  TextColor (15);
  writeln (Name);
  If EX > 0 then
  begin
    GotoXY (EX,EY);
    write (EnemTexture);
  end;
  If E2X > 0 then
  begin
    GotoXY (E2X,E2Y);
    write (EnemTexture);
  end;
  If E3X > 0 then
  begin
    GotoXY (E3X,E3Y);
    write (EnemTexture);
  end;
  GotoXY (1,2);
  Delay (2000);
  TextColor (ParColor1);
  While not eof(LevData) do
  begin
    read(LevData,Line);
    TextColor (ParColor1); {If Texture is not one of the}
    TextBackground (0); {following:}
    case Line of
      ' ' : begin
          TextColor (0);
          TextBackground (0)
        end;
      'Р' : begin
          TextColor (ParColor2);
          TextBackground (0)
        end;
      '›' : begin
          TextColor (7);
          TextBackground (0)
        end;
      'š' : begin
          TextColor (7);
          TextBackground (0)
        end;
      'А' : begin
          TextColor (2);
          TextBackground (0)
        end;
      'В' : begin
          TextColor (8);
          TextBackground (7)
        end;
      'Б' : begin
          TextColor (8);
          TextBackground (7)
        end;
      '­' : begin
          TextColor (12);
          TextBackground (0)
        end;
      'Ќ' : begin
          TextColor (14);
          TextBackground (0)
        end;
      'ў' : begin
          TextColor (4);
          TextBackground (0)
        end;
      'Д' : begin
          TextColor (5);
          TextBackground (0)
        end;
    end;
    If SoftColor then
    begin
      TextColor (1);
      TextBackground (0);
    end;
    write(Line);
  end;
  TextColor (0);
  TextBackground (0);
  close(LevData);
end;

{*********************************************************************}
procedure PlayerMovement (var X, Y : integer; var BuildBlock : boolean;
                          var C : char; DoubleMove : boolean;
                          var Moves : integer);

begin   C := readkey;
  If (NOT DoubleMove) then
    If ord(C) = 0 then C := readkey; {filters control codes}
  GotoXY (X,Y);
  If NOT BuildBlock then write (' ')
    else begin
      TextColor (8);
      write ('л')
    end;
  case C of
    #$4B : begin {j - left}
        Moves := Moves - 1;
        X := X - 1;
      end;
    #$4D : begin {l - right}
        Moves := Moves - 1;
        X := X + 1;
      end;
    #$48 : begin {i - up}
        Moves := Moves - 1;
        Y := Y - 1;
      end;
    #$50 : begin {k - down}
        Moves := Moves - 1;
        Y := Y + 1
      end;
  end;
end;

{*********************************************************}
function Hitit(X,Y : integer; WallTexture : char): boolean;

begin
  Hitit := Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord(WallTexture)
end;

{*********************************************************}
function HitEnemy(X,Y : integer; EnemTexture : char): boolean;

begin
  HitEnemy := Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord(EnemTexture)
end;

{***************************************}
function HitPost(X,Y : integer): boolean;

begin
  HitPost := Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord('В')
end;

{***************************************}
function HitTree(X,Y : integer): boolean;

begin
  HitTree := Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord('А')
end;

{****************************************}
function HitFence(X,Y : integer): boolean;

begin
  HitFence := Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord('Р')
end;

{***************************************}
function HitLock(X,Y : integer): boolean;

begin
  HitLock := Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord('š')
end;

{***************************************}
function HitSpike(X,Y : integer): boolean;

begin   HitSpike := Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord('ў')
end;

{***************************************}
function HitPricker(X,Y : integer): boolean;

begin
  HitPricker := Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord('Д')
end;

{********************************************************************}
procedure PickupFreeze (var X, Y : integer; var Enemy, SFX : boolean);

var
  Freq, Note : integer;

begin
  Freq := 32;
  If Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord('­') then
  begin
    GotoXY (X,Y);
    write ('');
    Enemy := FALSE;
    GotoXY (40,1);
    write ('Got the Freeze Shield ');
    GotoXY (32,1);
    TextColor (12);
    write ('­');
    for Note := 1 to 16 do
    begin
      Freq := Freq * 2;
      If SFX then sound (Freq);
      delay (20);
    end;
    GotoXY (X,Y);
    NoSound;
  end;
end;

{****************************************************************}
procedure PickupKey (var C : char; var X, Y : integer;
                    var KoolKey: boolean;
var Key, SFX : boolean;
                    var Moves : integer);

var
  Note : integer;

begin
  If Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord('›') then
  begin
    If Key then
    begin
      case C of
        #$4B : begin {j - left}
          Moves := Moves + 1;
          X := X + 1;
        end;
        #$4D : begin {l - right}
          Moves := Moves + 1;
          X := X - 1;
        end;
        #$48 : begin {i - up}
          Moves := Moves + 1;
          Y := Y + 1;
        end;
        #$50 : begin {k - down}
          Moves := Moves + 1;
          Y := Y - 1
        end;
      end;
      GotoXY (40,1);
      write ('Cannot get two keys! ');
      GotoXY (31,1);
      Sound (100);
      Delay (200);
      NoSound;
      GotoXY (X,Y);
      TextColor (15);
      write ('›');
    end;
    If (NOT Key) then
    begin
      GotoXY (X,Y);
      write ('');
      KoolKey := FALSE;
      Key := TRUE;
      GotoXY (40,1);
      write ('Got the key! ');
      GotoXY (31,1);
      TextColor (12);
      write ('›');
      for Note := 1 to 6 do       begin
        case Note of
          1,3 : If SFX then sound (1200);
          2,4 : nosound;
          5,6 : If SFX then sound (1500);
        end;
        delay (50);
      end;
    end;
    GotoXY (X,Y);
    NoSound;
  end;
end;
{*******************************************************************}
procedure PickupPickAxe (var X, Y : integer; var Axe, SFX : boolean);

var
  Freq, Note : integer;

begin
  If Mem[Txt:(((Y - 1) * 160) + ((X - 1) * 2) )] = ord('Ќ') then
  begin
    GotoXY (X,Y);
    write ('');
    Axe := TRUE;
    GotoXY (40,1);
    write ('Got the Pick Axe! ');
    GotoXY (33,1);
    TextColor (12);
    write ('Ќ');
    for Note := 16 downto 1 do
    begin
      If SFX then sound (Note * 50);
      delay (20);
    end;
  GotoXY (X,Y);
  NoSound;
  end;
end;

{**********************************************************************}
procedure NeedKey (var X : integer; var Moves : integer; SFX : boolean);

begin
  GotoXY (40,1);
  If SFX then Sound(30);
  Delay(200);
  write('Need the key! ');
  GotoXY (31,1);
    TextColor (28);
    write ('›');
end;

{********************************************************}
procedure EnemyHitWall (EnemyDirect : integer; var EX, EY,
                        E2X, E2Y : integer);

begin
  case EnemyDirect of
    0 : EX := EX + 1;
    1 : EX := EX - 1;
    2 : EY := EY + 1;
    3 : EY := EY - 1;
    4 : E2X := E2X + 1;
    5 : E2X := E2X - 1;
    6 : E2Y := E2Y + 1;
    7 : E2Y := E2Y - 1   end;
end;

{***************************************************************}
procedure KeyHitWall (KeyDirect : integer; var KX, KY : integer);

begin
  case KeyDirect of
  0 : KX := KX - 1;
    1 : KX := KX + 1;
    2 : KY := KY - 1;
    3 : KY := KY + 1
  end;
end;

{****************************************************}
procedure Death (var Lives : shortint;
SFX : boolean);

var
  Freq : integer;

begin
  for Freq := 900 downto 500 do
  begin
    If SFX then Sound(Freq);
    Delay(2);
  end;
  NoSound;
  Delay(2000);
  Lives := Lives - 1;
end;

{**************************************}
procedure WallGenerate (X, Y : integer);

var
  WX : integer;
  WY : integer;
  NumofWalls : integer;
  RandColor : integer;

begin
  for NumofWalls := 1 to 8 do
  begin
    WX := Random (73) + 4;
    WY := Random (20) + 3;
    RandColor := Random (8) + 1;
    TextColor (RandColor);
    GotoXY (WX,WY);
    write ('В');
    case NumofWalls of
      5,6,7,8 : begin
        GotoXY (WX,WY);
        write (' ');
      end;
    end;
  end;
end;

{*********************************************************************}
procedure HitWall (C : char; var EnemTexture : char; var Key : boolean;
                   var Moves : Integer; var X, Y : integer;
                   SFX : boolean);

var
  Note : integer;

begin
  If HitEnemy (X,Y,EnemTexture) = true then
    begin
      Death (Lives,SFX);
      dec(Level);
      MakeLevel (Axe,BuildBlock,EnemTexture,Enemy,Enemy2,Enemy3,EX,EY,
        E2X,E2Y,E3X,E3Y,KX,KY,KoolKey,Level,Key,Logic,Moves,SoftColor,
        WallTexture,WildWall,X,Y);
    end;

  If (Hitit (X,Y,WallTexture) = true) then
  begin
    If SFX then Sound(2019);
    Delay(15);
    NoSound;
    If C = #$4B then X := X + 1; {j-right}
    If C = #$4D then X := X - 1; {l-left}
    If C = #$48 then Y := Y + 1; {i-down}
    If C = #$50 then Y := Y - 1; {k-up}
    Moves := Moves + 1;
  end;
  If (HitLock (X,Y) = true) then
  begin
    If (NOT Key) then
    begin
      NeedKey (X,Moves,SFX);
      If SFX then Sound(2019);
      Delay(15);
      NoSound;
      If C = #$4B then X := X + 1; {j-right}
      If C = #$4D then X := X - 1; {l-left}
      If C = #$48 then Y := Y + 1; {i-down}
      If C = #$50 then Y := Y - 1; {k-up}
      Moves := Moves + 1;
    end;
    If Key then
    begin
      Key := FALSE;
      GotoXY (X,Y);
      write ('');
      GotoXY (40,1);
      write ('Door is unlocked! ');
      GotoXY (31,1);
      TextColor (12);
      write (' ');
      for Note := 1 to 6 do
      begin
        case Note of
          1,2 : If SFX then sound (1500);
          4,6 : nosound;
          3,5 : If SFX then sound (1200);
        end;
        delay (50);
      end;
      GotoXY (X,Y);
      NoSound;
    end;
  end;

  If (HitPost (X,Y) = true) or (HitTree (X,Y) = true) then
  begin
    If SFX then Sound(X * Y);
    Delay(40);
    NoSound;
    If (NOT Axe) then
    begin
      If C = #$4B then X := X + 1;
      If C = #$4D then X := X - 1;
      If C = #$48 then Y := Y + 1;
      If C = #$50 then Y := Y - 1;
      Moves := Moves + 1;
    end;
  end;
  If HitFence (X,Y) = true then
  begin
    If SFX then Sound(X * Y);
    Delay(40);
    NoSound;
    If C = #$4B then X := X + 1;
    If C = #$4D then X := X - 1;
    If C = #$48 then Y := Y + 1;
    If C = #$50 then Y := Y - 1;
    Moves := Moves + 1;
  end;
  If HitSpike (X,Y) = true then
    begin
      Death (Lives,SFX);
      dec(Level);
      MakeLevel (Axe,BuildBlock,EnemTexture,Enemy,Enemy2,Enemy3,EX,EY,
        E2X,E2Y,E3X,E3Y,KX,KY,KoolKey,Level,Key,Logic,Moves,SoftColor,
        WallTexture,WildWall,X,Y);
    end;
  If HitPricker (X,Y) = true then
    begin
      Death (Lives,SFX);
      dec(Level);
      MakeLevel (Axe,BuildBlock,EnemTexture,Enemy,Enemy2,Enemy3,EX,EY,
        E2X,E2Y,E3X,E3Y,KX,KY,KoolKey,Level,Key,Logic,Moves,SoftColor,
        WallTexture,WildWall,X,Y);
    end;
end;

{*********************************************************************}
procedure EnemyMovement (var X, Y, EX, EY : integer;
                         var EnemTexture : char; var Enemy : boolean;
                         EnemyDirect : shortint; var KoolKey : boolean;
                         Level : LevType; WallTexture : char);

begin
  GotoXY (EX,EY);
  write (' ');
  EnemyDirect := Random (5);
  case EnemyDirect of     0 : If EX > X then EX := EX - 1;
    1 : If EX < X then EX := EX + 1;
    2 : If EY > Y then EY := EY - 1;
    3 : If EY < Y then EY := EY + 1
  end;
  If (EX > 79) then EX := 79;
  If (EX < 1) then EX := 1;
  If (EY > 23) then EY := 23;
  If (EY < 3) then EY := 3;

  {If (X = EX) and (Y = EY) then
    begin
      GotoXY (X,Y);
      TextColor (4);
      write (EnemTexture);
      Death (Lives,SFX);
      dec(Level);
      MakeLevel (Axe,BuildBlock,EnemTexture,Enemy,Enemy2,Enemy3,EX,EY,
        E2X,E2Y,E3X,E3Y,KX,KY,KoolKey,Level,Key,Logic,Moves,SoftColor,
        WallTexture,WildWall,X,Y);
    end;}

  If Mem[Txt:(((EY - 1) * 160) + ((EX - 1) * 2) )] = ord(WallTexture) then
    EnemyHitWall (EnemyDirect,EX,EY,E2X,E2Y);
  If Mem[Txt:(((EY - 1) * 160) + ((EX - 1) * 2) )] = ord(EnemTexture) then
    EnemyHitWall (EnemyDirect,EX,EY,E2X,E2Y);
  If Mem[Txt:(((EY - 1) * 160) + ((EX - 1) * 2) )] = ord('А') then
    EnemyHitWall (EnemyDirect,EX,EY,E2X,E2Y);
  If Mem[Txt:(((EY - 1) * 160) + ((EX - 1) * 2) )] = ord('›') then
    EnemyHitWall (EnemyDirect,EX,EY,E2X,E2Y);
  If Mem[Txt:(((EY - 1) * 160) + ((EX - 1) * 2) )] = ord('Ќ') then
    EnemyHitWall (EnemyDirect,EX,EY,E2X,E2Y);
  If Mem[Txt:(((EY - 1) * 160) + ((EX - 1) * 2) )] = ord('š') then
    EnemyHitWall (EnemyDirect,EX,EY,E2X,E2Y);
  If Mem[Txt:(((EY - 1) * 160) + ((EX - 1) * 2) )] = ord('ў') then
    EnemyHitWall (EnemyDirect,EX,EY,E2X,E2Y);
  If Mem[Txt:(((EY - 1) * 160) + ((EX - 1) * 2) )] = ord('Б') then
    begin
      KoolKey := TRUE;
    end;
  GotoXY (EX,EY);
  write (EnemTexture);
end;

{********************************************************************}
procedure KeyMovement (var X, Y, KX, KY : integer; WallTexture,
                       EnemTexture : char; KeyDirect : shortint);

begin
  GotoXY (KX,KY);
  write (' ');
  KeyDirect := Random (4);
  case KeyDirect of
    0 : If (KX >= X) then KX := KX + 1;
    1 : If (KX <= X) then KX := KX - 1;
    2 : If (KY >= Y) then KY := KY + 1;
    3 : If (KY <= Y) then KY := KY - 1
  end;
  If (KX > 77) then KX := 77;
  If (KX < 4) then KX := 4;
  If (KY > 23) then KY := 23;
  If (KY < 3) then KY := 3;
  If Mem[Txt:(((KY - 1) * 160) + ((KX - 1) * 2) )] = ord(WallTexture) then
    KeyHitWall (KeyDirect,KX,KY);
  If Mem[Txt:(((KY - 1) * 160) + ((KX - 1) * 2) )] = ord('ў') then
    KeyHitWall (KeyDirect,KX,KY);
  If Mem[Txt:(((KY - 1) * 160) + ((KX - 1) * 2) )] = ord(EnemTexture) then
  KeyHitWall (KeyDirect,KX,KY);
  GotoXY (KX,KY);
  write ('›');
end;

{***}
BEGIN
  Level := 1;
  while (Level < 14) do
  begin
    IntroCredits (Level,Lives,SFX,SoftColor);
    Level := Level - 1;
    MakeLevel (Axe,BuildBlock,EnemTexture,Enemy,Enemy2,Enemy3,EX,EY,
      E2X,E2Y,E3X,E3Y,KX,KY,KoolKey,Level,Key,Logic,Moves,SoftColor,
      WallTexture,WildWall,X,Y);

    TextColor (15);
    If EX > 0 then
    begin
      GotoXY (EX,EY);
      write (EnemTexture);
  end;
    If E2X > 0 then
    begin
      GotoXY (E2X,E2Y);
      write (EnemTexture);
    end;
    If E3X > 0 then
  begin
      GotoXY (E3X,E3Y);
      write (EnemTexture);
    end;

    while NOT (C = '') do
    begin
      PlayerMovement(X,Y,BuildBlock,C,DoubleMove,Moves);

      If Enemy then
        EnemyMovement(X,Y,EX,EY,EnemTexture,Enemy,EnemyDirect,
          KoolKey,Level,WallTexture);

      If Enemy2 then
        EnemyMovement(X,Y,E2X,E2Y,EnemTexture,Enemy,EnemyDirect,
          KoolKey,Level,WallTexture);

      If Enemy3 then
        EnemyMovement(X,Y,E3X,E3Y,EnemTexture,Enemy,EnemyDirect,
          KoolKey,Level,WallTexture);

      If KoolKey then
        KeyMovement(X,Y,KX,KY,WallTexture,EnemTexture,KeyDirect);

      If WildWall then
        WallGenerate(X,Y);

      If (X > 79) then
        begin
          MakeLevel (Axe,BuildBlock,EnemTexture,Enemy,Enemy2,Enemy3,EX,EY,
            E2X,E2Y,E3X,E3Y,KX,KY,KoolKey,Level,Key,Logic,Moves,SoftColor,
            WallTexture,WildWall,X,Y)
        end;
      If (X < 1) then
      begin
        X := 1;
        Moves := Moves + 1;
      end;
      If (Y < 2) then
      begin
        Y := 2;
        Moves := Moves + 1;
      end;
      If (Y > 24) then
      begin
        Y := 24;
        Moves := Moves + 1;
      end;
      If NOT Logic then
        begin
          If Moves < 1 then
            begin
              GotoXY (2,1); write ('Moves = ',Moves,' ');
              GotoXY (40,1); write ('Too many moves! ');
              Death (Lives,SFX);
              Level := Level - 1;
              MakeLevel (Axe,BuildBlock,EnemTexture,Enemy,Enemy2,Enemy3,
                EX,EY,E2X,E2Y,E3X,E3Y,KX,KY,KoolKey,Level,Key,Logic,Moves,
                SoftColor,WallTexture,WildWall,X,Y);
            end;
        end;
      If Lives < 1 then
        begin
          TextColor(White);
          GotoXY (20,1); write ('Lives = ',Lives);
          GotoXY (40,1); write ('Game over! ');
          Death (Lives,SFX);
          Level := 0;
          Lives := 3;
          break;
        end;
      HitWall (C,EnemTexture,Key,Moves,X,Y,SFX);
      GotoXY (X,Y);
      PickupKey (C,X,Y,KoolKey,Key,SFX,Moves);
      PickupFreeze (X,Y,Enemy,SFX);
      If NOT Axe then PickupPickAxe (X,Y,Axe,SFX);
      TextColor (15);
      TextBackground (0);
      write ('');
      TextColor(7);
      If NOT Logic then
        begin
          GotoXY (2,1); write ('Moves = ',Moves,' ');
        end;
      GotoXY (20,1); write ('Lives = ',Lives);
      If NOT (Level = 0) then
        begin
          GotoXY (65,1); write ('Level ',Level);
        end;
      NoSound;
    end;
    Lives := 0;
    EndCredits (Lives);
    break;
  end;
END.