3D Array workaround

T

TypicalHog

Guest
I'm currently storing stars in 2D arrays.
Star[star_index, 0] // X pos of a star
Star[star_index, 1] // Y pos of a star
Star[star_index, 2] // Color of a star

Each array cointains 64-512 stars.
I can't have star array for every chunk in my game.
All chunks also can't have only 1 star array because that would look too repetetive.
And I don't want to create separate array for every star array:
Star00, Star01, ... , Star15

Any ideas?
 
T

TypicalHog

Guest
Use an array of arrays... GMS's arrays can store anything on them, even more arrays. By making every cell of an array another array, you have basically created a makeshift higher-dimensional array.
Lol, I have no idea why i didn't come up with this. Thank you!
 
S

Strangebrownbag

Guest
So how would that work? Do you have an example? I'm trying to store a variable that tells cars when to turn upon collision with an intersection. The variable itself is just a number, relevant to a complicated equation not worth getting into here. As it is, I have the intersection reading a 2d array from its adjacent street, indexed by [vehicle type, direction its moving]. However, this is inefficient, as it requires each street object (there are hundreds) to hold its own redundant array telling intersections how to interact with it. It would be much more efficient to store one global, 3D array, indexed by [street type, vehicle type, direction]. But I can't figure out how I would read or write an "array of arrays". Thanks.
 

lolslayer

Member
I made a script for this once, I called it: array_getxy
This way you can you use one data recieve key slot like you're using 2.

This is the script:
Code:
///array_getxy(ax,ay,ly)

var ax = argument0;                 //array x, start with 0
var ay = argument1;                 //array y, start with 0
var ly = argument2;                 //length of the array columns

return ax*ly + ay;
You can create as many dimensions you want using this principle

One example I can give you is storing multiple variables to any grid location, the grid size is 100x100, the code to get any information of a specific x and y location of a grid will work like this:
Code:
grid[array_getxy(15,10,100),2]//return the height of the grid
 
Rough 3D array using nested arrays example:

Creating:
Code:
var outer_array = undefined,
    index = 0;

repeat (10)
{
    var inner_array = undefined,
        x1 = 0,
        y1 = 0;

    repeat (5)
    {
        repeat (5)
        {
            inner_array[x1, y1] = irandom(99);
           
            x1++;
        }   
       
        x1 = 0;
        y1++;
    }
   
    outer_array[index] = inner_array;
    index++;
}
Getting data (script form):
Code:
/// array_3d_get(array, x1, y1, z1) = value;

var out_array = argument[0],
    x1 = argument[1],
    y1 = argument[2],
    z1 = argument[3];

var in_array = out_array[@ x1];

return (in_array[@ y1, z1]);
... You could also have 1D arrays stored in a 2D array instead of the way I did above, where the 2D array is stored in a 1D array. All depends on how you want to do it. You could even ditch 2D arrays all together and just have triple nested 1D arrays.
 
S

Strangebrownbag

Guest
Thanks for the input, everyone! I think I'm going to try the ds_grid first for simplicity. That way's pretty straightforward.
 

lolslayer

Member
Rough 3D array using nested arrays example:

Creating:
Code:
var outer_array = undefined,
    index = 0;

repeat (10)
{
    var inner_array = undefined,
        x1 = 0,
        y1 = 0;

    repeat (5)
    {
        repeat (5)
        {
            inner_array[x1, y1] = irandom(99);
          
            x1++;
        }  
      
        x1 = 0;
        y1++;
    }
  
    outer_array[index] = inner_array;
    index++;
}
Getting data (script form):
Code:
/// array_3d_get(array, x1, y1, z1) = value;

var out_array = argument[0],
    x1 = argument[1],
    y1 = argument[2],
    z1 = argument[3];

var in_array = out_array[@ x1];

return (in_array[@ y1, z1]);
... You could also have 1D arrays stored in a 2D array instead of the way I did above, where the 2D array is stored in a 1D array. All depends on how you want to do it. You could even ditch 2D arrays all together and just have triple nested 1D arrays.
This doesn't seem like the best way to it, you could have the problem that the inner_array random number gets the same number 2 times if you're unlucky
 
S

Strangebrownbag

Guest
But lolslayer, it doesn't matter what datapoint the variable holds. The array itself doesn't have any random element to its structure, as that would be especially sloppy. irandom(99), as far as I can tell, is just a placeholder variable. It could be anything, though.
 

Joe Ellis

Member
whenever you address an array without any brackets, its getting the id\pointer of the array, with this it means you can technically make an array of infinite dimensions out of 1d arrays, for instance:

Code:
rows = 30
columns = 30
forwards = 30
downwards = 30



i1=0
repeat rows
{
i1++

dimension2=undefined

i2=0
repeat columns
{
i2++

dimension3=undefined

i3=0
repeat forwards
{
i3++

dimension4=undefined

i4=0
repeat downwards
{
i4++

dimension4[i4] = random(30)

}

dimension3[i3]=dimension4

}

dimension2[i2]=dimension3

}

dimension1[i1]=dimension2

}
so then if you were to access a value from that array, (you could think of it like on minecraft, even though thats only 3d) you would choose the row, then column, then move forwards into that cell by a few cells, then go downwards a number a cells, which then contains the actual value

Code:
i_row = 1+irandom(29)
i_column = 1+irandom(29)
i_forwards = 1+irandom(29)
i_downwards = 1+irandom(29)

row = dimension1[i_row]

column = row[i_column]

forwards = column[i_forwards]

value = forwards[i_downwards]
obviously on its own this would be pretty annoying to work with, but i'm showing that its possible,

that array contains 810,000 values, 25 times over the standard 32,000 limit
 
This may have already been answered but I have found that this technique works well for 3D arrays in GMS:
Code:
someArray[someSize] = 0;

for (var i = 0; i < array_length_1d(someArray); i++)
{
     someArray[i] = ds_grid_create(width,height)
     for (var j = 0; j < someWidth; j++)
    {
        for (var k = 0; k < someHeight; k++)
        {
            ds_grid_add(someArray[i],j,k,someReturnedValue);
        }
    }
}

//When value is needed
var getVal = ds_grid_get(someArray[someIndex],row,column);
 
Top