Программа


Program Bomber;
{ Имитатор системы бомбометания 
  реактивными снарядами }
Uses Crt,Graph;
Const MaxPoint=13; { Максимальный номер пункта меню }
      MaxString=33; { Максимальная длина строки меню }
      NumberParam=9; { Число параметров }
      ScaleY=4/3; { Соотношение сторон монитора }
      FileOfParam='Bomber'; { Внешний файл параметров }
Type MenuType=array[1..MaxPoint] of string[MaxString];  { Тип меню }
     ArrOfRel=array[1..NumberParam] of real; { Массив параметров }
Const MenuList:MenuType=('Скорость самолета',
                         'Высота самолета (координата Y)',
                         'Сила тяги ракеты ',
                         'Масса ракеты ',
                         'Коэффициент сопротивления воздуха',
                         'Положение цели (координата X)',
                         'Длина цели ',
                         'Высота цели ',
                         'Временной интервал расчетов',
                         'Загрузить параметры из файла  ',
                         'Сохранить параметры в файле   ',
                         'Имитатор',
                         'Выход   ');
Var Esc:boolean; { Булевская переменная для организации выхода из цикла }
    NumberOfMenu:byte; { Пункт меню }
    ParamArr:ArrOfRel; { Параметры имитатора }
procedure AutoSetParam(var Arr:ArrOfRel);
  { Определение параметров по умолчанию }
  Begin
    ParamArr[1]:=0.1;    { Скорость самолета }
    ParamArr[2]:=0.7;    { Высота самолета }
    ParamArr[3]:=0.01;   { Сила тяги ракеты }
    ParamArr[4]:=0.03;   { Масса ракеты }
    ParamArr[5]:=0.005;  { Коэффициент сопротивления воздуха }
    ParamArr[6]:=0.3;    { Положение цели }
    ParamArr[7]:=0.03;   { Длина цели }
    ParamArr[8]:=0.03;   { Высота цели }
    ParamArr[9]:=0.02    { Приращение времени }
  End;
procedure Menu(Var PointNumber:byte;Change:boolean;
               MenuList:MenuType);
{ При PointNumber=255 выводит все меню и устанавливает PointNumber=11,
  при другом значении - поднимает или опускает PointNumber в зависимости
  от Change }
  var i:integer; { Счетчик }
  procedure ShowPoint(PointNumber:byte;Show:boolean);
  { Выделяет или снимает выделение пункта меню }
    begin
      if Show then HighVideo;{ Установка высокой яркости выводимых символов }
      GoToXY(1,PointNumber);  { Установка курсора на первый символ текущего
                                пункта меню }
      write(MenuList[PointNumber]); { Вывод пункта меню }
      if PointNumber in [1..NumberParam]  { Если текущему пункту меню
                                              соответствует параметр }
        then   { то вывод параметра }
          begin
            GoToXY(MaxString+1,PointNumber); { Установка курсора }
            write(ParamArr[PointNumber])    { Вывод параметра }
          end;
      NormVideo { Установка нормальной яркости выводимых символов }
    end;
  Begin
    if PointNumber=255 { Если при вызове процедуры указан номер пункта 255 }
      then begin       { то вывод всего меню }
             ClrScr;  { Очистка экрана }
             for i:=1 to MaxPoint do
               begin  { Вывод полного меню с параметрами }
                 GoToXY(1,i);  { Установка курсора на первый символ пункта }
                 write(MenuList[i]); { Вывод пункта меню }
                 if i in [1..NumberParam ] { Если текущему пункту
                                               соответствует параметр,
                                               то вывод параметра }
                   then
                     begin
                       GoToXY(MaxString+1,i); { Установка курсора }
                       write(ParamArr[i])     { Вывод параметра }
                     end;
               end;
             PointNumber:=12; { Установка пункта меню }
             ShowPoint(PointNumber,true); { Подсветка пункта }
           end
      else begin  { изменение состояния меню }
             ShowPoint(PointNumber,false); { Гашение текущего пункта }
             if Change { Выбор переопределения состояния меню по Change }
                       then begin    { Сдвиг вниз }
                              PointNumber:=PointNumber+1;
                              if PointNumber>MaxPoint then PointNumber:=1
                            end
                       else begin    { Сдвиг вверх }
                              PointNumber:=PointNumber-1;
                              if PointNumber<1 then PointNumber:=MaxPoint
                            end;
              ShowPoint(PointNumber,true)    { Подсветка пункта }
           end
  End;
procedure ChangeParam(NumberOfMenu:integer;var Param:real);
{ Изменение параметра }
  var P:real; { Переменная для ввода параметра }
  Begin
    GoToXY(MaxString+1,NumberOfMenu);
    { Установка курсора на первый символ параметра }
    ClrEol; { Очистка строки с положения курсора до конца строки }
    {$I-}{ Выключение проверки ошибок ввода-вывода }
    read(P); { Чтение параметра }
    {$I+}{ Включение проверки ошибок ввода-вывода }
    if IOResult=0 then Param:=P;
    { Если нет ошибки ввода-вывода то установка параметра }
    HighVideo; { Установка высокой яркости выводимых символов }
    GoToXY(MaxString+1,NumberOfMenu); { Помещение курсора в начало параметра }
    write(Param); { Вывод параметра }
    NormVideo  { Установка первоначальной яркости }
  End;
procedure LoadParam(var Arr:ArrOfRel); { Загрузка параметров из файла }
  var Arr2:ArrOfRel;{ Буфер для предотвращения потери установленых
                      параметров при считывании файла параметров }
      F:file of real; { Файловая переменная }
      i:integer;  { Счетчик }
      Flag:boolean; { Переменная для фиксирования ошибок ввода-вывода }
  Begin
    {$I-}{ Выключение проверки ошибок ввода-вывода }
    Assign(F,FileOfParam);
    { Связывание файловой переменной с файлом параметров }
    Reset(F); { Открытие файла для чтения }
    Flag:=IOResult=0;  { Проверка корректности операций с файлом }
    if Flag then  { Если нет ошибки ввода-вывода, то }
              begin { чтение параметров }
                for i:=1 to NumberParam do begin
                          { Чтение параметра } read(F,Arr2[i]);
        { Проверка корректности ввода-вывода } Flag:=Flag and (IOResult=0)
                                             end;
                Flag:=Flag and Eof(F); { Проверка достижения конца файла }
                Close(F) { Закрытие файла }
              end;
    {$I+}{ Включение проверки ошибок ввода-вывода }
    if Flag then begin { Если не было ошибок при работе с файлом, то }
                   Arr:=Arr2;  { переопределение массива параметров, }
                   for i:=1 to NumberParam do begin { вывод параметров }
       { Помещение курсора в первую позицию }
       { параметра соответствующего пункта меню } GoToXY(MaxString+1,i);
                       { Вывод элемента массива } write(Arr[i])
                                                end
                 end
            else begin  { иначе оформление аварийной ситуации }
                   Sound(800); { Включение звука }
                   GotoXY(MaxString,NumberOfMenu);
                   { Помещение курсора в конец текущего пункта меню }
                   HighVideo;{ Установка высокой яркости выводимых символов }
                   write('ОШИБКА ЧТЕНИЯ ФАЙЛА');{ Вывод сообщения об ошибке }
                   NormVideo;
                   { Установка первоначальной яркости выводимых символов }
                   GoToXY(MaxString,NumberOfMenu);
                   { Помещение курсора в конец текущего пункта меню }
                   Delay(1000); { Задержка программы 1 сек.}
                   NoSound;  { Выключение звука }
                   ClrEol;  { Очистка строки от курсора }
                 end
  End;
procedure SaveParam(Arr:ArrOfRel); { Сохранение параметров }
  var i:integer;  { Счетчик }
      F:file of real; { Файловая переменная }
  Begin
    {$I-}{ Выключение проверки ошибок ввода-вывода }
    Assign(F,FileOfParam); { Связь файловой переменной с файлом }
    Rewrite(F); { Открытие файла под запись }
    {$I+}{ Включение проверки ошибок ввода-вывода }
    if IOResult=0  { Если не было ошибок при открытии файла, }
      then begin   { то }
             for i:=1 to NumberParam do write(F,Arr[i]);
             { Запись параметров в файл }
             Close(F) { Закрытие файла }
           end
      else begin  { иначе оформление аварийной ситуации }
             Sound(800); { Включение звука }
             GotoXY(MaxString,NumberOfMenu);
             { Помещение курсора в конец текущего пункта меню }
             HighVideo;{ Установка высокой яркости выводимых символов }
             write('ОШИБКА НА ДИСКЕ');{ Вывод сообщения об ошибке }
             NormVideo;
             { Установка первоначальной яркости выводимых символов }
             GoToXY(MaxString,NumberOfMenu);
             { Помещение курсора в конец текущего пункта меню }
             Delay(1000); { Задержка программы 1 сек.}
             NoSound;  { Выключение звука }
             ClrEol;  { Очистка строки от курсора }
           end
    {$I+}{ Включение проверки ошибок ввода-вывода }
  End;
procedure Work(vPlane,yPlane,F,m,k,xTarget,lTarget,hTarget,dt:real);
  const DriverPath='';  { Путь к графическому драйверу }
        hPlane=0.02;   { Высота самолета }
        lPlane=0.05;   { Длина самолета }
        AngleStep=Pi/12;  { Шаг поворота }
        g=-0.00981;      { Ускорение свободного падения }
  var GraphDriver,GraphMode:integer; { Графический драйвер и режим }
      Ch:char; { Переменная для обработки клавиатуры }
      X,Y,X1,Y1,X2,Y2:real; { Координаты бомбы }
      Angle,Angle1,Angle2:real; { Угол наклона }
      lBomb:real; { Длина бомбы }
      Vx,Vy:real; { Скорости бомбы }
      Ax,Ay:real; { Ускорения бомбы }
      xPlane,xPlane1,xPlane2:real; { Координаты самолета }
      Bomb,Page:boolean;  { Флаг "Бомба в полете" и селектор видеостраниц }
      BombInt:integer;  { Счетчик для прорисовки взрыва }
      i:integer;  { Служебный счетчик }
  Procedure SP;{ Переключение отображаемой и активной видеостраниц }
    Begin
      if Page then begin
                     SetActivePage(1);
                     SetVisualPage(0)
                   end
              else begin
                     SetActivePage(0);
                     SetVisualPage(1)
                   end;
      Page:=not Page { Переустановка флага }
    End;
  Begin { Work }
    GraphDriver:=Detect; { Автоматическое определение драйвера }
    GraphMode:=0;  { Зказ наименее емкого видеорежима }
    InitGraph(GraphDriver,GraphMode,DriverPath); { Инициализация графики }
    Page:=false; { Установка селектора видеостраниц }
    xPlane:=1; { Определение начального положения самолета }
    xPlane1:=xPlane; { Определение предыдущего положения самолета }
    X:=xPlane; { Определение координат бомбы (под самолетом) }
    Y:=yPlane-hPlane/2-0.01;
    X1:=X; { Определение предыдущих координат бомбы }
    Y1:=Y;
    Bomb:=false;  { Определение состояния бомбы }
    BombInt:=0;  { Определение счетчика для прорисовки взрыва }
    lBomb:=lPlane; { Определение длины бомбы }
    Angle:=Pi; { Определение начального угла наклона бомбы }
    Angle1:=Angle;  { Определение предыдущего угла }
    for i:=1 to 2 do { Прорисовка цели в двух видеостраницах }
      begin
        SP; { Переключение видеостраниц }
        Bar(Round((xTarget-lTarget/2)*GetMaxX),
            Round((1-hTarget*ScaleY)*GetMaxY),
            Round((xTarget+lTarget/2)*GetMaxX),Round(GetMaxY))
      end;
    repeat
      SP; { Переключение видеостраниц }
      xPlane2:=xPlane1; { Сохранение предыдущих координат }
      xPlane1:=xPlane;
      if xPlane>-lPlane/2  { Если самолет не достиг левого края экрана }
        then xPlane:=xPlane-vPlane*dt { то - пересчет координаты по скорости }
        else xPlane:=1+lPlane/2; { иначе - перенос вправо }
      X2:=X1; { Сохранение координат бомбы }
      X1:=X;
      Y2:=Y1;
      Y1:=Y;
      if Bomb    { Если бомба в полете }
        then     { то пересчет координат дифференциальным формулам }
          begin
            if (X>0)and(X<1)and(Y>0)and(Y<0.75)
                                     { Если бомба в пределах экрана }
              then                   { то }
                begin  { пересчет скоростей и координат }
{                  Vx:=Vx+(F*Cos(Angle)-k*Vx*Abs(Vx*Cos(Angle)))*dt/m;
                  Vy:=Vy+(-g+(F*Sin(Angle)-k*Vy*Abs(Vy*Sin(Angle)))/m)*dt; }
                  Ax:=(F*Cos(Angle)-k*Vx*abs(Vx)
                      +(k*50)*Vy*abs(Vy)*Cos(Angle)*Sin(Angle))/m ;
                  Ay:=g+(F*Sin(Angle)-k*Vy*abs(Vy)
                      +(k*50)*Vx*abs(Vx)*Cos(Angle)*Sin(Angle))/m;
                  Vx:=Vx+Ax*dt;
                  Vy:=Vy+Ay*dt;
                  X:=X+Vx*dt;
                  Y:=Y+Vy*dt
                end
              else Bomb:=false; { иначе - сброс флага "бомба в полете" }
            if Sqrt(Sqr(X-xTarget)+Sqr(Y-hTarget/2))<0.1 then
              { Если бомба попала в цель, то}
              begin
                Bomb:=false; { сброс флага "бомба в полете" }
                BombInt:=4 { определение счетчика для прорисовки взрыва }
              end
          end
        else { иначе переопределение координат по самолету }
          begin
            X:=xPlane;
            Y:=yPlane-hPlane/2-0.01;
            Angle:=Pi
          end;
      SetColor(Black);  { Установка черного цвета }
      SetFillStyle(SolidFill,Black);
      { Установка однородного заполнения фигур черным цветом }
      Bar(Round((xPlane2-lPlane/2)*GetMaxX),
          Round((1-(yPlane+hPlane/2)*ScaleY)*GetMaxY),
          Round((xPlane2+lPlane/2)*GetMaxX),
          Round((1-(yPlane-hPlane/2)*ScaleY)*GetMaxY));
          { Закрашивание предыдущего изображения самолета  }
      Line(Round((X2+lBomb/2*Cos(Angle2))*GetMaxX),
           Round((1-(Y2+lBomb/2*Sin(Angle2))*ScaleY)*GetMaxY),
           Round((X2-lBomb/2*Cos(Angle2))*GetMaxX),
           Round((1-(Y2-lBomb/2*Sin(Angle2))*ScaleY)*GetMaxY));
           { Закрашивание предыдущего положения бомбы }
      if BombInt in [1..2] then  { Закрашивание взрыва }
        PieSlice(Round(xTarget*GetMaxX),GetMaxY,0,180,100);
      SetColor(White); { Установка белого цвета }
      SetFillStyle(SolidFill,White);
      { Установка однородного заполнения фигур белым цветом }
      Bar(Round((xPlane-lPlane/2)*GetMaxX),  { Прорисовка самолета }
          Round((1-(yPlane+hPlane/2)*ScaleY)*GetMaxY),
          Round((xPlane+lPlane/2)*GetMaxX),
          Round((1-(yPlane-hPlane/2)*ScaleY)*GetMaxY));
      Line(Round((X+lBomb/2*Cos(Angle))*GetMaxX), { Прорисовка бомбы }
           Round((1-(Y+lBomb/2*Sin(Angle))*ScaleY)*GetMaxY),
           Round((X-lBomb/2*Cos(Angle))*GetMaxX),
           Round((1-(Y-lBomb/2*Sin(Angle))*ScaleY)*GetMaxY));
      if BombInt in [1..2] then Bar(Round((xTarget-lTarget/2)*GetMaxX),
                                    Round((1-hTarget*ScaleY)*GetMaxY),
                                    Round((xTarget+lTarget/2)*GetMaxX),
                                    Round(GetMaxY)); { Прорисовка цели }
      if BombInt in [3..4] then { Прорисовка взрыва }
        PieSlice(Round(xTarget*GetMaxX),GetMaxY,0,180,100);
      if BombInt in [1..4] then BombInt:=BombInt-1;
      { Подсчет кадров прорисовки взрыва }
      Angle2:=Angle1;  { Сохранение угла }
      Angle1:=Angle;
      if KeyPressed            { Если нажата клавиша }
        then Ch:=ReadKey       { то чтение буфера клавиатуры }
        else Ch:=' ';          { иначе сброс символа клавиатуры }
      case Ch of  { Определение действия по нажатой клавише }
        #72:if Bomb then Angle:=Angle+AngleStep;
            { Увеличение угла наклона бомбы }
        #80:if Bomb then Angle:=Angle-AngleStep;
            { Уменьшение угла наклона бомбы }
        #13:if not Bomb then  { Если бомба не в полете, то }
              begin
                Bomb:=true;   { Подьем флага "бомба в полете" }
                Angle:=Pi;     { Переопределение начальногоугла }
                Vx:=-vPlane;  { Определение начальной скорости }
                Vy:=0;
              end
      end
    until Ch=#27;  { Выход по Esc }
    CloseGraph { Закрытие графики }
  End; { Work }
BEGIN
  ClrScr; { Очистка экрана }
  AutoSetParam(ParamArr);{ Определение начальных параметров модели }
  NumberOfMenu:=255; { Определение параметра для вывода меню }
  Menu(NumberOfMenu,true,MenuList); { Вывод главного меню }
  Esc:=false; { Определение флага выхода }
  repeat
    case ReadKey of  { Чтение клавиатуры и выбор действия }
      #72:Menu(NumberOfMenu,false,MenuList); { Движение по меню вверх }
      #80:Menu(NumberOfMenu,true,MenuList);  { Движение по меню вниз }
      #13:case NumberOfMenu of  { Действие, определенное состоянием меню }
          1..9:ChangeParam(NumberOfMenu,ParamArr[NumberOfMenu]);
               { Изменение параметра модели }
            10:LoadParam(ParamArr); { Загрузка параметров модели из файла }
            11:SaveParam(ParamArr); { Сохранение параметров модели в файле }
            12:begin  { Запуск модели }
                 Work(ParamArr[1],ParamArr[2],ParamArr[3],ParamArr[4],
                      ParamArr[5],ParamArr[6],ParamArr[7],ParamArr[8],
                      ParamArr[9]);
                 NumberOfMenu:=255; { Определение параметра для вывода меню }
                 Menu(NumberOfMenu,true,MenuList) { Вывод  меню }
               end;
            13:Esc:=true { Определение флага "выход" }
          end;
      #27:Esc:=true  { Определение флага "выход" }
    end { case }
  until Esc  { Выход }
END.


Бесплатные примеры программ
Примеры написанных программ
Помощь студентам по программированию