Program gonki;
uses CRT,graph;
type STAR1=object
             x:0..640;
             y:0..480;
             c:0..15;
             V:boolean;
             constructor Init(x1,y1, c1:integer);
             Procedure On; virtual;
             Procedure Off; virtual;
             Procedure Drive(dX,dY:integer);
             Function GetX:integer;
             Function GetY:integer;
           end;

otr=object(STAR1)
    l:0..640;
    h:0..480;
    constructor Init(x1,y1,l1,h1,c1:integer);
             Procedure On;virtual;
             Procedure Off;virtual;
             Function Getl:integer;
             function geth:integer;
           end;

FLY=object(STAR1)
         r,t,cg:integer;
         constructor Init(x1,y1,t1,cg1,c1,r1:integer);
             Procedure On;virtual;
             Procedure Off;virtual;
             Procedure Move (dX,dy:integer);
             Function GetR:integer;
           end;
STAR2=object(STAR1)
        r:integer; d,f:integer;
              constructor Init(x1,y1,c1,r1,d1,f1:integer);
              Procedure On; virtual;
              Procedure Off; virtual;
              Procedure Drive(dX,dY:integer);
              Function GetR:integer;
          end;

STAR3=object(STAR1)
        z:0..600;      d,f:integer;
        w:0..465;
              constructor Init(x1,y1,z1,w1,d1,f1,c1:integer);
              Procedure On; virtual;
              Procedure Off; virtual;
              Procedure Drive(dX,dY:integer);
              Function GetZ:integer;
              Function GetW:integer;
          end;
Fly1=object(STAR1)
                 z:integer; d,f:integer;
                 constructor init(x1,y1,z1,d1,f1,c1:integer);
                 procedure on; virtual;
                 procedure off; virtual;
                 Procedure Move (dX,dy:integer);
                 function getz:integer;
               end;


PStar1=^Star1;  Potr=^otr;
PStar2=^Star2;
PStar3=^Star3;
PFly=^Fly;
PFly1=^Fly1;
Constructor Star1.Init(x1,y1,c1:integer);
begin
  x:=x1;
  y:=y1;
  V:=False;
  c:=c1;
end;

Procedure Star1.On;
begin
V:=true;
PutPixel(x,y,c);
end;

Procedure Star1.Off;
begin
PutPixel(x,y,0);
V:=False;
end;

Procedure Star1.Drive(dX,dY:integer);
begin
Off;
x:=x+dx;
y:=y+dy;
On;
end;

Function Star1.GetX:integer;
begin
 GetX:=x;
end;
Function Star1.GetY:integer;
begin
GetY:=Y;
end;

Constructor otr.Init(x1,y1,l1,h1,c1:integer);
begin
  Star1.Init(x1,y1,c1);
  l:=l1;
  h:=h1;
  V:=False;
end;

Procedure otr.On;
begin
V:=true;
SetColor(c);
line(x,y,l,h);
end;

Procedure otr.Off;
begin
SetColor(0);
line(x,y,l,h);
V:=False;
end;


Function otr.Getl:integer;
begin
 Getl:=l;
end;
Function otr.Geth:integer;
begin
Geth:=h;
end;


Constructor Star2.Init(x1,y1,c1,r1,d1,f1:integer);
begin
  Star1.Init(x1,y1,c1);
  r:=r1;         d:=d1; f:=f1;
  V:=False;
end;

Procedure Star2.On;
begin
V:=true;
Setfillstyle(d,c);
SetColor(c);
Circle(x,y,r);
Floodfill(x,y,f);
end;

Procedure Star2.Off;
begin
Setfillstyle(1,0);
SetColor(0);
Circle(x,y,r);
Floodfill(x,y,0);
V:=False;
end;

Procedure Star2.Drive(dX,dY:integer);
begin
Off;
x:=x+dx;
y:=y+dy;
On;
end;

Function Star2.GetR:integer;
begin
 GetR:=R;
end;


Constructor Star3.Init(x1,y1,z1,w1,d1,f1,c1:integer);
begin
  Star1.Init(x1,y1,c1);
  z:=z1;    d:=d1;
  w:=w1;          f:=f1;
  V:=False;
end;

Procedure Star3.On;
begin
V:=true;
Setfillstyle(d,c);
SetColor(c);
Rectangle(x,y,z,w);
Floodfill(x,y,f);
end;

Procedure Star3.Off;
begin
Setfillstyle(1,0);
SetColor(0);
Rectangle(x,y,z,w);
Floodfill(x,y,0);
V:=False;
end;

Procedure Star3.Drive(dX,dY:integer);
begin
Off;
x:=x+dx; z:=z+dx;
y:=y+dy; w:=w+dy;
On;
end;

Function Star3.GetZ:integer;
begin
 GetZ:=z;
end;
Function Star3.GetW:integer;
begin
GetW:=W;
end;

Constructor Fly.Init(x1,y1,t1,cg1,c1,r1:integer);
begin
  Star1.Init(x1,y1,c1);
  r:=r1;
  t:=t1;cg:=cg1;
  V:=False;
end;

Procedure Fly.On;
begin
V:=true;
Setfillstyle(t,c);
SetColor(c);
Circle(x,y,r);
Floodfill(x,y,cg);
end;

Procedure Fly.Off;
begin
Setfillstyle(1,0);
SetColor(0);
Circle(x,y,r);
Floodfill(x,y,0);
V:=False;
end;

Procedure Fly.Move(dX,dy:integer);
begin
Off;
x:=x+Dx;y:=y+dy;
On;
end;

Function Fly.GetR:integer;
begin
 GetR:=R;
end;

Constructor Fly1.init(x1,y1,z1,d1,f1,c1:integer);
begin
Star1.Init(x1,y1,c1);
z:=z1;d:=d1;f:=f1;
v:=false;
end;

procedure Fly1.on;
begin
v:=true;
Setfillstyle(d,c);
SetColor(c);
Circle(x,y,z);
Floodfill(x,y,f);
end;

procedure Fly1.off;
begin
v:=false;
Setfillstyle(1,0);
SetColor(0);
Circle(x,y,z);
Floodfill(x,y,0);
end;

Procedure Fly1.Move(dX,dy:integer);
begin
Off;
x:=x+Dx; y:=y+dy;
On;
end;

Function Fly1.getz:integer;
begin getz:=z; end;

procedure init(l1,h1,k1,q1,m1:integer);
var l,h,k,m,q:integer;    i:boolean;
begin
l:=l1; k:=k1;
h:=h1;       q:=q1;
m:=m1;
i:=false;
end;
Procedure On;
var i:boolean;     m,h,l,q,k:integer;
begin
i:=true;
SetColor(m);
line(l,h,k,q);
end;

Procedure Off;
var i:boolean;  k,q,h,l,m:integer;
begin
SetColor(0);
Rectangle(l,h,k,q);
i:=False;
end;

var OneStar1:PStar1;      oneotr:Potr;
    OneStar2,TwoStar2:PStar2;
    OneStar3,TwoStar3,ThreeStar3:PStar3;
    OneFly:PFly;
    OneFly1,TwoFly1,ThreeFly1,FourFly1:PFly1;
    S1:Star1;                 o:otr;
    S2,S21:Star2;
    S3,S31,S32:Star3;
    F:Fly;
    F1,F2,F3,F4:Fly1;
    s:integer;
function drag(var f:fly;var f1:fly1;var f2:fly1;var f3:fly1;var f4:fly1):boolean;
var key:char;
dx,dy:integer;
step,step1:integer;
begin
step:=5; step1:=5;
key:=readkey;
if key=chr(0) then key:=readkey;
dx:=0;   dy:=0;
case ord(key) of
75: dx:=-step;
77: dx:=step;
72: dy:=-step1;
80: dy:=step1;
27: begin drag:=false; exit end;
end;
f.move(dx,dy);f1.move(dx,dy);f2.move(dx,dy);f3.move(dx,dy);f4.move(dx,dy);
drag:=true;
end;

Function TEST(var S1:Star1;var S2,S21:Star2;var S3,S31,S32:Star3;var F:Fly):boolean;
begin
if (abs(S1.GetX-F.GetX)<F.GetR) and (abs(S1.GetY-F.GetY)<F.GetR) then TEST:=true;
if (abs(S2.GetX-F.GetX)<S2.GetR+F.GetR) and (abs(S2.GetY-F.GetY)<S2.GetR+F.GetR)
then TEST:=true;
if (abs(S3.GetX-F.GetX)<F.GetR) and (abs(S3.GetY-F.GetY)<F.GetR)
then TEST:=true;
if (abs(S3.GetZ-F.GetX)<F.GetR) and (abs(S3.GetW-F.GetY)<F.GetR)
then TEST:=true;
if (abs(S21.GetX-F.GetX)<S21.GetR+F.GetR) and (abs(S21.GetY-F.GetY)<S21.GetR+F.GetR)
then TEST:=true;
if (abs(S31.GetX-F.GetX)<F.GetR) and (abs(S31.GetY-F.GetY)<F.GetR)
then TEST:=true;
if (abs(S31.GetZ-F.GetX)<F.GetR) and (abs(S31.GetW-F.GetY)<F.GetR)
then TEST:=true;
if (abs(S32.GetX-F.GetX)<F.GetR) and (abs(S32.GetY-F.GetY)<F.GetR)
then TEST:=true;
if (abs(S32.GetZ-F.GetX)<F.GetR) and (abs(S32.GetW-F.GetY)<F.GetR)
then TEST:=true;
end;

Function drag1(var S1:Star1;var S2:Star2;var S3:Star3):boolean;
var i,dy,dx:integer;
    step,step1:integer;
begin
While S1.GetY<350 do
begin
step:=10;step1:=10;
dy:=step;dx:=step1;delay(5);
S1.drive(dx,dy);S2.drive(dx,dy);S3.drive(dx,dy); drag1:=true;
If TEST(S1,S2,S21,S3,S31,S32,F)=true then Drag1:=false;exit   end;
while S1.GetY>10 do
begin
step:=-480;step1:=-480;
dy:=step;dx:=step1;delay(10);
S1.drive(dx,dy);S2.drive(dx,dy);S3.drive(dx,dy); drag1:=true;
If TEST(S1,S2,S21,S3,S31,S32,F)=true then Drag1:=false;exit   end;
end;

Function drag2(var S21:Star2;var S31:Star3; var S32:Star3):boolean;
var i,dy,dx:integer;
    step,step1:integer;
begin
While S21.GetY<470 do
begin
step:=30;step1:=random(5)-5;
dy:=step;dx:=step1;delay(5);
S21.drive(dx,dy);S31.drive(dx,dy);S32.drive(dx,dy); drag2:=true;
If TEST(S1,S2,S21,S3,S31,S32,F)=true then Drag2:=false;exit   end;
while S21.GetY>10 do
begin
step:=-480;step1:=40;
dy:=step;dx:=step1;delay(10);
S21.drive(dx,dy);S31.drive(dx,dy);S32.drive(dx,dy); drag2:=true;
If TEST(S1,S2,S21,S3,S31,S32,F)=true then Drag2:=false;exit   end;
end;
Procedure Izo(S1:PStar1;S2,S21:PStar2;S3,S31,S32:PStar3;F:PFly;F1,F2,F3,F4:PFly1;o:potr);
var graphdriver:integer;
    graphmode:integer;
    errorcode,i:integer;

begin
 graphdriver:=detect;
 initgraph(graphdriver,graphmode,'d:\BP\bgi');
 errorcode:=graphresult;
 if errorcode<>grok then
   begin
   writeln('NOOOOOOOOOOOOOO ');
   halt;
   end;
   S1^.On;
   S2^.On;S21^.On;
   S3^.On;S31^.On; S32^.On;
   F^.On;
   F1^.On;F2^.On;F3^.On;F4^.On;o^.on;
readln;
 F^.Move(80,80);F1^.Move(80,80);F2^.Move(80,80);F3^.Move(80,80);F4^.Move(80,80);
 S1^.Drive(80,30);
 S2^.Drive(80,30);S21^.Drive(80,30); S32^.drive(80,30);
 S3^.Drive(80,30); S31^.Drive(80,30);S:=0;
 while (drag(F^,F1^,F2^,F3^,F4^)) and (drag1(S1^,S2^,S3^)) and (drag2(S21^,S31^,S32^)) do
 begin
 If TEST(S1^,S2^,S21^,S3^,S31^,S32^,F^)=true then clrscr else s:=s+1; end;
  CloseGraph;
 end;

begin
clrScr;
randomize;
New(OneStar1, Init(120,0,11));
New(OneStar2, Init(300,180,2,13,1,2));
New(OneStar3, init(120,120,130,100,1,1,1));
New(OneFly, init(300,300,1,15,15,20));
New(OneFly1, init(320,320,6,1,15,15));
New(TwoFly1, init(280,320,6,1,15,15));
New(ThreeFly1, init(320,280,6,1,15,15));
New(FourFly1, init(280,280,6,1,15,15));
New(TwoStar2, Init(120,420,9,13,1,9));
New(TwoStar3, init(400,300,425,320,1,14,14));
New(ThreeStar3, init(50,300,80,305,1,7,7));
New(oneotr, init(0,475,680,475,5));

Izo(OneStar1,OneStar2,TwoStar2,OneStar3,TwoStar3,ThreeStar3,OneFly,OneFly1,TwoFly1,ThreeFly1,FourFly1,oneotr);
textcolor(12);                               writeln;writeln; writeln;
writeln('                            ***IGRA OKONCHENA***');   writeln;writeln;textcolor(3);
writeln('                      ***proidenii vami put sostavlyaet: ',s,' km***');
readln;
end.