Захотелось написать забавную задачку, но возникла проблемка при её реализации.
Задаются начальные координаты точки и её цвет, для нее генерится точка-цель. Точка устремляется к цели, причем на каждом шаге к координатам точки довешивается рандомное значение (назовем его заносом), лежащее в промежутке [-foo,foo]. Как только расстояние от точки до цели меньше половины заноса, задается новая цель и цвет и так далее.
Например, при foo = 0 точка просто движется к цели без всяких заносов.
Вот что у меня получилось:
uses crt,graph;
var gd,gm:integer;
x,y,dx,dy,v,w,color,foo:integer;
ch:char;
function Sign(x:integer):shortint;
begin
sign:=ord(x>0)-ord(x<0); {обычная сигнатура, люблю я её через ord'ы писать}
end;
begin gd:=Detect;
randomize;
initgraph(gd,gm,'');
foo:=0;
x:=0; {задание координат исходной точки}
y:=0;
v:=random(getmaxx+1); {задание координат точки-цели}
w:=random(getmaxy+1);
color:=random(15)+1;
moveto(x,y);
readln;
repeat;
setcolor(color);
lineto(x,y);
moveto(x,y);
delay(200);
dx:=random(2*foo+1)-foo; {генерация случайной составляющей движения}
dy:=random(2*foo+1)-foo; {рандом генерит значения в промежутке [-foo,foo]}
if (x+dx>getmaxx) or (x+dx<0) then dx:=-dx; {проверка выхода за границы экрана}
if (y+dy>getmaxy) or (y+dy<0) then dy:=-dy;
inc(x,dx+sign(v-x)); {устремление точки к цели за счет сигнатуры расстояния до цели + занос}
inc(y,dy+sign(w-y));
if (abs(v-x)<=(foo div 2)) and (abs(w-y)<=(foo div 2)) then {проверка достижения цели}
begin
color:=random(15)+1;
v:=random(getmaxx+1); {задание новой цели}
w:=random(getmaxy+1);
end;
if keypressed then begin {интерфейс}
ch:=readkey;
case ch of
'+':inc(foo);
'-':if foo>0 then dec(foo);
'0':foo:=0;
'c':begin
cleardevice;
moveto(x,y);
end;
end;
end;
until ch=#27;
closegraph;
end.
Ну, насколько я понимаю, http://forum.pascal.net.ru/index.php?s=&showtopic=5491&view=findpost&p=42527 должна тебе помочь? У тебя "цель" движется? В моей программе - погоня за движущейся целью...
Цель абсолютно неподвижна и меняется только после её достижения. Я не представляю, как мне использовать твою программу про зайца, потому как там нету все портящего случайного заноса.
Если бы заноса не было, то решение было б очевидно. Я бы перевел x и y в real и в момент задания цели вычислил бы скорость:
buf:=max(abs(v-x),abs(w-y)); {в буферную переменную закидываю длину бОльшего катета}
vx:=(v-x)/buf; {одна из скоростей стала бы равна единице}
vy:=(w-y)/buf;
x:=x+vx;
y:=y+vy;
есть смутная мысль...
если ты можешь реализовать y=x, то сможешь и y=2x, допустим?...
О, осенило! В моем случае достаточно лишь перерассчитывать эти vx и vy не только при задании новой цели, но и вообще на каждом витке цикла!
uses crt,graph;
var gd,gm:integer;
dx,dy,v,w,color,foo:integer;
x,y,buf:real;
ch:char;
function max(a,b:integer):integer;
begin
if a<=b then max:=b
else max:=a;
end;
function GetNew(z,limit:integer):integer; {вычисление отличной от текущей точки цели}
var buf:integer;
begin
repeat;
buf:=random(limit+1);
until buf<>z;
getnew:=buf;
end;
begin gd:=Detect;
randomize;
initgraph(gd,gm,'');
foo:=0;
x:=0;
y:=0;
v:=getnew(round(x),getmaxx);
w:=getnew(round(y),getmaxy);
color:=random(15)+1;
moveto(round(x),round(y));
readln;
repeat;
setcolor(color);
lineto(round(x),round(y));
moveto(round(x),round(y));
delay(200);
dx:=random(2*foo+1)-foo; {[-foo,foo]}
dy:=random(2*foo+1)-foo; {[-foo,foo]}
if (x+dx>getmaxx) or (x+dx<0) then dx:=-dx;
if (y+dy>getmaxy) or (y+dy<0) then dy:=-dy;
{кусок с проверкой достижения цели пришлось переставить выше
вычисления новых координат, ибо иначе могла вылезти ошибка "division by zero"}
if (abs(v-x)<=foo/2) and (abs(w-y)<=foo/2) then
begin
color:=random(15)+1;
x:=round(x);
y:=round(y);
v:=getnew(round(x),getmaxx);
w:=getnew(round(y),getmaxy);
end;
buf:=max(abs(v-round(x)),abs(w-round(y))); {сохраняем длину бОльшего катета}
x:=x+dx+(v-x)/buf;
y:=y+dy+(w-y)/buf;
if keypressed then begin
ch:=readkey;
case ch of
'+':inc(foo);
'-':if foo>0 then dec(foo);
'0':foo:=0;
'c':begin
cleardevice;
moveto(round(x),round(y));
end;
end;
end;
until ch=#27;
closegraph;
end.