Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.04.10;
Скачать: CL | DM;

Вниз

Вызов процедуры из самой себя   Найти похожие ветки 

 
pavel_k   (2003-03-28 19:16) [0]

Есть процедура
procedure MyFunc(x,y)
begin
...........
end;

КАК сделать, чтобы в теле этой процедуры можно было вызвать ее же? То есть эта функция должна вызывать себя с другими параметрами, например MyFunc(x+1,y); MyFunc(x,y+1); Как это реализовать? (Просто так не получается - ошибка, что-то вроде "Stack overflow").


 
Mike Kouzmine   (2003-03-28 19:18) [1]

Нужно ограничение на рекурсию


 
Романов Р.В. ©   (2003-03-28 19:19) [2]

Организуй выход из этой процедуры при определенных параметрах


 
pavel_k   (2003-03-28 19:19) [3]

А можете объяснить конкретнее, что нужно сделать?


 
Романов Р.В. ©   (2003-03-28 19:21) [4]

Покажи сначала что ты делаешь


 
mrcat ©   (2003-03-28 19:21) [5]

Купить три пакета!!! (с)


 
pavel_k   (2003-03-28 19:30) [6]

Вот код процедуры

procedure OpenMany(x, y: integer);
Var i,j:integer;
begin
if (not x in [0..9]) or (not y in [0..9]) then exit;
if (Table[x,y].number<>0) or (Table[x,y].Typ) then
exit;
i:=x;
j:=y;
if (j+1) in [0..9] then
begin
Table[i,j+1].Isopen:=True;
if (i+1) in [0..9] then
Table[i+1,j+1].Isopen:=True;
if (i-1) in [0..9] then
Table[i-1,j+1].Isopen:=True;
end;
if (j-1) in [0..9] then
begin
Table[i,j-1].Isopen:=True;
if (i+1) in [0..9] then
Table[i+1,j-1].Isopen:=True;
if (i-1) in [0..9] then
Table[i-1,j-1].Isopen:=True;
end;
if (i+1) in [0..9] then
Table[i+1,j].Isopen:=True;
if (i-1) in [0..9] then
Table[i-1,j].Isopen:=True;
//*************************************

OpenMany(i+1,j);
OpenMany(i,j+1);
.....

end;

Table - массив:


Table:array [0..9,0..9] of TKo;

TKo=record
Typ:boolean;
Isopen:boolean;
PlPom:TPlPom;
number:integer;
end;



Надо, чтобы часть процедуры до звездочек выполнялась для каждого соседнего элемента, если его number=0.(Это проверяется в начале процедуры.).


 
Palladin ©   (2003-03-28 19:31) [7]


> pavel_k (28.03.03 19:16)

ну бежит у тебя эта процедура по какому то полю...
проверяй на верность координат
и сразу же выходи...
if (x<0) or (y<0) or (x>maxx) or (y>maxy) then exit;

естественно без проверки можно бежать до бесконечности...
что в принципе и делается пока стек не переполнится...


 
pavel_k   (2003-03-28 19:38) [8]

>Palladin
А разве не этим занимается строка:

if (not x in [0..9]) or (not y in [0..9]) then exit;

. Если что, извините за глупость, но на "рекурсию" я в первый раз попал...


 
Palladin ©   (2003-03-28 19:43) [9]

not x - глупость!

если уж делать как ты, то
if (not (x in [0..9])) and (not (y in [0..9])) then exit;



 
pavel_k   (2003-03-28 19:47) [10]


Ну я считал, что это не принципиально, хотя имел в виду написанное Palladin. За расстановку скобок - извините, но разве ошибка в этом?


 
Palladin ©   (2003-03-28 19:51) [11]

ты попробуй, а потом расскажи результат...

то что написал я и то что написал ты кардинально различаеся


 
pavel_k   (2003-03-28 19:53) [12]

Если бы это различалось принципиально - компилятор бы сказал (я думаю), т.к. not x - действительно глупость при x:integer. Но щас попробую...


 
Palladin ©   (2003-03-28 19:58) [13]

как ты думаешь чему будет равна переменная a?

var
c,
a:byte;
begin
c:=1;
a:=not c;
end;


 
pavel_k   (2003-03-28 19:59) [14]

Ошибка продолжает вылетать...
Что же делать???


 
Anatoly Podgoretsky ©   (2003-03-28 20:00) [15]

pavel_k (28.03.03 19:53)
Для компилятора это не глупость, а вполне нормальное утверждение.


 
Palladin ©   (2003-03-28 20:02) [16]

ну я баран
if (not (x in [0..9])) or (not (y in [0..9])) then exit;


 
pavel_k   (2003-03-28 20:04) [17]

>Palladin (28.03.03 19:58)
Извиняюсь, в этом вы правы, но видимо компилятор понял, что я имел в виду:).
Но что ему нехватает для счастья????


 
Anatoly Podgoretsky ©   (2003-03-28 20:07) [18]

упрощенная запись if not ((x in [0..9]) and (y in [0..9])) then exit;


 
pavel_k   (2003-03-28 20:08) [19]

>Palladin (28.03.03 20:02)
У меня так и есть, там стоит "or", все в скобках. В чем проблема???


 
Palladin ©   (2003-03-28 20:08) [20]


> pavel_k (28.03.03 20:04)

нет, компилятор понял подругому нежеле чем ты...

он сначала инвертировал x и потом проверил на вхождение в дапазон...


 
pavel_k   (2003-03-28 20:10) [21]

>Anatoly Podgoretsky (28.03.03 20:07)
Вы думаете, это из-за того, что у меня "усложненная" запись?


 
Palladin ©   (2003-03-28 20:10) [22]


> pavel_k (28.03.03 20:08)

сделай либо как Anatoly Podgoretsky © (28.03.03 20:07) либо как Palladin © (28.03.03 19:31)


 
pavel_k   (2003-03-28 20:15) [23]

>Palladin (28.03.03 20:10)
Испробовал оба варианта, ТА ЖЕ ФИГНЯ...
А может ошибка не в этой строке???
Я вообще незнаком с рекурсией, может после названия процедуры recurs; написать или что-нибудь в этом роде?:))


 
Palladin ©   (2003-03-28 20:20) [24]


> pavel_k (28.03.03 20:15)

это невозможно...
максимально возможных 10 вызовов, стек выдержит...


 
pavel_k   (2003-03-28 20:26) [25]

Вызовов возможно немного больше...
Проверял я с таким вариантом


.....
//***************
OpenMany(i+1,j);




В рабочем варианте будет Восемь вызовов (для всех соседних клеток), причем каждый из вызовов может повлечь еще...
Но в конечном этоге не должно быть больше 100.


 
pavel_k   (2003-03-28 20:29) [26]

У меня есть предположение:
Может один элемент вызывает процедуру для всех соседних, а любой из соседних вызывает эту процедуру для начальной клетки, что ведет к бесконечному циклу...

Может ли такое быть и как этого избежать...


 
Palladin ©   (2003-03-28 20:30) [27]

а ты уверен что у тебя сейчас все еще Stack overflow?


 
pavel_k   (2003-03-28 20:32) [28]

>Palladin © (28.03.03 20:30)
Да, я уверен, но от этого не легче...


 
Palladin ©   (2003-03-28 20:36) [29]

короче
procedure OpenMany(x, y: integer);
begin
if (not ((x in [0..9]) and (y in [0..9]))) or
(Table[x,y].number<>0) or
(Table[x,y].Typ) or
(Table[x,y].IsOpen) then exit;
Table[x,y].IsOpen:=True;
//*************************************
OpenMany(x-1,y-1);
OpenMany(x,y-1);
OpenMany(x+1,y-1);
OpenMany(x-1,y);
OpenMany(x+1,y);
OpenMany(x-1,y+1);
OpenMany(x,y+1);
OpenMany(x+1,y+1);
end;

я так понимаю это сапер...


 
Anatoly Podgoretsky ©   (2003-03-28 21:00) [30]

pavel_k (28.03.03 20:10)
Не не думаю и не вижу основания для переполнения стека, предел рекурсии 100, всего черыре переменных, плюс адрес возврата, сущая мелочь.
Для облегчения поиска сделай записиь в лог при входе в процедуру значений x,y поможет в трассировке.


 
pavel_k   (2003-03-28 21:03) [31]

Да, вы совершенно правы, это сапер...
Спасибо всем за огромную помощь, проблема решена с помощью небольшого видоизменения процедуры от Palladin © (28.03.03 20:36). В скором времени выложу в кладовку...


 
Anatoly Podgoretsky ©   (2003-03-28 21:07) [32]

Ну так и сказал бы в чем была проблема, все таки люди время потратили.


 
pavel_k   (2003-03-28 21:14) [33]

Ну если бы я знал в чем была проблема...


 
Anatoly Podgoretsky ©   (2003-03-28 21:16) [34]

Ну тогда приведи работающий кусок


 
pavel_k   (2003-03-28 21:27) [35]

procedure OpenMany(x, y: integer);
begin
if (not ((x in [0..9]) and (y in [0..9]))) or
(Table[x,y].IsOpen) then exit;
Table[x,y].IsOpen:=True;
//*************************************
if (Table[x,y].number<>0) then exit;
OpenMany(x-1,y-1);
OpenMany(x,y-1);
OpenMany(x+1,y-1);
OpenMany(x-1,y);
OpenMany(x+1,y);
OpenMany(x-1,y+1);
OpenMany(x,y+1);
OpenMany(x+1,y+1);
end;

Процедура вызова сменилась с:

Table[i,j].Isopen:=True;
PlaySound((PChar(extractfilepath(paramstr(0))+"Sound\Click.wav")),0,SND_ASYNC);
OpenMany(i,j);

на

PlaySound((PChar(extractfilepath(paramstr(0))+"Sound\Click.wav")),0,SND_ASYNC);
OpenMany(i,j);



Страницы: 1 вся ветка

Текущий архив: 2003.04.10;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.027 c
3-30289
Наташа
2003-03-22 13:56
2003.04.10
выбор транзакции.


14-30588
Интересующийся
2003-03-25 20:43
2003.04.10
Операции AND и OR


4-30647
Pakshin A. S.
2003-02-11 11:53
2003.04.10
Очистка корзины...


14-30522
RDA
2003-03-23 21:37
2003.04.10
Для жителей Украины работающих с казначейством


1-30451
Lexa
2003-03-28 23:47
2003.04.10
Как убрать мерцание?