Tablice wielowymiarowe 2346 2

O temacie

Autor FOgidel

Zaczęty 22.05.2016 roku

Wyświetleń 2346

Odpowiedzi 2

FOgidel

FOgidel

Użytkownicy
posty60
Propsy100
ProfesjaSkrypter
  • Użytkownicy
Hej!
Czy w Daedalusie działają tablice wielowymiarowe?
Próbowałem, ale parser wywala błędy więc raczej nie, ale może ktoś coś?
 

FOgidel

FOgidel

Użytkownicy
posty60
Propsy100
ProfesjaSkrypter
  • Użytkownicy
W sumie to zrobię NPCa, który będzie tablicą wielowymiarową...
 

Lehona

Lehona

Użytkownicy
posty196
Propsy190
  • Użytkownicy
Daedalus doesn't support multidimensional arrays, but that doesn't matter much, because static arrays (the "normal" daedalus ones) are fixed-size, which in turn means that you can simply "emulate" multi-dimensional arrays, e.g. if I want a 5x5 array, I simply do it like this:

var int array[25 /* 5*5 */];

func void write2D(var int x, var int y, var int value) {
    array[5*y+x] = value;
};
Obviously it's not quite that easy because you can't use dynamic indices, but you get the point...

You can, however, simply build your own two-dimensional array using zCArray (and LeGo, if you want persistent memory).
A two-dimensional array can be thought of as an array, where every entry is another array (which then has the actual data), i.e. zCArray<zCArray<int>*>.

LeGo already supports (un-)archiving arrays, so you can simply create one like this:
var int array; array = new(zCArray@);
You can probably make a complete 2d-array system like this:
const int 2D_Inital = 80; // 20*4

func int createArray2D() {
var int h; h = new(zCArray@);
var zCArray arr; arr = get(h);

arr.array = MEM_Alloc(2D_Inital); // Allocate enough space for 20 subarrays
arr.numAlloc = 2D_Inital;
};


/* x-coordinate is within the first array */
func void writeArray2D(var int array, var int x, var int y, var int value) {
var zCArray arr; arr = get(h);

if (x*4 > arr.numAlloc) {
arr.array = MEM_Realloc(arr.array, arr.numAlloc, (x+10)*4 /* Get a small buffer */ );
arr.numAlloc = (x+10)*4;
};

var int handle2; handle2 = MEM_ReadInt(arr.array+4*x);
if (!handle2) {
MEM_WriteInt(arr.array+4*x, new(zCArray@));
handle2 = MEM_ReadInt(arr.array+4*x);
};

var zCArray arr2; arr2 = get(handle2);
if (y*4 > arr2.numAlloc) {
arr2.array = MEM_Realloc(arr2.array, arr2.numAlloc, (y+5)*4 /* Get a small buffer */ );
arr2.numAlloc = (y+5)*4;
};

MEM_WriteInt(arr2.array+y*4, value);
};

func int readArray2D(var int array, var int x, var int y) {
var zCArray arr; arr = get(h);

if (x*4 > arr.numAlloc) {
arr.array = MEM_Realloc(arr.array, arr.numAlloc, (x+10)*4 /* Get a small buffer */ );
arr.numAlloc = (x+10)*4;
};

var int handle2; handle2 = MEM_ReadInt(arr.array+4*x);
if (!handle2) {
MEM_WriteInt(arr.array+4*x, new(zCArray@));
handle2 = MEM_ReadInt(arr.array+4*x);
};

var zCArray arr2; arr2 = get(handle2);
if (y*4 > arr2.numAlloc) {
arr2.array = MEM_Realloc(arr2.array, arr2.numAlloc, (y+5)*4 /* Get a small buffer */ );
arr2.numAlloc = (y+5)*4;
};

return MEM_ReadInt(arr2.array+y*4);
};
I haven't tested this at all, but you should get the idea.
Note that this can blow up in size relatively quickly if you use relatively big indices, even if you save only a couple of values.

In that case you probably want to emulate it using Hashtables:

/* This will fail silently once indices get too big, around 10K, so be careful and add additional error checks if you actually use this */
func void WriteHT2D(var int array, var int x, var int y, var int value) {
var int key; key = x << 14 + y;
HT_InsertOrChange(array, value, key);
};


/* This doesn't care if the value actually exists, so keep that in mind. Check with HT_Has() first if you actually use this */
func int readHT2D(var int array, var int x, var int y) {
var int key; key = x << 14 + y;
return HT_Get(array, key);
};

As you can see, it's also way less code :D
 
Unless specified otherwise, my posts are always about Gothic 2 Night of the Raven.


0 użytkowników i 1 Gość przegląda ten wątek.
0 użytkowników
Do góry