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

Задача 2 Урок 29
Есть код, который позволяет управлять сразу двумя объектами в анимационной сцене:

uses Crt; //  импортируем модуль Crt
  
type
  Animal = class
    public
      constructor create(skinValue, moveLeftChar, moveRightChar: char);
      procedure drawFrame();
      procedure handleCommand(commandValue: char);
      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;
  
  Scene = class // Сцена Анимации
    public
      procedure handleCommand();
      procedure run(AnimalItem, SecondAnimal: Animal);
      procedure drawSceneFrame(AnimalItem, SecondAnimal: Animal);
      function getCommand(): char;
    protected
      command: char; // последняя введенная команда
      function getMax(a, b: integer): integer;
  end;
  
// -- Реализация Scene -------
  
procedure Scene.run(AnimalItem, SecondAnimal: Animal);
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 Scene.drawSceneFrame(AnimalItem, SecondAnimal: Animal);
var maxPosition, i: integer;
begin
   maxPosition :=
     self.getMax(AnimalItem.getPosition(), SecondAnimal.getPosition());
   for i:=1 to maxPosition do
   begin
     if (AnimalItem.isCurrentPosition(i)) OR (SecondAnimal.isCurrentPosition(i)) then
     begin
       if (AnimalItem.isCurrentPosition(i)) then
         AnimalItem.drawFrame();
       if (SecondAnimal.isCurrentPosition(i)) then
         SecondAnimal.drawFrame();
     end else
       write(' ');
   end;
end;
  
function Scene.getMax(a, b: integer): integer;
begin
  if (a > b) then
    result := a
  else
    result := b;
end;
  
procedure Scene.handleCommand();
begin
  self.command := ReadKey(); // читаем символ из консоли
end;
  
function Scene.getCommand(): char;
begin
  result := self.command;
end;
  
  
  
// -- Реализация Animal -------
constructor Animal.create(skinValue, moveLeftChar, moveRightChar: char);
begin
  self.skin := skinValue;
  self.moveLeftChar := moveLeftChar;
  self.moveRightChar := moveRightChar;
  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;
// ---------------
var
  AnimalItem, // первое животное
    Dog       // второе животное
    : Animal;
  SceneItem: Scene;
begin
  AnimalItem := Animal.create('*', '1', '2');
  Dog := Animal.create('@', '3', '4');
  SceneItem :=  Scene.create(); // создаем сцену
  SceneItem.run(AnimalItem, Dog); // запускаем анимацию
  
  readln();
end.
-- перепроектируйте классы так, чтобы можно было двигаться на плоскости (в двумерном, а не одномерном пространстве):

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

Решение:

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

type
  Animal = class
    public
      constructor create(skinValue, moveLeftChar, moveRightChar: char);
      procedure drawFrame();
      procedure handleCommand(commandValue: char);
      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; virtual;
  end;

  D1Animal = class(Animal)// для перемешения по первой строчке

  end;

  D2Animal = class(Animal)// для перемешения в двумерном пространстве
    public
      constructor create(skinValue, moveUpChar, moveDownChar: char);
      procedure handleCommand(commandValue: char);
      function CurrentPositio(i,j: integer): boolean;
    protected
      moveUpChar: char;
      moveDownChar: char;
      upDownPosition: integer;
      function getNewPosition(commandValue: char): integer; override;
  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;

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

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
  writeln('Upravlenie: * - 1 2 ; @ - a d w s');
  maxPosition :=
   self.getMax(AnimalItem.getPosition(), SecondAnimal.getPosition());
   for j:= 1 to SecondAnimal.upDownPosition do
   begin
     for i:=1 to maxPosition do
     begin
       if (AnimalItem.isCurrentPosition(i)) OR (SecondAnimal.CurrentPositio(i,j)) then
       begin
         if (AnimalItem.isCurrentPosition(i))and(j = 1) then
           AnimalItem.drawFrame();
         if (SecondAnimal.CurrentPositio(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, moveLeftChar, moveRightChar: char);
begin
  self.skin := skinValue;
  self.moveLeftChar := moveLeftChar;
  self.moveRightChar := moveRightChar;
  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;

//  D2Animal
constructor D2Animal.create(skinValue, moveUpChar, moveDownChar: char);
begin
  self.skin := skinValue;
  self.moveUpChar := moveUpChar;
  self.moveDownChar := moveDownChar;
  self.moveLeftChar := 'a';
  self.moveRightChar := 'd';
  self.command := ' ';  // значение по умолчанию
  self.position := 1;
  self.upDownPosition := 1;
end;

procedure D2Animal.handleCommand(commandValue: char);
begin
  if(commandValue = 'a')or(commandValue = 'd') then
    self.position := self.getNewPosition(commandValue)
  else if (commandValue = 'w')or(commandValue = 's') then
    self.upDownPosition:= self.getNewPosition(commandValue);
end;

function D2Animal.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
  else
    if (commandValue = self.moveDownChar) then
      result := self.upDownPosition + 1
  else
    if ((commandValue = self.moveUpChar)AND (self.position > 1)) then
      result := self.upDownPosition - 1;
end;

function D2Animal.CurrentPositio(i,j: integer): boolean;
begin
  result := (i = self.position)and(j = self.upDownPosition);
end;

// ---------------
var
  AnimalItem: // первое животное
  D1Animal;
    Dog       // второе животное
    : D2Animal;
  SceneItem: D2Scene;
begin
  AnimalItem := D1Animal.create('*', '1', '2');
  Dog := D2Animal.create('@', 'w', 's');
  SceneItem :=  D2Scene.create(); // создаем сцену
  SceneItem.run(AnimalItem, Dog); // запускаем анимацию
  readln();
end.