GoalQuest

Crt game with two levels by Nikhil (Y9, Age ~14)

Introduction

Nikhil started his code by basing it on Joe's program SnakeWithoutATail - which is pleasing because that is a reason for publishing our student programs! He then developed his own ideas to produce an original game with impressive coding of objects. The game has two levels, each with its own colours, and the second level's goal has additional protection. Nikhil's instructions are:

  • Use the arrow keys to move.
  • You start in the top left corner.
  • You try to end in the bottom right corner on the line of the goal.
  • For the second level the '!'s are dangerous and will kill you.

A typical screenshot from the running program is shown below.

Screenshot showing Level 2 in action

Screenshot showing Level 2 in action

The Program

program GoalQuest;
{
    Copyright (c) 2013 Nikhil

    Licensed under the Apache License, Version 2.0 (the "License"); you may not
    use this file except in compliance with the License, as described at
    http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/
}
uses
  crt, sysutils;

type enemy = object
  public
    x : integer;
    y : integer;
    oldX : integer;
    oldy : integer;
    name : string;
    direction : string;
    procedure drawMe;
    procedure move;
    procedure init;
  end;
var
  c, oldC : char;
  speed : integer;
  oldplX, oldplY, playerX, playerY, goalX, goalY : integer;
  enemy1, enemy2, enemy3, enemy11, enemy22, enemy33, enemy44 : enemy;
const
  MaxX = 79 ;
  MaxY = 25 ;
  SlowSpeed = 40;       //80

procedure enemy.drawMe;
begin
  gotoxy(x, y);
  write(name);
  if direction = 'right' then
    x := x + 1;
  if direction = 'left' then
    x := x - 1;
  if direction = 'up' then
    y := y - 1;
  if direction = 'down' then
    y := y + 1;
end;

procedure enemy.move;
begin
  if x < 1 then
      x := MaxX;
  if y < 1 then
      y := MaxY;
  if x > MaxX then
      x := 1;
  if y > MaxY then
      y := 1;

  if (X <> oldX) or (y <> oldY) then
    begin
      gotoxy(oldX, oldy);
      write(' ');
      gotoxy(X, Y);
      write(name);
      oldX := X;
      oldY := Y;
    end;
end;

procedure enemy.init;
begin
  oldx := x;
  oldY := y;
end;

procedure intro;
begin
  textColor(yellow);
  textBackground(black);
  clrScr;
  writeln('                    ***********************************');
  writeln('                    Hello and welcome to my Adventure!!');
  writeln('                    ***********************************');
  sleep(2000);
  writeln('                    You must use your arrow keys to get');
  writeln('                    across to the goal - 0_o - when you');
  writeln('                    there  then the second  level  will');
  writeln('                    start.  But  watch  out  there  are');
  writeln('                    enemies patrolling the area. If you');
  writeln('                    touch one then  you  will  have  to');
  writeln('                    start again. In  the  second  level');
  writeln('                    there  will  be  more  enemies  and');
  writeln('                    guards surrounding the  goal. Watch');
  writeln('                            out and good luck!');
  writeln('                           Press enter to begin.');
  readln;
  clrscr;
end;

procedure lose;
begin
  sleep(100);
  clrscr;
  writeln('Oh No!');
  writeln('You died!');
  writeln('The game will close in 10 seconds.');
  sleep(10000);
  halt;
end;

procedure guards;
begin
  gotoxy(74, 23);
  write('0');
  gotoxy(76, 23);
  write('o');
  gotoxy(74, 24);
  write('!');
  gotoxy(75, 24);
  write('!');
  gotoxy(76, 24);
  write('!');
  gotoxy(73, 24);
  write('!');
  gotoxy(77, 24);
  write('!');
  gotoxy(77, 23);
  write('!');
  gotoxy(77, 22);
  write('!');
  gotoxy(77, 21);
  write('!');
  gotoxy(77, 20);
  write('!');
  gotoxy(73, 24);
  write('!');
  gotoxy(73, 23);
  write('!');
  gotoxy(73, 22);
  write('!');
  gotoxy(73, 21);
  write('!');
  gotoxy(73, 20);
  write('!');
  if (playerX = 73) and (playerY = 24) or
     (playerX = 74) and (playerY = 24) or
     (playerX = 75) and (playerY = 24) or
     (playerX = 76) and (playerY = 24) or
     (playerX = 77) and (playerY = 24) or
     (playerX = 77) and (playerY = 23) or
     (playerX = 77) and (playerY = 22) or
     (playerX = 77) and (playerY = 21) or
     (playerX = 77) and (playerY = 20) or
     (playerX = 73) and (playerY = 24) or
     (playerX = 73) and (playerY = 23) or
     (playerX = 73) and (playerY = 22) or
     (playerX = 73) and (playerY = 21) or
     (playerX = 73) and (playerY = 20) then
       lose;
end;

procedure level1;
begin
  textColor(darkgray);
  textBackground(white);
  clrScr;
  playerX := 1;
  playerY := 1;
  goalX := 75;
  goalY := 24;
  enemy1.x := 3;
  enemy2.x := 40;
  enemy3.x := 41;
  enemy1.y := 15;
  enemy2.y := 3;
  enemy3.y := 22;
  enemy1.name := '+';
  enemy2.name := '&';
  enemy3.name := '*';
  enemy1.direction := 'right';
  enemy2.direction := 'down';
  enemy3.direction := 'left';

  //Draw initial screen position
  gotoxy(playerX, playerY);
  writeln('#');
  repeat
    //objective
    gotoxy(goalx, goalY);
    write('0_o');
    sleep(speed);
    if keypressed = true then
      begin
        oldC := c;
        c := readkey;
      end;

    //Controls
    case c of
      #75 : dec(playerX);
      #77 : inc(playerX);
      #72 : dec(playerY);
      #80 : inc(playerY);
      #27 : halt;
      else
        c := oldC;
    end; //case

    enemy1.drawMe;
    enemy2.drawMe;
    enemy3.drawMe;
    sleep(slowspeed);


    if (playerX = enemy1.x) and (playerY = enemy1.y) or
       (playerX = enemy2.x) and (playerY = enemy2.y) or
       (playerX = enemy3.x) and (playerY = enemy3.y) then
      lose;

    enemy1.move;
    enemy2.move;
    enemy3.move;

    if playerX < 1 then
      playerX := MaxX;
    if playerY < 1 then
      playerY := MaxY;
    if playerX > MaxX then
      playerX := 1;
    if playerY > MaxY then
      playerY := 1;

    if (playerX <> oldplX) or (playerY <> oldPlY) then
      begin
        //clear old position
        gotoxy(oldplX, oldplY);
        write(' ');
        gotoxy(playerX, playerY);
        write('#');

        //remember old player coordinates
        oldplX := playerX;
        oldplY := playerY;
      end;

  until (playerX = goalX + 1) and (playerY = goalY);
  Clrscr;
  writeln('level complete!');
  sleep(2000);
end;

procedure level2;
begin
  textBackground(blue);
  textColor(green);
  playerX := 1;
  playerY := 1;
  goalX := 75;
  goalY := 23;
  enemy11.x := 3;
  enemy22.x := 40;
  enemy33.x := 41;
  enemy44.x := 65;
  enemy11.y := 15;
  enemy22.y := 3;
  enemy33.y := 22;
  enemy44.y := 1;
  enemy11.name := '$';
  enemy22.name := '%';
  enemy33.name := '*';
  enemy44.name := '!';
  enemy11.direction := 'right';
  enemy22.direction := 'down';
  enemy33.direction := 'left';
  enemy44.direction := 'down';
  clrscr;

  //Draw initial screen position
  gotoxy(playerX, playerY);
  writeln('#');

  repeat
    guards;
    gotoxy(goalX, goalY);
    write('_');
    sleep(speed);

    if keypressed = true then
      begin
        oldC := c;
        c := readkey;
      end;

    //Controls
    case c of
      #75 : dec(playerX);
      #77 : inc(playerX);
      #72 : dec(playerY);
      #80 : inc(playerY);
      #27 : halt;
    else
      c := oldC;
    end;

    enemy11.drawMe;
    enemy22.drawMe;
    enemy33.drawMe;
    enemy44.drawMe;
    sleep(slowspeed);

    if (playerX = goalX + 1) and (playerY = goalY) then
      begin
        Clrscr;
        writeln('level complete!');
        sleep(2000);
      end;

    if (playerX = enemy11.x) and (playerY = enemy11.y) or
       (playerX = enemy22.x) and (playerY = enemy22.y) or
       (playerX = enemy33.x) and (playerY = enemy33.y) or
       (playerX = enemy44.x) and (playerY = enemy44.y) then
      lose;

    enemy11.move;
    enemy22.move;
    enemy33.move;
    enemy44.move;

    if playerX < 1 then
      playerX := MaxX;
    if playerY < 1 then
      playerY := MaxY;
    if playerX > MaxX then
      playerX := 1;
    if playerY > MaxY then
      playerY := 1;

    if (playerX <> oldplX) or (playerY <> oldPlY) then
      begin
        //clear old position
        gotoxy(oldplX, oldplY);
        write(' ');
        gotoxy(playerX, playerY);
        write('#');
        //remember old player coordinates
        oldplX := playerX;
        oldplY := playerY;
      end;

  until 1 = 2;
end;

begin
  enemy1.init;
  enemy2.init;
  enemy3.init;
  enemy11.init;
  enemy22.init;
  enemy33.init;
  enemy44.init;
  playerX := 1;
  playerY := 1;
  clrscr;
  cursoroff;
  intro;
  repeat
    level1;
    level2;
  until 1 = 2;
end.

Remarks

Could you write a crt program with different levels?

Programming - a skill for life!

Three programs including MazePlus by Nikhil