uses crt,
     graph;
var  x1, x2, y1, y2, r1, r2,
     dx1, dy1, dx2, dy2, bgC: integer;
     Gd, Gm : integer;

procedure draw (x, y, r, c : integer);
begin
  setfillstyle(solidfill, c);
  fillellipse(x, y, r, r);
  Setcolor (c);
  circle (x, y, r);
end;

procedure escape (x, y, r, bgC : integer);
begin
  setfillstyle(solidfill, bgC);
  fillellipse(x, y, r, r);
  Setcolor (bgC);
  circle (x, y, r);

end;

procedure move (var x, y: integer; dx, dy :  integer);
begin
 x := x + dx;
 y := y + dy;
end;

procedure charge_on_oppositeX (var x, dx : integer);
begin
 dx := -dx;
 x := x + dx;
end;

procedure charge_on_oppositeY (var y, dy : integer);
begin
 dy := -dy;
 y := y + dy;
end;

Procedure border (var x, y: integer; r : integer; var dx, dy: integer);
begin
 if (x + r >= GetMaxX-1) or (x - r <= 1) then charge_on_oppositeX(x, dx);
 if (y + r >= GetMaxY-1) or (y - r <= 1) then charge_on_oppositeY(y, dy);
end;

begin
Gd := Detect;
InitGraph (Gd, Gm, '');
If GraphResult <> grOk then halt(1);
x1 := 50; y1 := 150;
x2 := 400; y2 := 300;
r1 := 30; r2 := 40;
dx1 := 20; dy1 := 15;
dx2 := 20; dy2 := 15;

bgC := 0;
rectangle (1,1, getMaxX - 1, getMaxY - 1);
repeat
begin
 draw (x1, y1, r1, white);
 draw (x2, y2, r2, red );
 delay(15100);
 escape (x1, y1, r1, bgC);
 escape (x2, y2, r2, bgC);
 border (x1, y1, r1, dx1, dy1);
 border (x2, y2, r2, dx2, dy2);
 move (x1, y1, dx1, dy1);
 move (x2, y2, dx2, dy2);
end;
until  keypressed;
readkey;
closegraph;
end.