Упражняюсь в задачах, ранее написал програмку, которая отображает сетку звездочек 10x10 в центре экрана консоли. Символ # перемещается по периметру сетки по часовой стрелке с задержкой в 100 миллисекунд между каждым шагом. Пользователь может приостановить и возобновить анимацию, нажав пробел. Анимация продолжается до тех пор, пока пользователь не нажмет какую-либо клавишу. Программа использует модули SysUtils и Crt для различных функций, включая сон и clrscr. Процедура DrawGrid рисует сетку в заданной позиции x, y, а процедура MoveGrid анимирует движение символа # по периметру сетки.
Вот полный код:
program clrsrceen;
uses Crt, SysUtils;
const
  Width = 12;
  Height = 12;
  Delay = 100;
  GridWidth = 10;
  GridHeight = 10;
  GridBack = '*';
  GridRunner = '#';
procedure DrawGrid(x, y: Integer);
var
  i, j: Integer;
begin
  for i := 0 to GridHeight - 1 do begin
    GotoXY(x, y + i);
    for j := 0 to GridWidth - 1 do
      Write(GridBack);
  end;
end;
procedure MoveGrid(x, y: Integer);
  procedure Animate;
  var
    i: Integer;
  begin
    for i := 0 to GridWidth - 1 do begin
      GotoXY(x + i, y);
      Write(GridRunner);
      GotoXY(x + i, y);
      Sleep(Delay);
      Write(GridBack);
      if KeyPressed then Exit;
    end;
    for i := 0 to GridHeight - 1 do begin
      GotoXY(x + GridWidth - 1, y + i);
      Write(GridRunner);
      GotoXY(x + GridWidth - 1, y + i);
      Sleep(Delay);
      Write(GridBack);
      if KeyPressed then Exit;
    end;
    for i := GridWidth - 1 downto 0 do begin
      GotoXY(x + i, y + GridHeight - 1);
      Write(GridRunner);
      GotoXY(x + i, y + GridHeight - 1);
      Sleep(Delay);
      Write(GridBack);
      if KeyPressed then Exit;
    end;
    for i := GridHeight - 1 downto 0 do begin
      GotoXY(x, y + i);
      Write(GridRunner);
      GotoXY(x, y + i);
      Sleep(Delay);
      Write(GridBack);
      if KeyPressed then Exit;
    end;
  end;
begin
  while not KeyPressed do begin
    GotoXY(1, 1);
    Animate;
  end;
  if ReadKey = #0 then ReadKey;
end;
var
  x, y: Integer;
begin
  ClrScr;
  x := (ScreenWidth - GridWidth) div 2;
  y := (ScreenHeight - GridHeight) div 2;
  DrawGrid(x, y);
  MoveGrid(x, y);
  ClrScr;
end.
Потом возникла необходимость изменить так, чтобы программа закрывалась только нажатием Esc, на стрелки влево и вправо менялась скорость задержки и нажатием пробел менять направление движения решетки. вот что я сам попытался сделать. Но вот это не работает, хотя и компилируется, но теперь кнопки вообще безразличны программе. Подскажите как правильно сделать, и как переписать процедуру Animate без такого количества почти одинаковых блоков.
program clrscreenmode;
uses SysUtils, Crt;
const
   width      = 12;
   height     = 12;
   delay      = 100;
   gridWidth  = 10;
   gridHeight = 10;
   gridBack   = '*';
   gridRunner = '#';
var
  EscPressed: Boolean;
function IsEscPressed(): Boolean;
begin
  if (not EscPressed) and KeyPressed() then
    EscPressed := ReadKey() = #27;
  IsEscPressed := EscPressed;
end;
procedure DrawGrid(x, y	: integer);
var
   i, j	: integer;
begin
   for i := 0 to gridHeight - 1 do begin
      gotoXY(x, y + i);
      for j := 0 to gridWidth - 1 do
	 write(gridBack);
   end;
end;
procedure MoveGrid(x, y	: integer);
  procedure Animate(x, y: integer; forward: Boolean);
  var
   i	: integer;
  begin
   if forward then begin
      for i := 0 to gridWidth - 1 do begin
	 gotoXY(x + i, y);
	 write(gridRunner);
	 gotoXY(x + i, y);
	 sleep(delay);
	 write(gridBack);
	 if KeyPressed and (ReadKey = ' ') then forward := not forward;
	 if IsEscPressed then exit;
      end;
      for i := 0 to gridHeight - 1 do begin
	 gotoXY(x + gridWidth - 1, y + i);
	 write(gridRunner);
	 gotoXY(x + gridWidth - 1, y + i);
	 sleep(delay);
	 write(gridBack);
	 if KeyPressed and (ReadKey = ' ') then forward := not forward;
         if IsEscPressed then exit;
      end;
         for i := gridWidth - 1 downto 0 do begin
	 gotoXY(x + i, y + gridHeight - 1);
	 write(gridRunner);
	 gotoXY(x + i, y + gridHeight - 1);
	 sleep(delay);
	 write(gridBack);
	 if KeyPressed and (ReadKey = ' ') then forward := not forward;
	 if IsEscPressed then exit;
      end;
      for i := gridHeight - 1 downto 0 do begin
	 gotoXY(x, y + i);
	 write(gridRunner);
	 gotoXY(x, y + i);
	 sleep(delay);
	 write(gridBack);
	 if KeyPressed and (ReadKey = ' ') then forward := not forward;
	 if IsEscPressed then exit;
      end;
   end
   else begin
      for i := gridWidth - 1 downto 0 do begin
	 gotoXY(x + i, y);
	 write(gridRunner);
	 gotoXY(x + i, y);
	 sleep(delay);
	 write(gridBack);
	 if KeyPressed and (ReadKey = ' ') then forward := not forward;
	 if IsEscPressed then exit;
      end;
      for i := gridHeight - 1 downto 0 do begin
	 gotoXY(x, y + i);
	 write(gridRunner);
	 gotoXY(x, y + i);
	 sleep(delay);
	 write(gridBack);
	 if KeyPressed and (ReadKey = ' ') then forward := not forward;
         if IsEscPressed then exit;
      end;
      for i := 0 to gridWidth - 1 do begin
	 gotoXY(x + i, y + gridHeight - 1);
	 write(gridRunner);
	 gotoXY(x + i, y + gridHeight - 1);
	 sleep(delay);
	 write(gridBack);
	 if KeyPressed and (ReadKey = ' ') then forward := not forward;
	 if IsEscPressed then exit;
      end;
      for i := 0 to gridHeight - 1 do begin
	 gotoXY(x + gridWidth - 1, y + i);
	 write(gridRunner);
	 gotoXY(x + gridWidth - 1, y + i);
	 sleep(delay);
	 write(gridBack);
	 if KeyPressed and (ReadKey = ' ') then forward := not forward;
	 if IsEscPressed then exit;
      end;
   end;
end;
var
   forward: Boolean;
begin
   forward := True;
   repeat
      gotoXY(1, 1);
      Animate(x, y, forward);
      if KeyPressed and (ReadKey = ' ') then forward := not forward;
   until IsEscPressed();
end;
var
   x, y	: integer;
begin
   clrscr;
   x := (screenWidth - gridWidth) div 2;
   y := (screenHeight - gridHeight) div 2;
   DrawGrid(x, y);
   MoveGrid(x, y);
   clrscr;
end.
