Урок 29 Задача 2

Урок 29 Задача 2

-- перепроектируйте классы так, чтобы можно было двигаться на плоскости
(в двумерном, а не одномерном пространстве):

базовый класс для животного оставьте без изменения, для перемешения в двумерном
пространстве создайте два класса-потомка от Animal:
класс D2Animal, объекты которого двигаются по плоскости
класс D1Animal, объекты которого могут двигаться только по первой строчке
(как и Animal, новый класс тут нужен, чтобы обобщить работу с координатами)
Добавьте класс D2Scene для работы с новым двумерным пространством

uses Crt; //  импортируем модуль Crt

type
  Animal = class
    public
      constructor create(skinValue, moveLeftValue, moveRightValue: char); virtual;
      procedure drawFrame();
      procedure handleCommand(commandValue: char); virtual;
      function getCommand(): char;
      function getPosition(): integer;
      function isCurrentPosition(position: integer): boolean; 
    protected
      moveLeftChar: char; // клавиша (символ) для движения влево
      moveRightChar: char; // клавиша (символ) для движения вправо
      skin: char; // внешний вид
      position: integer; // текущая позиция
      command: char; // последняя введенная команда
      function getNewPosition(commandValue: char): integer;
  end;
  D1Animal = class(Animal) // ползает
    public
    //переопределить конструктор
    constructor create(skinValue, moveLeftValue, moveRightValue: char); override;
    function CurrentPosition(pos, vertical: integer): boolean;
    //добавить вертикаль, поставить на 1
    protected
    vertical: integer;
  end;
  D2Animal = class(Animal) // летает
    public
    //переопределить конструктор
    constructor create(skinValue, moveLeftValue, moveRightValue: char); override;
    //переопределить хэндл команд на обработку второго измерения
    procedure handleCommand(commandValue: char); override;
    function getNewVertical(commandValue: char): integer;
    function getVertical(): integer;
    //проверку переписать, потому что меняется сигнатура
    function CurrentPosition(pos, vertical: integer): boolean;
    protected
    vertical: integer;
    //добавить вертикаль, поставить на 1
    //добавить клавиши вверх и вниз
    moveUpChar: char;
    moveDownChar: char;
  end;

  D2Scene = class // Сцена Двумерной Анимации
    public
      procedure handleCommand();
      procedure run(AnimalItem: D1Animal; SecondAnimal: D2Animal);
      procedure drawSceneFrame(AnimalItem: D1Animal; SecondAnimal: D2Animal);
      function getCommand(): char;
    protected
      command: char; // последняя введенная команда
      function getMax(a, b: integer): integer;
  end;

// -- Реализация D2Scene -------

procedure D2Scene.run(AnimalItem: D1Animal; SecondAnimal: D2Animal);
begin
  // обработки событий
  while(self.getCommand() <> 'q') do
  begin
    ClrScr();
    // новый метод, для отрисовки кадра и всех объектов
    self.drawSceneFrame(AnimalItem, SecondAnimal);
    writeln();
    Delay(50);
    if (keyPressed()) then
    begin
       self.handleCommand();
       AnimalItem.handleCommand(self.getCommand());
       SecondAnimal.handleCommand(self.getCommand());
    end;
  end;

  writeln('Scena zavershena!');
end;

// Отрисовка кадра сцены
procedure D2Scene.drawSceneFrame(AnimalItem: D1Animal; SecondAnimal: D2Animal);
var maxPosition, i, j: integer;
begin
   maxPosition :=
     self.getMax(AnimalItem.getPosition(), SecondAnimal.getPosition());
   for j := 1 to SecondAnimal.getVertical() do
   begin
     for i:=1 to maxPosition do
     begin
       if (AnimalItem.CurrentPosition(i,j)) OR (SecondAnimal.CurrentPosition(i,j)) then
       begin
         if (AnimalItem.CurrentPosition(i,j)) then
           AnimalItem.drawFrame();
         if (SecondAnimal.CurrentPosition(i,j)) then
           SecondAnimal.drawFrame();
       end else
         write(' ');
     end;
     writeln();
   end;
end;

function D2Scene.getMax(a, b: integer): integer;
begin
  if (a > b) then
    result := a
  else
    result := b;
end;

procedure D2Scene.handleCommand();
begin
  self.command := ReadKey(); // читаем символ из консоли
end;

function D2Scene.getCommand(): char;
begin
  result := self.command;
end;


// -- Реализация Animal -------
constructor Animal.create(skinValue, moveLeftValue, moveRightValue: char);
begin
  self.skin := skinValue;
  self.moveLeftChar := moveLeftValue;
  self.moveRightChar := moveRightValue;
  self.command := ' ';  // значение по умолчанию
  self.position := 1;
end;

procedure Animal.drawFrame();
begin
  write(self.skin);
end;

// больше не работаем с консолью напрямую
procedure Animal.handleCommand(commandValue: char);
begin
  self.position := self.getNewPosition(commandValue);
end;

function Animal.getNewPosition(commandValue: char): integer;
begin
  result := self.position; // предыдущее значение, как значение по умолчанию
  if (commandValue = self.moveRightChar) then
    result := self.position + 1
  else
    if ((commandValue = self.moveLeftChar) AND (self.position > 1)) then
      result := self.position - 1;
end;

function Animal.getCommand(): char;
begin
  result := self.command;
end;

function Animal.getPosition(): integer;
begin
  result := self.position;
end;

function Animal.isCurrentPosition(position: integer): boolean;
begin
  result := (position = self.position);
end;
// ----Реализация D1Animal ----
constructor D1Animal.create(skinValue, moveLeftValue, moveRightValue: char);
begin
  Inherited create(skinValue, moveLeftValue, moveRightValue);
  self.vertical:= 1;
end;
function D1Animal.CurrentPosition(pos, vertical: integer): boolean;
begin
  result := (pos = self.position) and (vertical = self.vertical);
end;
// ----Реализация D2Animal ----
constructor D2Animal.create(skinValue, moveLeftValue, moveRightValue: char);
begin
  Inherited create(skinValue, moveLeftValue, moveRightValue);
  self.vertical := 1;
  self.moveUpChar := '8';
  self.moveDownChar := '2';
end;

procedure D2Animal.handleCommand(commandValue: char);
begin
  Inherited handleCommand(commandValue);
  self.vertical := self.getNewVertical(commandValue);
end;

function D2Animal.getNewVertical(commandValue: char): integer;
begin
  result := self.vertical; // предыдущее значение, как значение по умолчанию
  if (commandValue = self.moveDownChar) then
    result := self.vertical + 1
  else
    if ((commandValue = self.moveUpChar) AND (self.vertical > 1)) then
      result := self.vertical - 1;
end;

function D2Animal.getVertical(): integer;
begin
  result := self.Vertical;
end;

function D2Animal.CurrentPosition(pos, vertical: integer): boolean;
begin
  result := (pos = self.position) and (vertical = self.vertical);
end;

// ---------------
var
  Dog: D1Animal; // первое животное
  Ptica: D2Animal; // второе животное
  SceneItem: D2Scene;
begin
  Dog := D1Animal.create('*', 'a', 'd');
  Ptica := D2Animal.create('V', '4', '6');
  SceneItem :=  D2Scene.create(); // создаем сцену
  SceneItem.run(Dog, Ptica); // запускаем анимацию

  readln();
end.
vedro-compota's picture

засчитано

_____________
матфак вгу и остальная классика =)