SA-MP Forums Archive
3d array - Printable Version

+- SA-MP Forums Archive (https://sampforum.blast.hk)
+-- Forum: SA-MP Scripting and Plugins (https://sampforum.blast.hk/forumdisplay.php?fid=8)
+--- Forum: Scripting Help (https://sampforum.blast.hk/forumdisplay.php?fid=12)
+--- Thread: 3d array (/showthread.php?tid=625597)



3d array - GoldenLion - 03.01.2017

Hi, I made 6 3d arrays for a dealership. Each array has vehicles from a certain category and their price. However if I try to compile the script, the compiler crashes.
Here are the arrays:
Код:
new g_OffRoad[][][] =
{
	{"Landstalker", 50000},
	{"Rancher", 65000},
	{"Sandking", 80000},
	{"Mesa", 45000},
	{"Huntley", 100000}
};

new g_Saloons[][][] =
{
	{"Bravura", 25000},
	{"Sentinel", 45000},
	{"Manana", 20000},
	{"Esperanto", 50000},
	{"Washington", 75000},
	{"Premier", 100000},
	{"Previon", 30000},
	{"Admiral", 40000},
	{"Glendale", 50000},
	{"Oceanic", 50000},
	{"Hermes", 55000},
	{"Virgo", 50000},
	{"Greenwood", 60000},
	{"Elegant", 75000},
	{"Nebula", 35000},
	{"Majestic", 65000},
	{"Buccaneer", 35000},
	{"Fortune", 70000},
	{"Cadrona", 65000},
	{"Willard", 45000},
	{"Vincent", 55000},
	{"Clover", 60000},
	{"Bravura", 25000},
	{"Intruder", 35000},
	{"Primo", 30000},
	{"Tampa", 30000},
	{"Sunrise", 50000},
	{"Merit", 75000},
	{"Sultan", 250000},
	{"Elegy", 200000},
	{"Stafford", 80000},
	{"Emperor", 35000}
};

new g_SportVehicles[][][] =
{
	{"Buffalo", 400000},
	{"Cheetah", 750000},
	{"Banshee", 800000},
	{"Turismo", 1000000},
	{"Sabre", 75000},
	{"ZR-350", 300000},
	{"Blista Compact", 80000},
	{"Super GT", 500000},
	{"Bullet", 1250000},
	{"Uranus", 175000},
	{"Jester", 150000},
	{"Flash", 125000},
	{"Euros", 100000},
	{"Club", 75000},
	{"Alpha", 100000},
	{"Phoenix", 450000},
	{"Bravura", 25000}
};

new g_StationWagons[][][] =
{
	{"Perenniel", 40000},
	{"Moonbeam", 35000},
	{"Solair", 45000},
	{"Regina", 25000},
	{"Stratum", 50000},
	{"Bravura", 25000}
};

new g_Convertibles[][][] =
{
	{"Stallion", 65000},
	{"Comet", 150000},
	{"Feltzer", 75000},
	{"Windsor", 65000},
	{"Stallion", 65000}
};

new g_Industrial[][][] =
{
	{"Pony", 80000},
	{"Bobcat", 65000},
	{"Rumpo", 85000},
	{"Stallion", 65000},
	("Berkley's RC Van", 100000),
	{"Walton", 30000},
	{"Stallion", 65000},
	{"Burrito", 80000},
	{"Boxville", 100000},
	{"Sadler", 50000},
	{"Yosemite", 125000},
	{"Stallion", 65000},
	{"Picador", 40000},
	{"Stallion", 65000}
};
And this is where I use them (this is an example with g_OffRoad)
Код:
for (new i; i < sizeof(g_OffRoad); i++)
{
	format(string, sizeof(string), "%s\t$%d\n", g_OffRoad[i][0], g_OffRoad[i][1]);
	strcat(dialog, string);
}
ShowPlayerDialog(playerid, DIALOG_OFF_ROAD, DIALOG_STYLE_LIST, "Off Road", dialog, "Select", "Back");
What's up?


Re: 3d array - IstuntmanI - 03.01.2017

You can't create 3D array directly (also, the prices wouldn't require another dimension, as the string does). You have to do it like this:
pawn Код:
enum e_Convertibles
{
    g_C_Name[16],
    g_C_Price,
};

new g_Convertibles[][e_Convertibles] =
{
    {"Stallion", 65000},
    {"Comet", 150000},
    {"Feltzer", 75000},
    {"Windsor", 65000},
    {"Stallion", 65000}
};
Accessing: g_Convertibles[i][g_C_Name] .

By the way, I recommend you to create only one array with all those vehicles, by also specifying an enum item for the type, and when looping you should check the type to show it or not.


Re: 3d array - GoldenLion - 03.01.2017

But iPLEOMAX did that in this tutorial: https://sampforum.blast.hk/showthread.php?tid=318212 and also I made a testing filterscript where I made a 3d array, looped through the elements and printed them and about one array, I didn't think of doing it like this, thanks. :P

EDIT: I found the problem.
Код:
("Berkley's RC Van", 100000),
These are supposed to be curly brackets.


Re: 3d array - SickAttack - 04.01.2017

There is no need for 3 dimensions. Let's take one of your arrays for an example (note that I removed the 3rd dimension):

pawn Код:
new g_OffRoad[][] =
{
    {"Landstalker", 50000},
    {"Rancher", 65000},
    {"Sandking", 80000},
    {"Mesa", 45000},
    {"Huntley", 100000}
};
With that being said, we can take Y and X for an easier comprehension:



Y [UP & DOWN] = 1st dimension
X [LEFT & RIGHT] = 2nd dimension

Meaning that the 1st dimension will define the row (UP & DOWN) and the 2nd dimension will define the column (LEFT & RIGHT) to choose. A 3rd dimension technically has no use.


Re: 3d array - GoldenLion - 04.01.2017

Quote:
Originally Posted by SickAttack
Посмотреть сообщение
There is no need for 3 dimensions. Let's take one of your arrays for an example (note that I removed the 3rd dimension):

pawn Код:
new g_OffRoad[][] =
{
    {"Landstalker", 50000},
    {"Rancher", 65000},
    {"Sandking", 80000},
    {"Mesa", 45000},
    {"Huntley", 100000}
};
With that being said, we can take Y and X for an easier comprehension:



Y [UP & DOWN] = 1st dimension
X [LEFT & RIGHT] = 2nd dimension

Meaning that the 1st dimension will define the row (UP & DOWN) and the 2nd dimension will define the column (LEFT & RIGHT) to choose. A 3rd dimension technically has no use.
That's what I tried doing before reading a tutorial. I printed the vehicle's name and it's price. The name was good, but the price was something around 100. However when I added the third dimension it started working properly.


Re: 3d array - IstuntmanI - 04.01.2017

Quote:
Originally Posted by GoldenLion
Посмотреть сообщение
But iPLEOMAX did that in this tutorial: https://sampforum.blast.hk/showthread.php?tid=318212 and also I made a testing filterscript where I made a 3d array, looped through the elements and printed them and about one array, I didn't think of doing it like this, thanks. :P
I still think that way is a bad. Up-Down should be the first dimension and from the left to the right it should be the second dimension. The compiler wouldn't give any warning or error when you make a mistake.
pawn Код:
new g_Convertibles[][][] =
{
//#           0                1 (second dimension)
//1st dim
/*0*/    {"Stallion",        65000},
/*1*/    {"Comet",           150000},
/*2*/    {"Feltzer",         75000},
/*3*/    {"Windsor",         65000},
/*4*/    {"Stallion",        65000}
};
Good examples for your method:
pawn Код:
printf( "'%c'/%s/%d", g_Convertibles[ 0 ][ 0 ] ); // "'S'/Stallion/83" - ok
printf( "'%c'/%s/%d", g_Convertibles[ 0 ][ 0 ][ 0 ] ); // "'S'/Stallion/83" - ok
printf( "'%c'/%s/%d", g_Convertibles[ 0 ][ 0 ][ 1 ] ); // "'t'/tallion/116" - ok
printf( "%d", g_Convertibles[ 0 ][ 1 ] ); // "65000" - ok
printf( "%d", g_Convertibles[ 0 ][ 1 ][ 0 ] ); // "65000" - ok - but bad, you shouldn't be able to access any additional dimension of an integer, as it doesn't exists
Bad examples, the compiler gives no warning/error:
pawn Код:
printf( "'%c'/%s/%d", g_Convertibles[ 0 ][ 0 ][ 20 ] ); // "'t'/tzer/116" - not ok, should give a compiling error
printf( "%c", g_Convertibles[ 0 ][ 1 ][ 1 ] ); // 'C' - not ok, this result because an integer has no additional dimension, so it will access the next bytes, which is the 'C' from "Comet", should give a warning/error
----------------

Quote:
Originally Posted by SickAttack
Посмотреть сообщение
<>
Your method is also bad because the compiler won't know exactly what you are doing. There won't be any error/warning in case you do anything with no logic. Example:
pawn Код:
g_OffRoad[ 0 ][ 500000 ]
Also, as I said before, the first dimension should be the number of rows (and it is) and the second dimension should be the number of human-readable columns (in your case it isn't). You can't access it like this:
pawn Код:
g_OffRoad[ 0 ][ 0 ] // name in index 0 with additional dimension for each character - nope
g_OffRoad[ 0 ][ 1 ] // value in index 1 - nope
----------------

Quote:
Originally Posted by GoldenLion
Посмотреть сообщение
That's what I tried doing before reading a tutorial. I printed the vehicle's name and it's price. The name was good, but the price was something around 100. However when I added the third dimension it started working properly.
That's because his method internally actually looks like this:
pawn Код:
new g_OffRoad[][] =
{
    {'L', 'a', 'n', 'd', 's', 't', 'a', 'l', 'k', 'e', 'r', '\0', 50000 },
    {'R', 'a', 'n', 'c', 'h', 'e', 'r', '\0', 65000}, // further indexes will go in row 3
    {'S', 'a', 'n', 'd', 'k', 'i', 'n', 'g', '\0', 80000}, // further indexes will go in row 4, etc.
    {'M', 'e', 's', 'a', '\0', 45000},
    {'H', 'u', 'n', 't', 'l', 'e', 'y', '\0', 100000}
};
If you access for example g_OffRoad[0][1] it won't give you the price, but the ASCII value for character 'a', which is 97 (around 100, as you said).

Well, the value for the first row (0 - "Landstalker") is placed in g_OffRoad[0][12], as that value of 50000 is in the 13rd index. For the second row it isn't in 13, but in 9th (g_OffRoad[0][8]). If you access the 10th index of row 0 you will get the 'R' from the first index of the second row, which isn't really alright.

----------------

Sorry if I messed something up, I took both OffRoad and Convertibles arrays for different examples, also I wrote-edited, wrote-edited, wrote-edited.

With more advanced things you risk to mess it up and access invalid memory addresses, which can corrupt the memory (better be safe than sorry). I think that my method is the safest one and easy to understand, which gives exact dimensions of everything. It gives enough warnings/errors if you access invalid indexes. You know exactly where is the name and where is the value.


Re: 3d array - GoldenLion - 04.01.2017

Quote:
Originally Posted by IstuntmanI
Посмотреть сообщение
I still think that way is a bad. Up-Down should be the first dimension and from the left to the right it should be the second dimension. The compiler wouldn't give any warning or error when you make a mistake.
pawn Код:
new g_Convertibles[][][] =
{
//#           0                1 (second dimension)
//1st dim
/*0*/    {"Stallion",        65000},
/*1*/    {"Comet",           150000},
/*2*/    {"Feltzer",         75000},
/*3*/    {"Windsor",         65000},
/*4*/    {"Stallion",        65000}
};
Good examples for your method:
pawn Код:
printf( "'%c'/%s/%d", g_Convertibles[ 0 ][ 0 ] ); // "'S'/Stallion/83" - ok
printf( "'%c'/%s/%d", g_Convertibles[ 0 ][ 0 ][ 0 ] ); // "'S'/Stallion/83" - ok
printf( "'%c'/%s/%d", g_Convertibles[ 0 ][ 0 ][ 1 ] ); // "'t'/tallion/116" - ok
printf( "%d", g_Convertibles[ 0 ][ 1 ] ); // "65000" - ok
printf( "%d", g_Convertibles[ 0 ][ 1 ][ 0 ] ); // "65000" - ok - but bad, you shouldn't be able to access any additional dimension of an integer, as it doesn't exists
Bad examples, the compiler gives no warning/error:
pawn Код:
printf( "'%c'/%s/%d", g_Convertibles[ 0 ][ 0 ][ 20 ] ); // "'t'/tzer/116" - not ok, should give a compiling error
printf( "%c", g_Convertibles[ 0 ][ 1 ][ 1 ] ); // 'C' - not ok, this result because an integer has no additional dimension, so it will access the next bytes, which is the 'C' from "Comet", should give a warning/error
----------------



Your method is also bad because the compiler won't know exactly what you are doing. There won't be any error/warning in case you do anything with no logic. Example:
pawn Код:
g_OffRoad[ 0 ][ 500000 ]
Also, as I said before, the first dimension should be the number of rows (and it is) and the second dimension should be the number of human-readable columns (in your case it isn't). You can't access it like this:
pawn Код:
g_OffRoad[ 0 ][ 0 ] // name in index 0 with additional dimension for each character - nope
g_OffRoad[ 0 ][ 1 ] // value in index 1 - nope
----------------



That's because his method internally actually looks like this:
pawn Код:
new g_OffRoad[][] =
{
    {'L', 'a', 'n', 'd', 's', 't', 'a', 'l', 'k', 'e', 'r', '\0', 50000 },
    {'R', 'a', 'n', 'c', 'h', 'e', 'r', '\0', 65000}, // further indexes will go in row 3
    {'S', 'a', 'n', 'd', 'k', 'i', 'n', 'g', '\0', 80000}, // further indexes will go in row 4, etc.
    {'M', 'e', 's', 'a', '\0', 45000},
    {'H', 'u', 'n', 't', 'l', 'e', 'y', '\0', 100000}
};
If you access for example g_OffRoad[0][1] it won't give you the price, but the ASCII value for character 'a', which is 97 (around 100, as you said).

Well, the value for the first row (0 - "Landstalker") is placed in g_OffRoad[0][12], as that value of 50000 is in the 13rd index. For the second row it isn't in 13, but in 9th (g_OffRoad[0][8]). If you access the 10th index of row 0 you will get the 'R' from the first index of the second row, which isn't really alright.

----------------

Sorry if I messed something up, I took both OffRoad and Convertibles arrays for different examples, also I wrote-edited, wrote-edited, wrote-edited.

With more advanced things you risk to mess it up and access invalid memory addresses, which can corrupt the memory (better be safe than sorry). I think that my method is the safest one and easy to understand, which gives exact dimensions of everything. It gives enough warnings/errors if you access invalid indexes. You know exactly where is the name and where is the value.
Alright, I will use your method. Thank you.


Re: 3d array - SickAttack - 04.01.2017

Quote:
Originally Posted by IstuntmanI
Посмотреть сообщение
Your method is also bad because the compiler won't know exactly what you are doing. There won't be any error/warning in case you do anything with no logic. Example:
pawn Код:
g_OffRoad[ 0 ][ 500000 ]
Also, as I said before, the first dimension should be the number of rows (and it is) and the second dimension should be the number of human-readable columns (in your case it isn't). You can't access it like this:
pawn Код:
g_OffRoad[ 0 ][ 0 ] // name in index 0 with additional dimension for each character - nope
g_OffRoad[ 0 ][ 1 ] // value in index 1 - nope
Well, duh! That's why enumerators are commonly used for the last dimension, if it worked by simply placing a consecutive number there, then there would be no use for enumerators being used with arrays (in this particular scenario). Simple arrays like that behave that way so you can access individual cells; otherwise, you could only retrieve the whole set of characters.

That's also why the size of enumerators with elements that have more than one cell are always larger than the actual number of columns (counting by 1).

And the reason behind doing enum_name:1, enum_name:2, etc. in the index where the enumerator was placed when declaring the array as an alternative to not use the name of the elements in the enumerator.

I was only explaining to the thread author regarding to why a 3rd dimension isn't needed. But I get where you are coming from since I used 'column', it technically defines the column if you insert the right index, but I guess I could have used 'cell' instead.

-----

Quote:
Originally Posted by GoldenLion
Посмотреть сообщение
Alright, I will use your method. Thank you.
I'm not sure what method you are talking about, but this is the most common one:

pawn Код:
enum e_array
{
    string[144],
    integer
};

new array[][e_array] =
{
    {"hello buddy", 5000},
    {"something", 2000}
};

main()
{
    printf("%s %d", array[0][string], array[0][integer]);
}
This is really basic (I see people that are new to PAWN even create arrays this way), I thought you knew about it already. So I just felt the need to point out why a 3rd dimension isn't needed.


Re: 3d array - GoldenLion - 04.01.2017

Quote:
Originally Posted by SickAttack
Посмотреть сообщение
Well, duh! That's why enumerators are commonly used for the last dimension, if it worked by simply placing a consecutive number there, then there would be no use for enumerators being used with arrays (in this particular scenario). Simple arrays like that behave that way so you can access individual cells; otherwise, you could only retrieve the whole set of characters.

That's also why the size of enumerators with elements that have more than one cell are always larger than the actual number of columns (counting by 1).

And the reason behind doing enum_name:1, enum_name:2, etc. in the index where the enumerator was placed when declaring the array as an alternative to not use the name of the elements in the enumerator.

I was only explaining to the thread author regarding to why a 3rd dimension isn't needed. But I get where you are coming from since I used 'column', it technically defines the column if you insert the right index, but I guess I could have used 'cell' instead.

-----



I'm not sure what method you are talking about, but this is the most common one:

pawn Код:
enum e_array
{
    string[144],
    integer
};

new array[][e_array] =
{
    {"hello buddy", 5000},
    {"something", 2000}
};

main()
{
    printf("%s %d", array[0][string], array[0][integer]);
}
This is really basic (I see people that are new to PAWN even create arrays this way), I thought you knew about it already. So I just felt the need to point out why a 3rd dimension isn't needed.
Yes, I'm using that one. Actually I never used any arrays like this so this was the first time I had to do something like this.