Текущий архив: 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