Function Prototyping & Multiple Recursive Functions

Started by Kjammer, Thu 07/04/2011 11:50:36

Previous topic - Next topic

Kjammer

I'm trying to make a script that uses 4 recursive functions that can call each other or itself.  Unfortunately, this doesn't work because functions need to be defined in order. 

What I'm trying to do is script a puzzle where the player places objects on a field/pit/table/whatever and releases an autonomous bug whose movement is affected by the objects. I thought function recursion would be perfect for this puzzle.  The 4 functions each correspond to a direction the bug is facing and changes directions by calling one of the other three functions.

For example:
Code: ags
function GoNorth (int square, int start) {
if (BASE CASE) return;
//object in front, go back
else if (pos[square - 10] == 1) GoSouth(square, start);
//object to the left, go right
else if (pos[square - 11] == 1) GoEast(square, start);
// object to the right, go left
else if (pos[square - 9] == 1) GoWest(square, start);
// no object, move foreward
else GoNorth(square + 1, start);
}


Is there a way to implement function prototyping or to make all functions recognize each other?

Sephiroth

#1
Hey, I don't see the point of having all this code inside GoNorth function.

You could simplify it by using a Move() function:

Code: ags

function BugMove( int square, int start )
{

  if (BASE CASE)  return;
  else if (pos[square - 10] == 1) GoSouth();
  else if (pos[square - 11] == 1) GoEast();
  else if (pos[square - 9] == 1) GoWest();
  else GoNorth();

}


And have all the Go* functions defined before no matter the order. I hope this works as you expected. Assuming BASE CASE is what allows you to start/stop movement, calling this in the repeatedly execute would allow you to make it move by setting BASE_CASE to FALSE.

Then if the GoNorth() function looks like this, it should be ok.

Code: ags

function GoNorth()
{
 Bug.x = Bug.x;
 Bug.y = Bug.y-10;
//or something like Bug.walk()
}


Khris

What I'd do is use a single function and make the direction a parameter.

Kjammer

Thanks for the tips.  I don't know why I didn't think of it before?  I guess this is what happens when  you're sleep depraved and are too stubborn to erase your code and start from scratch.

Here is what I ended up doing:

Code: ags

function BugMove(int square, int start, int dir) {
  if (BASE_CASE) return;

  if (dir == 0) { // Facing North
       if (pos[square - 10] == 1) dir = (dir + 2) % 4; // turn around
       else if (pos[square - 11] == 1) dir = (dir + 1) % 4; // turn right
       else if (pos[square - 9] == 1) dir = (dir - 1) % 4; // turn left
       else square = square + 1;  // move foreward
  }

  else if (dir == 1) {  // Facing East

  // Etc..

  // Function recursion
  BugMove(square, start, dir);
}


Thank you both for helping me out here.

Sephiroth

#4
Hm, I was wondering why you need recursive function at all.

Maybe you could use:

Code: ags


function repeatedly_execute() 
{
  
  if( BASE_CASE == false )
  {
    BugMove(square, start, dir);
  }

}



Wouldn't it be more simple?

monkey0506

That would work completely differently. A recursive function adds itself to the call stack (again). A function is removed from the call stack when it returns (or ends). The game loop does not end until the call stack is empty.

repeatedly_execute however is only queued (added to the call stack) once per game loop.

Effectively the difference is that of a blocking versus a nonblocking function. The later may in fact work for this particular case (or it may not), but the two are not directly comparable.

Sephiroth

#6
I've never used recursive function for anything other than listing directory files, where the function has to call itself in a different context before you can process to next loop.

None of these concept seem to apply to this case, at least from what I've seen... I'm not comparing anything, just saying the use of recursive function probably isn't needed here.

Generally speaking , the current code is the same as :

Code: ags

function BugMove(int square, int start, int dir)
{

 while(BASE_CASE == false)
 {
   if (dir == 0)  // Facing North
   {
       if (pos[square - 10] == 1) dir = (dir + 2) % 4; // turn around
       else if (pos[square - 11] == 1) dir = (dir + 1) % 4; // turn right
       else if (pos[square - 9] == 1) dir = (dir - 1) % 4; // turn left
       else square = square + 1;  // move foreward
  }
  //etc
 }

}


Which can, imho, be simplified to what I've described in previous post, because the use of recursive isn't really required.

Sorry if I'm writing a lot but something else is strange, none of the code actually move an object or character, if the bug is supposed to move on screen, there must be a 'rendering' function somewhere right? So I assume you're either updating the graphics inside 'repeatedly execute always', also controlling the BASE_CASE variable from there, or you'd need to add the code to the function BugMove... I'm done..sorry.

Kjammer

Quote from: Sephiroth on Fri 08/04/2011 03:03:52

Sorry if I'm writing a lot but something else is strange, none of the code actually move an object or character, if the bug is supposed to move on screen, there must be a 'rendering' function somewhere right? So I assume you're either updating the graphics inside 'repeatedly execute always', also controlling the BASE_CASE variable from there, or you'd need to add the code to the function BugMove... I'm done..sorry.


Yeah, what I posted was a very simplified version of what I intended to do, just so you could get an idea of how my script works.  BASE_CASE was used in my example in lieu of the actual conditions, a set of values and numbers that won't make sense without context.  Something else is governing the visual movement.

int pos[square] governs which square the bug located and another function maps the oBug to the room.  Hope this makes sense.


SMF spam blocked by CleanTalk