SRL Archive - OSR Help

Recursive calls


blackfire553

2011-06-15 16:50:41

Should i try to avoid recursive calls? I could break this code up into several procedures but it works fine with recursion.


procedure GetFight;
var
NPC : TNPC;
NPCPoint : TPoint;
i,j,tries,checkFight : integer;
begin
if not (LoggedIn) then
Exit;
if FindNPC(Players[0].Strings[0],NPC) = false then
begin
writeln('no mobs');
wait(3000);
GetFight;
Exit;
end;
If (NPC.Interacting = -1) then
begin
NPCPoint := TileToMS(NPC.Tile,NPC.Height*3/4);
if (NPCPoint.x <> -1) then
begin
Mouse(NPCPoint.x,NPCPoint.y,3,3,false);
ChooseOption('ttack');
writeln(IntToStr(NPCPoint.x) + ' ' + IntToStr(NPCPoint.y));
writeln(IntToStr(NPC.ID));
writeln(NPC.Name);
wait(3000);
Me := GetMe;
if (Me.Interacting <> -1) then
begin
writeln('Got a fight');
Exit;
end;
GetFight;
Exit;
end;
end;
end;

edit: i am going to add some way for it to log out after it fails enough times so it doesnt loop for 24.5 years

i luffs yeww

2011-06-15 17:56:33

Recursion is far slower than iteration. In my opinion it should be avoided in almost any circumstance.

masterBB

2011-06-15 18:02:23

Don't use them. It would only make things harder for yourself. It can easily avoided here anyway.

Sabzi

2011-06-15 18:03:54

From: i luffs yeww
Recursion is far slower than iteration. In my opinion it should be avoided in almost any circumstance.


I was like this nearly a year ago on my programming test(I can't say it better in English, but it's not a simple test) and I made the task with iteration with lots of lines compared to the 3 liner recursive method XD.(there was not only 1 task; on paper)
So recursion is not something to avoid at all cost, but iteration is certainly better most cases just as Ian said.
Thought I may share this.

blackfire553

2011-06-15 18:31:30

whenever i iterate through a list of NPCs, by the time i get to the second or third NPC they have moved, is there any way to update their positions without losing track of the order?

masterBB

2011-06-15 18:45:49

No, but I'm writing a working piece of code for you.

Could you try this? Haven't test it yet.
procedure GetFight;
var
NPCS:TNPCArray;
NPC : TNPC;
NPCPoint : TPoint;
nrOfNpcs,i,tries,functionTries,x,y: integer;
begin
if not (LoggedIn) then
Exit;
functionTries := 0;

repeat
NPCS := GetNPCs(Players[0].Strings[0]);
tries := 0;
while(Length(NPCS)>0) do
begin
Inc(tries);
if(tries > 10) then
Exit;
Wait(3000+random(1000));
Writeln('no mobs');
NPCS := GetNPCs(Players[0].Strings[0]);
end;

for i := 0 to High(NPCS) do
if(NPCS[i].Interacting <> -1) then
begin
NPCPoint := TileToMS(NPCS[i].Tile,NPCS[i].Height*3/4);
if(NPCPoint.x <> -1) then
begin
MMouse(NPCPoint.x,NPCPoint.y,3,3));
if not(r_WaitUpTextMulti(['tack','options'],500))then
Break;
Mouse(x,y,0,0,false);
if not(ChooseOption('ttack')) then
Break;
Wait(3000+random(1000));
Me := GetMe;
if(Me.InterActing <> -1) then
begin
Result := True;
Exit;
end;
end;
end;
until(functionTries > 3);
end;

Capricorn

2011-06-15 19:01:26

I don't think you'd want to be using recursive functions in a language like PS.

Iamadam

2011-06-15 19:06:25

Meh, I'm a fan of recursion - speed is unimportant in functions like that because the speed of reflection is the limiting factor.

Richard

2011-06-15 19:07:14

From: i luffs yeww
Recursion is far slower than iteration. In my opinion it should be avoided in almost any circumstance.


Apart from at considerable depths of recursion, they compilation times aren't actually that notable (or at least not with data this small).

I ran a recursive factorial algorithm in Python to a depth of 985 and it ran within about 5 seconds (bearing in mind I was using a VERY slow PC. Can't really make a comparison with PS because you can't have integers over 64bits, so you're quite limited in that respect.

i luffs yeww

2011-06-15 19:26:59

The time it takes is exponential, so I'd say it is quite relevant, even with small amounts of data. A very simple recursive Fibonacci function vs a simple iterative counterpart can really prove my point, in my opinion.

http://shiman.wordpress.com/2008/05/28/recursion-vs-iteration/

Iamadam

2011-06-15 20:17:24

2 Things:
N = 5, recursive = 5 ticks, iterative = 9 ticks.


This function is likely to not be called more than 5 times, so according to this info, would actually be _faster_ using the recursive method.

Second:
Q: Then why use recursion??
A: It makes the code beautiful ***8211; recursion is a beauty of programming. Sometimes it is much simpler to write the recursive version.


Anyway, in this context it would make no difference. Just make sure you have a break out clause.

Richard

2011-06-15 20:27:12

From: i luffs yeww
The time it takes is exponential, so I'd say it is quite relevant, even with small amounts of data. A very simple recursive Fibonacci function vs a simple iterative counterpart can really prove my point, in my opinion.

http://shiman.wordpress.com/2008/05/28/recursion-vs-iteration/


Not entirely sure what a "tick" is in their terms, but I've just been running some factorials in java, up to 21, and I've yet to see it go over 1ms, which to me is sufficiently efficient.

EDIT: To the above, Recursion just shows you're more awesome

i luffs yeww

2011-06-15 20:38:30

I still disagree about using recursion. But whatever. Don't care to really argue about bad practice on my phone. :p

Richard

2011-06-15 20:48:07

From: i luffs yeww
I still disagree about using recursion. But whatever. Don't care to really argue about bad practice on my phone. :p


You have to agree with recursion, it's in SRL's name!

Capricorn

2011-06-15 23:28:43

From: i luffs yeww
The time it takes is exponential, so I'd say it is quite relevant, even with small amounts of data. A very simple recursive Fibonacci function vs a simple iterative counterpart can really prove my point, in my opinion.

http://shiman.wordpress.com/2008/05/28/recursion-vs-iteration/


Well it really depends on what language you're coding in and what you're trying to do.

Iterative doesn't always win.

JPHamlett

2011-06-16 00:02:19

From: Richard
You have to agree with recursion, it's in SRL's name!


Well put Well put!

KingKong

2011-06-16 00:41:51

From: Richard
Not entirely sure what a "tick" is in their terms, but I've just been running some factorials in java, up to 21, and I've yet to see it go over 1ms, which to me is sufficiently efficient.

EDIT: To the above, Recursion just shows you're more awesome


Don’t say you don’t know what is a tick Nazmul. A tick is a tick in the system clock. Have you forgotten OS Course?


^ The guy in the comments section of the website.

masterBB

2011-06-16 01:44:02

http://runescape.wikia.com/wiki/Game_tick

It is 0.6 seconds….

And I'm still not a fan of recursive functions. It makes good look ugly. Especially if you want to add failsafes. And I'm pretty sure it's slower as my function.

Using getNPC will take the same reflection call as getNPCs. So it will be just as fast. But with getNPCs we can loop through the NPCs so we don't have to call this function a hundred times. Which would make it so much slower. I think everyone here has gone beyond the problem/question, don't use recursive functions in this example.

KingKong

2011-06-16 03:14:31

From: masterBB
http://runescape.wikia.com/wiki/Game_tick

It is 0.6 seconds….


Uh, the 0.6 seconds is for runescape tick, the tick were talking about is the computer clock one.

masterBB

2011-06-16 04:57:14

From: KingKong
Uh, the 0.6 seconds is for runescape tick, the tick were talking about is the computer clock one.


That makes more sense ;)

Also what everybody seems to be forgotten, this is a bad example of a recursive calls vs iteration. There is a change that you will take the same NPC every time. Only when rs shuffles the array of NPCs, you will get a different NPC. With iteration this is much easier. Unless you want to pass through which NPCs were already checked?

nielsie95

2011-06-16 11:22:11

http://c2.com/cgi/wiki?TailRecursion

Pascal Script probably doesn't support it, but it shows why recursion can be quite awesome.

i luffs yeww

2011-06-16 11:24:32

I think he does want to recheck them. What he wants is multithreading, I think. To be able to loop through and constantly update position while still looping. You could just have a check in the loop to see if the position has changed for any NPC, but that seems like it could be slow.

Not sure why you'd need this though.. Unless you're trying to get NPCs all in one box to do ancient magic on them or something. Better ways to do that, although I'm sure that's not why you want this. :p

E: Niels, I read up a bit on that last night and I agree it *can* be useful, but for someone who must ask what to use, chances are he should just iterate over the loop.

jerryt

2011-06-17 03:20:13

From: i luffs yeww
Recursion is far slower than iteration. In my opinion it should be avoided in almost any circumstance.


Oh my God, you are stupid.

Recursion is definitely much faster than iterating through.

masterBB

2011-06-17 04:28:18

From: i luffs yeww
You could just have a check in the loop to see if the position has changed for any NPC, but that seems like it could be slow.


This isn't in possible if there are multiple NPCs with the same ID. The index changes all the time.

@jerryt

At least use arguments when you call someone stupid. It's indeed slower.