Passing arrays to functions

Started by deltamatrix, Thu 03/05/2007 01:35:28

Previous topic - Next topic

deltamatrix

Is there not a way to pass arrays to functions in AGS? It'd be cool to do it a similar way to C++.

i.e. int foo(int *array)
BAD WOLF - TORCHWOOD - MR SAXON - THE BEES ARE DISAPPEARING - PANDORICA - RIVER SONG

monkey0506

There's no way to pass an array into a function in AGS right now...but if you really needed it a possible workaround could be something like:

Code: ags
#define INTARRAY_SIZE 50  

struct IntArray {
  int i[INTARRAY_SIZE];
  import void Randomize(int min, int max, bool preventRepeats=false);
  import bool Contains(int value);
  };

bool IntArray::Contains(int value) {
  int index = 0;
  while (index < INTARRAY_SIZE) {
    if (this.i[index] == value) return true;
    index++;
    }
  return false;
  }

void IntArray::Randomize(int min, int max, bool preventRepeats) {
  if ((max - min) < INTARRAY_SIZE) preventRepeats = false;
  int index = 0;
  while (index < INTARRAY_SIZE) {
    int ran = Random(max - min) + min;
    while ((preventRepeats) && (this.Contains(ran))) ran = Random(max - min) + min;
    this.i[index] = ran;
    index++;
    }
  }

IntArray my_int_array;

// game_start
my_int_array.Randomize(5, 100, true);


It's not exactly what you wanted but it can achieve the same end result. The problem with this method is that it requires a static size for all of your integer arrays. This causes two conflicts: 1) if you need more items in the array, you must increase the size of all the arrays, 2) if you don't use all the items in the array, you're wasting memory.

If you want to save memory with this method, you may consider the VectorClass module. It's still not what you asked about, but it gets the same results, and saves memory over the statically-sized array approach.

If you wanted to use the module, you would have to add your own functions to the module-implemented class iVector:

Code: ags
struct MyIntVector extends iVector {
  import void Randomize(int min, int max, bool preventRepeats=false);
  import bool Contains(int value);
  };

bool MyIntVector::Contains(int value) {
  int i = 0;
  while (i < this.Size) {
    if (this.GetValue(i) == value) return true;
    i++;
    }
  return false;
  }

void MyIntVector::Randomize(int min, int max, bool preventRepeats) {
  if ((max - min) < this.Size) preventRepeats = false;
  int i = 0;
  while (i < this.Size) {
    int ran = Random(max - min) + min;
    while ((preventRepeats) && (this.Contains(ran))) ran = Random(max - min) + min;
    this.SetValue(i, ran);
    i++;
    }
  }

deltamatrix

That doesn't solve the problem as you can't pass structs to functions either. And AGS doesn't even allow this:
int foo(IntArray *i)
BAD WOLF - TORCHWOOD - MR SAXON - THE BEES ARE DISAPPEARING - PANDORICA - RIVER SONG

monkey0506

#3
My workaround idea was that you could implement the functions you needed to pass arrays into as MEMBER functions of the struct.

i.e., instead of:

Code: ags
void Randomize(int arr[], int size, int min, int max) {
  int i = 0;
  while (i < size) {
    int ran = Random(max - min) + min;
    i++;
    }
  //etc.
  }


You could set up the randomize function like in my example, as a member function of the structure.

[EDIT:]

It's really not exactly what you wanted, especially if you were hoping to be able to load one array from another or some such...I just provided it as a workaround to be able to get your function to be able to perform actions upon the array.

deltamatrix

#4
Thanks. But sadly, what I need to assign an unique set of values to each individual room and pass them to a global function. Its for drawing stars in the sky at night time using rawdraw functions.
I suppose it coulda been done by passing the array values individually using a while loop.

However, I have done this using an special string property instead which is decoded and  the relevant numbers are extracted. This saves me the bother of having to add script per room.

Thanks anyway.
BAD WOLF - TORCHWOOD - MR SAXON - THE BEES ARE DISAPPEARING - PANDORICA - RIVER SONG

monkey0506

Just based on your description I don't see why my method wouldn't work...as long as the function works the same way regardless of the values in the array...I mean, clearly the end result will vary, but so long as the actual methods are the same...you could probably make my idea work quite nicely...just implement one of these special structurized arrays into the rooms where you need to draw the effects (or create a global array of them to accommodate all rooms)...then call the function for drawing the stars (which would work based off the values in the structure's members).

You seem to have gotten it worked out anyway...just saying that it could work.

P.S. You're welcome ;)

SMF spam blocked by CleanTalk