{===========================================================================}
{                            BADGUYS.PAS                                    }
{===========================================================================}
{                                                                           }
{  Source File: BADGUYS.PAS                                                 }
{  Date: May 28, 1999                                                       }
{  Written By: Mike and Jeff                                                }
{                                                                           }
{  Last Modification: June 6, 1999                                          }
{      Changed so background maintained when objects moved on screen.       }
{  Last Modification: June 7, 1999                                          }
{      Cleaned up comments                                                  }
{                                                                           }
{---------------------------------------------------------------------------}
{ Comments:                                                                 }
{                                                                           }
{                                                                           }
{                                                                           }
{---------------------------------------------------------------------------}

USES CRT,WINDOWU;

TYPE

{ Use a maximum array size of 2000. The most badguys you can have is }
{ 24 * 79 = 1896 so this covers the limit.                           }

BADGUYPOSITION  = ARRAY[0..2000] OF INTEGER;
BADGUYSTATUS    = ARRAY[0..2000] OF BOOLEAN;

VAR

XPOSITIONBADGUY : BADGUYPOSITION;  { X position ARRAY of bad guys }
YPOSITIONBADGUY : BADGUYPOSITION;  { Y position ARRAY of bad guys }
BADGUYSHOT      : BADGUYSTATUS;    { Flags ARRAY to indicate if bad guy shot }

INDEX    : INTEGER;        { Loop counter     }
YINDEX   : INTEGER;        { Loop counter for Y value }
XINDEX   : INTEGER;        { Loop counter for X value }
ANSWER   : STRING;         { Y or N input     }

MOVE      : REAL;          { Random number value used to determine if the }
                           { Bad Guys move                                }

SCORE    : LONGINT;        { Score value           }

XPOSITION,                 { New X value for Good Guy }
YPOSITION,                 { New Y value for Good Guy }
OLDXPOSITION,              { Previous X value of Good Guy }
OLDYPOSITION    : INTEGER; { Previous Y value of Good Guy }

NUMBADGUYS : INTEGER;      { Set this to the number of badguys - 1  }
LEVELNUMBER : INTEGER;     { This is the current level being played }

KEY             : CHAR;    { Value of the key pressed }

DONE : BOOLEAN;            { Flag to indicate we are done           }
SOUNDON : BOOLEAN;         { Flag to turn sound effects on or off   }
MOVEON  : BOOLEAN;         { Flag to turn move BADGUYS on           }
COLORON : BOOLEAN;         { Flag to turn on color display          }
ALLDONE : BOOLEAN;         { Flag to indicate all bad guys are shot }

{-------------------------------------------------------------------------}
{ THIS ROUTINE DISPLAYS THE GAME INSTRUCTIONS                             }
{-------------------------------------------------------------------------}

PROCEDURE SHOWINSTRUCTIONS;
BEGIN
  CLRSCR;
  WRITELN('+==============================================================+');
  WRITELN('|  The BADGUYS game                             Version 1.00   |');
  WRITELN('|--------------------------------------------------------------|');
  WRITELN('| The object of this game is to get all the BADGUYS !!!        |');
  WRITELN('| Each BADGUY is 5 points. You can shoot them or run them over.|');
  WRITELN('| The keys used are shown below.                               |');
  WRITELN('|                                                              |');
  WRITELN('|    Move right = right arrow     S =  toggle sound effects    |');
  WRITELN('|    Move left  = left  arrow     Z =  toggle movement         |');
  WRITELN('|    Move up    =  up   arrow     Q =  quit the game           |');
  WRITELN('|    Move down  = down  arrow                                  |');
  WRITELN('|                                                              |');
  WRITELN('|    Shoot right = F key                                       |');
  WRITELN('|    Shoot left  = D key                                       |');
  WRITELN('|    Shoot up    = R key                                       |');
  WRITELN('|    Shoot down  = C key                                       |');
  WRITELN('|                                                              |');
  WRITELN('| After all BADGUYS are gone a new screen is generated. Each   |');
  WRITELN('| new screen has twice as many BADGUYS ! The maximum number    |');
  WRITELN('| of BADGUYS is 1896, at which time the game starts over at    |');
  WRITELN('| 5 BADGUYS.                                                   |');
  WRITELN('+==============================================================+');
  WRITELn('Push any key to start the game ...');
  READLN;
END;

{-------------------------------------------------------------------------}
{ THIS ROUTINE MAKES THE BAD GUY SHOT SOUND                               }
{-------------------------------------------------------------------------}

PROCEDURE BADGUYSHOTSOUND;
BEGIN
  SOUND(1000);                        { Set the frequency of the sound    }
  DELAY(15);                          { Wait a bit                        }
  SOUND(1500);                        { Change the frequency of the sound }
  DELAY(15);                          { Wait a bit                        }
  SOUND(2500);                        { Change the frequency of the sound }
  DELAY(15);                          { Wait a bit                        }
  NOSOUND;                            { Turn off the sound                }
END;

{-------------------------------------------------------------------------}
{ THIS ROUTINE SETS UP THE BAD GUYS ON THE SCREEN                         }
{-------------------------------------------------------------------------}
{ Two arrays are used to hold the X Y positions of the Badguys. A third   }
{ array is used to hold the status of each Badguy. ie. A Badguy can be    }
{ either Shot ( True ) or Not Shot ( False ) This array is initially set  }
{ to False for all Badguys. The initial X Y positions are generated by    }
{ using the Random function.                                              }
{                                                                         }
{-------------------------------------------------------------------------}

PROCEDURE CREATEBADGUYS;
BEGIN
{ Use a Random number generator to intialize the BadGuy array }

  RANDOMIZE;                         { Set up the random number generator }

  FOR INDEX := 0 TO NUMBADGUYS DO
  BEGIN
{ Save the randomly generated badguy positions in an array }

    XPOSITIONBADGUY[INDEX] := RANDOM(78)+1;  { Set a random range 0 to 79 }
    YPOSITIONBADGUY[INDEX] := RANDOM(23)+1;  { Set a random range 0 to 24 }

{ Set shot status to false for all bad guys }

    BADGUYSHOT[INDEX] := FALSE;           { Set bad guy shot false        }

      IF COLORON THEN                     { See if we have selected color }
        SETCOLOR(BROWN,BLACK);            { if so set the Bad Guy color   }

{ Now write the badguys on the screen }

    GOTOXY(XPOSITIONBADGUY[INDEX],YPOSITIONBADGUY[INDEX]);
    WRITE(CHR(1));          { This is where you can set the bad guy shape }
  END;
  IF COLORON THEN                         { See if we have selected color }
     SETCOLOR(WHITE,BLACK);               { if so set the default color   }

END;

{-------------------------------------------------------------------------}
{ THIS ROUTINE CHECKS TO SEE IF ANY BADGUYS HIT                           }
{-------------------------------------------------------------------------}
{ Check if we have hit a bad guy. If so then bump up the score. We do this}
{ by checking the X Y position of the missile with the X Y positions saved}
{ in the Badguy X and Y arrays. If the X Y position matches then we have  }
{ a hit. A flag is set TRUE to indicate that we have hit this badguy. The }
{ next time if we get a match on the X Y position we will not bump up the }
{ score since this flag shows us that we have already hit this bad guy.   }
{                                                                         }
{-------------------------------------------------------------------------}

PROCEDURE CHECKHITS;
BEGIN

      FOR INDEX := 0 TO NUMBADGUYS DO
      BEGIN
        IF ( XPOSITIONBADGUY[INDEX] = XPOSITION)      { Check X position  }
           AND ( YPOSITIONBADGUY[INDEX] = YPOSITION ) { and Y position    }
           AND ( BADGUYSHOT[INDEX] = FALSE ) THEN     { and see if we hit }
           BEGIN                                      { this one before   }
             BADGUYSHOT[INDEX] := TRUE;
             SCORE := SCORE + 5;        { Not hit before so Bump score    }
             IF SOUNDON THEN            { Make Sound only if flag is TRUE }
                BADGUYSHOTSOUND;
           END;
      END;

{ Now check if all the bad guys are shot - if so then create some more   }
{ We do this by checking the Badguyshot array to see if any flags are    }
{ still FALSE. A flag that is FALSE indicates a Badguy that was not shot }

      ALLDONE := TRUE;                  { Set alldone flag TRUE to start }

      FOR INDEX := 0 TO NUMBADGUYS DO
      BEGIN
        IF ( BADGUYSHOT[INDEX] = FALSE ) THEN
           ALLDONE := FALSE;           { If one not shot then clear flag }
      END;
      IF ALLDONE THEN
        BEGIN
          GOTOXY (1,25);
          WRITE(' You''re not done yet !!');          { Message to player }
          DELAY(2000);                                { Delay so player   }
          GOTOXY (1,25);                              { can read message  }
          WRITE('                       ');           { Clear the message }

{ Increase the difficulty of game by increasing number of bad guys        }
{ Here is where you can have some fun !!                                  }

          NUMBADGUYS := NUMBADGUYS * 2;     { Double the number of Badguys }
          LEVELNUMBER := LEVELNUMBER + 1;   { Bump up the Level Number     }
          IF NUMBADGUYS > 1896 THEN { The limitation is on the screen size }
             NUMBADGUYS := 4;       { which is 79 x 24 = 1896 in text mode }
          CREATEBADGUYS;            { Create some more bad guys            }
        END;
      IF COLORON THEN               { Check the color flag                 }
        SETCOLOR(YELLOW,BLACK);
{ Update the level }
    GOTOXY(1,25);
    WRITE('LEVEL = ',LEVELNUMBER);           { Bump up the displayed Level }
      IF COLORON THEN                        { Check the color flag        }
        SETCOLOR(CYAN,BLACK);
{ Update the  number of badguys }
      GOTOXY(12,25);
      WRITE('BADGUYS = ',NUMBADGUYS+1);    { Bump up the displayed Badguys }
      IF COLORON THEN                      { Check the color flag          }
        SETCOLOR(WHITE,BLACK);
{ Update the score }
      GOTOXY(25,25);
      WRITE('SCORE = ',SCORE);             { Bump up the displayed Score   }
END;

{-------------------------------------------------------------------------}
{ THIS ROUTINE MOVES THE BADGUYS AROUND BASED ON A RANDOM VALUE           }
{-------------------------------------------------------------------------}

PROCEDURE MOVEBADGUYS;
BEGIN
  RANDOMIZE;                         { Set up the random number generator }
  MOVE := RANDOM;                    { Get a random number }

  IF MOVE > 0.5 THEN                 { Only move if random number is > 0.5 }
  BEGIN
    FOR INDEX := 0 TO NUMBADGUYS DO
    BEGIN
      IF ( BADGUYSHOT[INDEX] = FALSE ) THEN    { Only move Badguys NOT shot }
      BEGIN
{ First clear the BADGUY by writing background value in its position }
        GOTOXY(XPOSITIONBADGUY[INDEX],YPOSITIONBADGUY[INDEX]);
        IF COLORON THEN                      { Check the color flag         }
           SETCOLOR(GREEN,BLACK);
        WRITE(CHR(177));                     { This is the background value }

        MOVE := RANDOM;                      { Get a random number }
{ The X direction we move is also based on a random number.. if > 0.5 we  }
{ move Left, otherwise we move Right                                      }
        IF MOVE > 0.5 THEN
        BEGIN
           XPOSITIONBADGUY[INDEX] := XPOSITIONBADGUY[INDEX] - 1;
           IF XPOSITIONBADGUY[INDEX] < 1 THEN   { Check if at edge of screen }
              XPOSITIONBADGUY[INDEX] := 1;
        END
        ELSE
        BEGIN
           XPOSITIONBADGUY[INDEX] := XPOSITIONBADGUY[INDEX] + 1;
           IF XPOSITIONBADGUY[INDEX] > 79 THEN  { Check if at edge of screen }
              XPOSITIONBADGUY[INDEX] := 79;
        END;
{ The Y direction we move is also based on a random number.. if > 0.5 we  }
{ move Up, otherwise we move Down                                         }
        IF MOVE > 0.5 THEN
        BEGIN
           YPOSITIONBADGUY[INDEX] := YPOSITIONBADGUY[INDEX] - 1;
           IF YPOSITIONBADGUY[INDEX] < 1 THEN  { Check if at edge of screen }
              YPOSITIONBADGUY[INDEX] := 1;
        END
        ELSE
        BEGIN
           YPOSITIONBADGUY[INDEX] := YPOSITIONBADGUY[INDEX] + 1;
           IF YPOSITIONBADGUY[INDEX] > 24 THEN { Check if at edge of screen }
              YPOSITIONBADGUY[INDEX] := 24;
        END;

      IF COLORON THEN                      { Check the color flag         }
        SETCOLOR(BROWN,BLACK);
{ Now write the BADGUY in the new position }
        GOTOXY(XPOSITIONBADGUY[INDEX],YPOSITIONBADGUY[INDEX]);
        WRITE(CHR(1));      { This is where you can set the bad guy shape }
      END;
  END;
END;

END;

{-------------------------------------------------------------------------}
{ THIS ROUTINE SETS UP THE BACKGROUND OF THE GAME                         }
{-------------------------------------------------------------------------}

PROCEDURE SETBACKGROUND;
BEGIN
  CLRSCR;                                 { Clear the screen }
  FOR YINDEX := 1 TO 24 DO                { We do 24 lines of 80 characters }
  BEGIN
    FOR XINDEX := 1 TO 80 DO
    BEGIN
      GOTOXY(XINDEX,YINDEX);
      IF COLORON THEN                     { Check the color flag }
        SETCOLOR(GREEN,BLACK);
      WRITE(CHR(177));         { This is where you can set the background   }
    END;                       { character. USE THE ASCII TABLE IN THE BOOK }
  END;
  IF COLORON THEN                         { Check the color flag }
     SETCOLOR(RED,BLACK);
  GOTOXY(40,25);                          { Write the title }
  WRITE('         The Badguys game.  Version 1.00');
  IF COLORON THEN                         { Check the color flag }
     SETCOLOR(YELLOW,BLACK);
    GOTOXY(1,25);
    WRITE('LEVEL = ',LEVELNUMBER);        { Update the level }
  IF COLORON THEN                         { Check the color flag }
     SETCOLOR(CYAN,BLACK);
  GOTOXY(12,25);
  WRITE('BADGUYS = ',NUMBADGUYS+1);       { Update the  number of badguys }
  IF COLORON THEN                         { Check the color flag }
     SETCOLOR(WHITE,BLACK);
  GOTOXY(25,25);
  WRITE('SCORE = ',SCORE);                { Update the score }
END;

{-------------------------------------------------------------------------}
{ THIS ROUTINE CHECKS TO SEE IF ALL DONE  ( FOR LEFT & RIGHT FIRES )      }
{-------------------------------------------------------------------------}

PROCEDURE CHECKIFDONELR;
BEGIN

{ Check if we have hit a bad guy. If so then bump up the score.       }
{ We do this by checking the X Y position of the missile with the X Y }
{ positions saved in the Badguy X and Y arrays.                       }
{ If the X Y position matches then we have a hit. A flag is set TRUE  }
{ to indicate that we have hit this badguy. The next time if we get a }
{ match on the X Y position we will not bump up the score since this  }
{ flag shows us that we have already hit this bad guy.                }

      FOR INDEX := 0 TO NUMBADGUYS DO
      BEGIN
        IF ( XPOSITIONBADGUY[INDEX] = XINDEX )        { Check X position  }
           AND ( YPOSITIONBADGUY[INDEX] = YPOSITION ) { and Y position    }
           AND ( BADGUYSHOT[INDEX] = FALSE ) THEN     { and see if we hit }
           BEGIN                                      { this one before   }
             BADGUYSHOT[INDEX] := TRUE;
             SCORE := SCORE + 5;                      { Bump score    }
             IF SOUNDON THEN            { Make Sound only if flag is TRUE }
                BADGUYSHOTSOUND;
           END;
      END;

{ Now check if all the bad guys are shot - if so then create some more   }
{ We do this by checking the Badguyshot array to see if any flags are    }
{ still FALSE. A flag that is FALSE indicates a Badguy that was not shot }

      ALLDONE := TRUE;                  { Set the DONE flag on initially }

      FOR INDEX := 0 TO NUMBADGUYS DO
      BEGIN
        IF ( BADGUYSHOT[INDEX] = FALSE ) THEN { If any Badguy Not shot   }
           ALLDONE := FALSE;                  { clear DONE flag          }
      END;
      IF ALLDONE THEN                         { If DONE then display a   }
        BEGIN                                 {message                   }
          GOTOXY (1,25);
          WRITE(' You''re not done yet !!');
          DELAY(2000);
          GOTOXY (1,25);                      { Clear the message        }
          WRITE('                       ');

{ Increase the difficulty of game by increasing number of bad guys        }
{ Here is where you can have some fun !!                                  }

          NUMBADGUYS := NUMBADGUYS * 2;    { Double the number of Badguys }
          LEVELNUMBER := LEVELNUMBER + 1;  { Bump up the Level            }
          IF NUMBADGUYS > 1896 THEN      { See if at the limit of Badguys }
             NUMBADGUYS := 4;            { If we are then reset back to 5 }
          CREATEBADGUYS;                      { Create some more bad guys }
        END;
      IF COLORON THEN                        { Check the color flag }
        SETCOLOR(YELLOW,BLACK);
      GOTOXY(1,25);
      WRITE('LEVEL = ',LEVELNUMBER);         { Update the level }
      IF COLORON THEN                        { Check the color flag }
        SETCOLOR(CYAN,BLACK);
      GOTOXY(12,25);
      WRITE('BADGUYS = ',NUMBADGUYS+1);      { Update the  number of badguys }
      IF COLORON THEN                        { Check the color flag }
        SETCOLOR(WHITE,BLACK);
      GOTOXY(25,25);
      WRITE('SCORE = ',SCORE);               { Update the score }
END;

{-------------------------------------------------------------------------}
{ THIS ROUTINE CHECKS TO SEE IF ALL DONE   ( FOR UP & DOWN FIRES )        }
{-------------------------------------------------------------------------}

PROCEDURE CHECKIFDONEUD;
BEGIN

{ Check if we have hit a bad guy. If so then bump up the score.       }
{ We do this by checking the X Y position of the missile with the X Y }
{ positions saved in the Badguy X and Y arrays.                       }
{ If the X Y position matches then we have a hit. A flag is set TRUE  }
{ to indicate that we have hit this badguy. The next time if we get a }
{ match on the X Y position we will not bump up the score since this  }
{ flag shows us that we have already hit this bad guy.                }

      FOR INDEX := 0 TO NUMBADGUYS DO
      BEGIN
        IF ( YPOSITIONBADGUY[INDEX] = YINDEX )        { Check X position  }
           AND ( XPOSITIONBADGUY[INDEX] = XPOSITION ) { and Y position    }
           AND ( BADGUYSHOT[INDEX] = FALSE ) THEN     { and see if we hit }
           BEGIN                                      { this one before   }
             BADGUYSHOT[INDEX] := TRUE;
             SCORE := SCORE + 5;                      { Bump score    }
             IF SOUNDON THEN            { Make Sound only if flag is TRUE }
                BADGUYSHOTSOUND;
           END;
      END;

{ Now check if all the bad guys are shot - if so then create some more   }
{ We do this by checking the Badguyshot array to see if any flags are    }
{ still FALSE. A flag that is FALSE indicates a Badguy that was not shot }

      ALLDONE := TRUE;                  { Set the DONE flag on initially }

      FOR INDEX := 0 TO NUMBADGUYS DO
      BEGIN
        IF ( BADGUYSHOT[INDEX] = FALSE ) THEN { If any Badguy Not shot   }
           ALLDONE := FALSE;                  { clear DONE flag          }
      END;
      IF ALLDONE THEN                         { If DONE then display a   }
        BEGIN                                 {message                   }
          GOTOXY (1,25);
          WRITE(' You''re not done yet !!');
          DELAY(2000);
          GOTOXY (1,25);                      { Clear the message        }
          WRITE('                       ');

{ Increase the difficulty of game by increasing number of bad guys        }
{ Here is where you can have some fun !!                                  }

          NUMBADGUYS := NUMBADGUYS * 2;    { Double the number of Badguys }
          LEVELNUMBER := LEVELNUMBER + 1;  { Bump up the Level            }
          IF NUMBADGUYS > 1896 THEN      { See if at the limit of Badguys }
             NUMBADGUYS := 4;            { If we are then reset back to 5 }
          CREATEBADGUYS;                      { Create some more bad guys }
        END;
      IF COLORON THEN                        { Check the color flag }
        SETCOLOR(YELLOW,BLACK);
      GOTOXY(1,25);
      WRITE('LEVEL = ',LEVELNUMBER);         { Update the level }
      IF COLORON THEN                        { Check the color flag }
        SETCOLOR(CYAN,BLACK);
      GOTOXY(12,25);
      WRITE('BADGUYS = ',NUMBADGUYS+1);      { Update the  number of badguys }
      IF COLORON THEN                        { Check the color flag }
        SETCOLOR(WHITE,BLACK);
      GOTOXY(25,25);
      WRITE('SCORE = ',SCORE);               { Update the score }
END;

{==========================================================================}
{                       START OF MAIN PROGRAM                              }
{==========================================================================}

BEGIN
  CLRSCR;                                               { Clear the screen }
  COLORON := FALSE;                  { Set the color display off initially }

{ Check if we need to display instructions }

  WRITELN('The BADGUYS game.....Do you want instructions ? (Y or N )');
  READLN(ANSWER);
  IF (ANSWER = 'Y') OR (ANSWER ='y') THEN
    SHOWINSTRUCTIONS;                          { Display game instructions }

{ Check if we display in color }

  WRITELN('Do you want a color display ? (Y or N )');
  READLN(ANSWER);
  IF (ANSWER = 'Y') OR (ANSWER ='y') THEN
    COLORON := TRUE;            { Set color flag on }

  NUMBADGUYS := 4;              { Set this to the number of badguys - 1 }
  LEVELNUMBER := 1;             { Set the initial level to 1 }

  SOUNDON := TRUE;              { Set  the sound on initially }
  MOVEON := TRUE;               { Set the BADGUY movement on initially }

  SETBACKGROUND;                { Set up the background screen }
  CREATEBADGUYS;                { Create the badguys on screen }

  SCORE := 0;                   { Set score to 0 }

  XPOSITION := 35;              { Set the starting position of smiley face }
  YPOSITION := 15;
  OLDXPOSITION := XPOSITION;    { Set old position to starting position    }
  OLDYPOSITION := YPOSITION;

  GOTOXY (XPOSITION,YPOSITION); { Go to X Y position and write a smiley }
  WRITE(CHR(2));

  DONE := FALSE;                { This is the quit flag }

{-------------------------------------------------------------------------}
{ Start of the routine which reads the keyboard and moves the Smiley face }
{-------------------------------------------------------------------------}

  REPEAT

  IF (KEYPRESSED) THEN                  { See if any key pressed }
  BEGIN
    KEY := READKEY;                     { Yes so now get the Key value }

    IF MOVEON THEN                      { Only move BADGUYS if MOVEON flag }
       MOVEBADGUYS;                     { is TRUE                          }

  IF COLORON THEN                       { Check the color flag }
     SETCOLOR(YELLOW,BLACK);

    GOTOXY(1,25);
    WRITE('LEVEL = ',LEVELNUMBER);      { Update the level }

  IF COLORON THEN                       { Check the color flag }
     SETCOLOR(WHITE,BLACK);

    GOTOXY(25,25);
    WRITE('SCORE = ',SCORE);            { Update the score }

                                        {------------------------}
    IF KEY = #72 THEN                   { Check for Up Arrow Key }
    BEGIN                               {------------------------}
      IF SOUNDON THEN
      BEGIN                             { Sound only if flag is TRUE }
        SOUND(200);
        DELAY(5);
        NOSOUND;
      END;
      OLDYPOSITION := YPOSITION;    { Save the current position of Smiley }
      OLDXPOSITION := XPOSITION;
      YPOSITION := YPOSITION - 1;            { Bump up Y to next position }
      IF YPOSITION < 1 THEN YPOSITION := 1;  { If at Top then stay there  }
      GOTOXY(OLDXPOSITION,OLDYPOSITION);     { Goto old Smiley position   }
      IF COLORON THEN
         SETCOLOR(GREEN,BLACK);
      WRITE(CHR(177));                     { This is the background value }
      IF COLORON THEN                      { Check the color flag }
        SETCOLOR(YELLOW,BLACK);
      GOTOXY(XPOSITION,YPOSITION);
      WRITE(CHR(2));                       { Write the Smiley face }
      CHECKHITS;        { Check for any hits,create new level if required   }
    END;                { if required and update status line with score etc }

                                        {--------------------------}
    IF KEY = #80 THEN                   { Check for Down Arrow Key }
    BEGIN                               {--------------------------}
      IF SOUNDON THEN
      BEGIN
        SOUND(400);                     { Sound only if flag is TRUE }
        DELAY(5);
        NOSOUND;
      END;
      OLDYPOSITION := YPOSITION;      { Save the current position of Smiley }
      OLDXPOSITION := XPOSITION;
      YPOSITION := YPOSITION + 1;           { Bump down Y to next position  }
      IF YPOSITION = 25 THEN YPOSITION := 24;{ If at Bottom then stay there }
      GOTOXY(OLDXPOSITION,OLDYPOSITION);      { Goto old Smiley position    }
      IF COLORON THEN
         SETCOLOR(GREEN,BLACK);
      WRITE(CHR(177));                     { This is the background value }
      IF COLORON THEN                      { Check the color flag }
        SETCOLOR(YELLOW,BLACK);
      GOTOXY(XPOSITION,YPOSITION);
      WRITE(CHR(2));                       { Write the Smiley face }
      CHECKHITS;        { Check for any hits,create new level if required }
    END;                { and update status line with score etc           }

                                        {---------------------------}
    IF KEY = #77 THEN                   { Check for Right Arrow Key }
    BEGIN                               {---------------------------}
      IF SOUNDON THEN
      BEGIN
        SOUND(600);                     { Sound only if flag is TRUE }
        DELAY(5);
        NOSOUND;
      END;
      OLDYPOSITION := YPOSITION;       { Save the current position of Smiley }
      OLDXPOSITION := XPOSITION;
      XPOSITION := XPOSITION + 1;             { Bump up X to next position  }
      IF XPOSITION > 79 THEN XPOSITION := 79; { If at Right then stay there }
      GOTOXY(OLDXPOSITION,OLDYPOSITION);      { Goto old Smiley position    }
      IF COLORON THEN
         SETCOLOR(GREEN,BLACK);
      WRITE(CHR(177));                     { This is the background value }
      IF COLORON THEN                      { Check the color flag }
        SETCOLOR(YELLOW,BLACK);
      GOTOXY(XPOSITION,YPOSITION);
      WRITE(CHR(2));                       { Write the Smiley face }
      CHECKHITS;        { Check for any hits,create new level if required }
    END;                { and update staus line with score etc            }

                                        {--------------------------}
    IF KEY = #75 THEN                   { Check for Left Arrow Key }
    BEGIN                               {--------------------------}
      IF SOUNDON THEN
      BEGIN
        SOUND(800);                     { Sound only if flag is TRUE }
        DELAY(5);
        NOSOUND;
      END;
      OLDYPOSITION := YPOSITION;      { Save the current position of Smiley }
      OLDXPOSITION := XPOSITION;
      XPOSITION := XPOSITION - 1;            { Bump down X to next position }
      IF XPOSITION < 1 THEN XPOSITION := 1;  { If at Left then stay there   }
      GOTOXY(OLDXPOSITION,OLDYPOSITION);     { Goto old Smiley position     }
      IF COLORON THEN
         SETCOLOR(GREEN,BLACK);
      WRITE(CHR(177));                     { This is the background value }
      IF COLORON THEN                      { Check the color flag }
        SETCOLOR(YELLOW,BLACK);
      GOTOXY(XPOSITION,YPOSITION);
      WRITE(CHR(2));                       { Write the Smiley face }
      CHECKHITS;        { Check for any hits,create new level if required }
    END;                { and update staus line with score etc            }

{----------------------------------}
{ Fire the missile Right direction }
{----------------------------------}
                                                {-----------------}
    IF (KEY = 'F') or (KEY ='f') THEN           { Check for F Key }
    BEGIN                                       {-----------------}
      OLDYPOSITION := YPOSITION;   { Save the current position of Smiley }
      OLDXPOSITION := XPOSITION;

      FOR XINDEX := XPOSITION TO 79 DO       { X from current to column 79 }
      BEGIN
        GOTOXY(XINDEX+1,YPOSITION);
        WRITE(CHR(16));      { This is where you can set the missile shape }
        IF SOUNDON THEN             { Sound only if flag is TRUE }
        BEGIN
          SOUND(50+xindex*2);                       { Missile sound effects }
          DELAY(2);                 { Xindex increases so the sound pitch   }
          SOUND(150+xindex*5);      { will rise as the missile moves Right  }
          DELAY(5);                 { on the screen.                        }
          SOUND(250+xindex*12);
          DELAY(10);
          NOSOUND;
        END;
        IF NOT SOUNDON THEN         { If no Sound we must still delay ! }
           DELAY(20);
        GOTOXY(XINDEX+1,YPOSITION);
      IF COLORON THEN                      { Check the color flag }
         SETCOLOR(GREEN,BLACK);
      WRITE(CHR(177));                     { This is the background value }

      CHECKIFDONELR;                         { Check if all Badguys shot }

      END;
    END;

{----------------------------------}
{ Fire the missile Left direction  }
{----------------------------------}
                                                {-----------------}
    IF (KEY = 'D') or (KEY ='d') THEN           { Check for D Key }
    BEGIN                                       {-----------------}
      OLDYPOSITION := YPOSITION;   { Save the current position of Smiley }
      OLDXPOSITION := XPOSITION;

      FOR XINDEX := XPOSITION DOWNTO 2 DO  { X from current downto column 2 }
      BEGIN
        GOTOXY(XINDEX-1,YPOSITION);
        WRITE(CHR(17));     { This is where you can set the missile shape }
        IF SOUNDON THEN             { Sound only if flag is TRUE }
        BEGIN
          SOUND(50+xindex*2);                       { Missile sound effects }
          DELAY(2);                 { Xindex decreases so the sound pitch   }
          SOUND(150+xindex*5);      { will fall as the missile moves Left on}
          DELAY(5);                 { the screen.                           }
          SOUND(250+xindex*12);
          DELAY(10);
          NOSOUND;
        END;
        IF NOT SOUNDON THEN         { If no Sound we must still delay ! }
           DELAY(20);
        GOTOXY(XINDEX-1,YPOSITION);
      IF COLORON THEN
         SETCOLOR(GREEN,BLACK);
      WRITE(CHR(177));                     { This is the background value }

      CHECKIFDONELR;                         { Check if all Badguys shot }

      END;
    END;

{----------------------------------}
{ Fire the missile Up direction    }
{----------------------------------}
                                                {-----------------}
    IF (KEY = 'R') or (KEY ='r') THEN           { Check for R Key }
    BEGIN                                       {-----------------}
      OLDYPOSITION := YPOSITION;   { Save the current position of Smiley }
      OLDXPOSITION := XPOSITION;

      FOR YINDEX := YPOSITION DOWNTO 2 DO     { Y from current downto row 2 }
      BEGIN
        GOTOXY(XPOSITION,YINDEX-1);
        WRITE(CHR(30));       { This is where you can set the missile shape }
        IF SOUNDON THEN             { Sound only if flag is TRUE }
        BEGIN
          SOUND(50+yindex*2);                       { Missile sound effects }
          DELAY(2);                 { Yindex decreases so the sound pitch   }
          SOUND(150+yindex*5);      { will fall as the missile moves UP     }
          DELAY(5);                 { the screen.                           }
          SOUND(250+yindex*12);
          DELAY(10);
          NOSOUND;
        END;
        IF NOT SOUNDON THEN         { If no Sound we must still delay ! }
           DELAY(20);
        GOTOXY(XPOSITION,YINDEX-1);
      IF COLORON THEN
         SETCOLOR(GREEN,BLACK);
      WRITE(CHR(177));                     { This is the background value }

      CHECKIFDONEUD;                         { Check if all Badguys shot }

      END;
    END;

{------------------------------------}
{ Fire the missile Down direction    }
{------------------------------------}
                                                {-----------------}
    IF (KEY = 'C') or (KEY ='c') THEN           { Check for C Key }
    BEGIN                                       {-----------------}
      OLDYPOSITION := YPOSITION;   { Save the current position of Smiley }
      OLDXPOSITION := XPOSITION;

      FOR YINDEX := YPOSITION TO 23 DO           { Y from current to row 23 }
      BEGIN
        GOTOXY(XPOSITION,YINDEX+1);
        WRITE(CHR(31));       { This is where you can set the missile shape }
        IF SOUNDON THEN             { Sound only if flag is TRUE }
        BEGIN
          SOUND(50+yindex*2);                       { Missile sound effects }
          DELAY(2);                 { Yindex decreases so the sound pitch   }
          SOUND(150+yindex*5);      { will fall as the missile moves UP     }
          DELAY(5);                 { the screen.                           }
          SOUND(250+yindex*12);
          DELAY(10);
          NOSOUND;
        END;
        IF NOT SOUNDON THEN         { If no Sound we must still delay ! }
           DELAY(20);
        GOTOXY(XPOSITION,YINDEX+1);
      IF COLORON THEN
         SETCOLOR(GREEN,BLACK);
      WRITE(CHR(177));                     { This is the background value }

      CHECKIFDONEUD;                         { Check if all Badguys shot }

      END;
    END;
                                                          {-------------}
    IF (KEY = 'S') OR (KEY = 's') THEN                    { S FOR SOUND }
      SOUNDON := NOT SOUNDON;    { Toggle sound flag }    {-------------}
                                                          {-------------}
    IF (KEY = 'Z') OR (KEY = 'z') THEN                    { Z FOR MOVE  }
      MOVEON := NOT MOVEON;       { Toggle Move flag }    {-------------}
                                                          {------------}
    IF (KEY = 'Q') OR (KEY = 'q') THEN                    { Q FOR QUIT }
      DONE := TRUE;               { Set DONE flag }       {------------}

  END;

  UNTIL DONE;

END.
