Two Dim. Array for Item and its quality

Dagoba

Member
Hello!

Once again an array problem (sigh).
I am trying to create a random item like this:
Code:
var item;
item = choose("Apple","Banana","Carrot","Potato");
This is the simple creation for the code, but I need to create multiple objects at the same, given each of them a "quality".

Code:
var rn, item_quality;
rn = irandom_range(1,5);
for (i = 0; i < rn; i++) {
      //The first slot of array is the item, second is for the quality
item[i,0] = choose("Apple","Banana","Carrot","Potato");
item_quality = choose("High","Average","Bad");

}
The thing I want is to add variable "item_quality" to the next dimension of that array, but item[i,i] would not work.
What could be the solution for this?

Thanks in advance!

EDIT: Wait, I can use it like (item[item,item_quality]) isn't it like that? I am going to try.

EDIT2: Did a small new project for this problem and here is the following code:

scr_choose_random();
Code:
var quality, item, item_id, randomizer;

randomizer = irandom_range(1,5);
for (i = 0; i < randomizer; i+=1) {

    item_id = choose("Apple","Banana","Carrot","Potato");
    quality = choose("Best","Average","Bad");
    var_item_returned = item[item_id,quality];
    return var_item_returned;
}
obj_controller:

CREATE:
Code:
var_item_returned = 0;
scr_choose_random();
DRAW:
Code:
for (i = 0; i < item[i]; i+=1) {
    draw_text(0,16+item[i]*2,var_item_returned);
}
Will create this error:
Code:
___________________________________________
ERROR in
action number 1
of Create Event
for object obj_item:

In script scr_choose_random:
Error in code at line 8:
       var_item_returned = item[item_id,quality];
                                ^
at position 31: Wrong type of array index
Any ideas?
 
Last edited:

jo-thijs

Member
You should have used item[i, 1].

As for the error message, you're using GM8?
Anyway, item_id and quality are both strings,
you should use numbers as array indices instead.
 

NightFrost

Member
GMS only supports integers as array indices (sadly). However, it seems like you are wanting to generate a simple name from combo of two choices, in which case you don't need to wrangle arrays. In your script, after the two chooses, declare
Code:
var_item_returned = item_id + " " + quality;
You'll want to avoid var_ as a prefix in your variable names because var has meaning in GMS and writing var_item_returned and var item_returned mean two very different things.

EDIT - also, your script does not need to return the variable. It has been declared in the object that calls it, and script can see variables of calling objects. This of course can lead to problems when calling object does not have variable by that name, so returning something from the script and catching it at the object end is a wised idea.
 

Dagoba

Member
You should have used item[i, 1].

As for the error message, you're using GM8?
Anyway, item_id and quality are both strings,
you should use numbers as array indices instead.
Yes, for the example I used GM8.0 since it's faster just open it than close my existsing project.
So I should not use item[item_id,item_quality] at all?
Thought that worked in GM8.0, but yeah I am using this on GM:Studio.

GMS only supports integers as array indices (sadly). However, it seems like you are wanting to generate a simple name from combo of two choices, in which case you don't need to wrangle arrays. In your script, after the two chooses, declare
Code:
var_item_returned = item_id + " " + quality;
You'll want to avoid var_ as a prefix in your variable names because var has meaning in GMS and writing var_item_returned and var item_returned mean two very different things.

EDIT - also, your script does not need to return the variable. It has been declared in the object that calls it, and script can see variables of calling objects. This of course can lead to problems when calling object does not have variable by that name, so returning something from the script and catching it at the object end is a wised idea.
Yeah, I know that I should avoid var_blabla but that was just for showing the example I want, not using those names in my real project.
And I use return for the case that I usually code with Java and I'm used to return everything unless it's a void method + my script did not work like this:
Code:
choose(
 choose(1,2,3,4,5),
 choose(7,8,9,10,11),
 choose(13,14,15,16)
);
But this worked:
Code:
var selection;
selection = choose( (all items inside as above));
return selection;
But that is different case, also could not make the code like this:

Code:
var quality, item, item_id, randomizer;

randomizer = irandom_range(1,5);
for (i = 0; i < randomizer; i+=1) {

    item_id = choose("Apple","Banana","Carrot","Potato");
    quality = choose("Best","Average","Bad");
    var_item_returned[item_id,quality] /*Changed this line, it was before like this /*
}

ANYWAYS, the problem is that I really need more than 1-5 objects, it varies from 1-30 in my real project and each of the MUST have quality, also for future use they get more slots once your player picks them up (where it is from, europe, usa, asia (the item)).
Soo, I should just use normal variables or?
The player should be able to "store" many of these objects at the same, so only reason for that is Arrays in my opinion.

EDIT: But as adding, this for example:

Code:
item_id = choose("Apple","Banana","Carrot","Potato");
quality = choose("Best","Average","Bad");
var_item_returned = item[item_id,1];
How can I insert the item[item_id,1] <- 1 as quality? Or should I define it twice like
var_item_returned = item[item_id, 1];
var_item_returned = item[i,quality];

I just think that would not work... :D
 
Last edited:

NightFrost

Member
Too many code examples... what is your current code, what is it supposed to return, what are you seeing it returning, and how has your item array been initialized? Also, where does the code I suggested fall short? It returns an item and quality combination as a string. Do you need them returned separately?
 

Dagoba

Member
First of all the script chooses random integer, let's say 8.
Now we want 8 unique items from banana,carrot,potato or apple.
Each of them will have quality: high, average or bad.

I want to return it as: item[item_id,item_quality];
And then I want to draw that as text; when clicking a player, a text will appear for each item he has like this:

Apple, High
Apple, Bad
Banana, Average
Carrot, High
Potato, Average
Potato, Bad
Carrot, Average
Banana, Average

And I tried this:

Code:
for (i = 0; i < item[i]; i+=1) {
    draw_text(0,16+item[i]*2,var_item_returned);
}
But of course it will print error. So where is my problem? In the printing or the creation or with everything?
The variable names doesn't matter because they aren't decided yet.

EDIT: But I could use your example:
item = item_id + " " + item_quality;

I guess it works too. And sorry for not answering all of your questions, I tried to replace the quality as integer 1 item[item_id,1]; but it didn't seem to work.
 
Last edited:

jo-thijs

Member
So, it is as I thought.
Write "apple", "banana" and such to item[i, 0] and "high", "average" and "bad" to item[i, 1].
Then loop through them like this:
Code:
for (i = 0; i < array_height_2d(item); i++) {
    draw_text(0,16+i*2,item[i, 0] + " : " + item[i, 1]);
}
 
C

CedSharp

Guest
First of all the script chooses random integer, let's say 8.
Now we want 8 unique items from banana,carrot,potato or apple.
Each of them will have quality: high, average or bad.

I want to return it as: item[item_id,item_quality];
And then I want to draw that as text; when clicking a player, a text will appear for each item he has like this:

Apple, High
Apple, Bad
Banana, Average
Carrot, High
Potato, Average
Potato, Bad
Carrot, Average
Banana, Average

And I tried this:

Code:
for (i = 0; i < item[i]; i+=1) {
    draw_text(0,16+item[i]*2,var_item_returned);
}
But of course it will print error. So where is my problem? In the printing or the creation or with everything?
The variable names doesn't matter because they aren't decided yet.
I would've used a grid instead.
Why? Because grids have a lot more scripts you can use to play with them.
For example, you can shuffle and sort a grid, you can clear it, you can save it, etc.
Very useful in my opinion.

An item has a name and a quality, so you would have 2 columns, and you have a random number of items ( each item is a row )

here is an example:
Code:
   +--------+---------+
   | Name   | Quality |
   +--------+---------+
0  | Apple  | High    |
1  | Apple  | Bad     |
2  | Banana | Average |
3  | Carrot | High    |
4  | Potato | Average |
5  | Potato | Bad     |
6  | Carrot | Average |
7  | Banana | Average |
   +--------+---------+
So you need to generate a grid, with 2 colums, and 'x' rows ( x will be a random number ).

Here is a potential way of doing it:
Code:
items = ds_grid_create( 2,irandom_range( 4,10 ) ); // between 4 and 10 items
var i, item_name, item_quality;
for( i=0; i<ds_grid_height( items ); i++ ) {
    item_name = choose( "Apple", "Banana", "Carrot", "Potato" );
    item_quality = choose( "Hight", "Average", "Bad" );
    items[# i,0] = item_name;  // Save the name of the item in first column
    items[# i,1] = item_quality; // Save the quality in the second column
}
And then, when you want to show them on the screen, you can do a similar loop
Code:
var i, item_name, item_quality;
for( i=0; i<ds_grid_height( items ); i++ ) {
    item_name = items[# 0,i];
    item_quality = grid[# 1,i];
    draw_text( 16, 16 + (i*22), item_name + ", " + item_quality );
}
If you want more help about this, you can PM me and I'll gladly explain in details how all
of this works :D

-- NOTE --
I applied some corrections to my code based on jo-thijs's 2 following posts,
thanks to him for finding my typos :p

Regards,
CedSharp
 
Last edited:

Dagoba

Member
So, it is as I thought.
Write "apple", "banana" and such to item[i, 0] and "high", "average" and "bad" to item[i, 1].
Then loop through them like this:
Code:
for (i = 0; i < array_height_2d(item); i++) {
    draw_text(0,16+i*2,item[i, 0] + " : " + item[i, 1]);
}
Yes, that is the way I wanted it to print, I forgot you could do it like that... :oops:

I would've used a grid instead.
Why? Because grids have a lot more scripts you can use to play with them.
For example, you can shuffle and sort a grid, you can clear it, you can save it, etc.
Very useful in my opinion.

An item has a name and a quality, so you would have 2 columns, and you have a random number of items ( each item is a row )

here is an example:
Code:
   +--------+---------+
   | Name   | Quality |
   +--------+---------+
0  | Apple  | High    |
1  | Apple  | Bad     |
2  | Banana | Average |
3  | Carrot | High    |
4  | Potato | Average |
5  | Potato | Bad     |
6  | Carrot | Average |
7  | Banana | Average |
   +--------+---------+
So you need to generate a grid, with 2 colums, and 'x' rows ( x will be a random number ).

Here is a potential way of doing it:
Code:
items = ds_grid_create( 2,irandom_range( 4,10 ) ); // between 4 and 10 items
var i, item_name, item_quality;
for( i=0; i<ds_grid_height( items ); i++ ) {
    item_name = choose( "Apple", "Banana", "Carrot", "Potato" );
    item_quality = choose( "Hight", "Average", "Bad" );
    items[# i,0] = item_name;  // Save the name of the item in first column
    items[# i,1] = item_quality; // Save the quality in the second column
}
And then, when you want to show them on the screen, you can do a similar loop
Code:
var i, item_name, item_quality;
for( i=0; i<ds_grid_height( items ); i++ ) {
    item_name = grid[# i,0];
    item_quality = grid[# i,1];
    draw_text( 16, 16 + (i*22), item_name + ", " + item_quality );
}
If you want more help about this, you can PM me and I'll gladly explain in details how all
of this works :D

Regards,
CedSharp
Actually, that looks pretty nice way to do it, didn't think you could use grids for that o_o .
I guess I understand everything except for item_name = grid[# i,0]; <- No idea what that hashtag does :D

You can actually explain it here as well if someone struggles with the same problem as I do :)
Thanks for the help, will go and edit my script to see if it works the way I want!

EDIT: As you use grid[# i,0]; to print, did you call the script as "grid" so you call it like that?
Because my script is scr_choose_item() and then I would use scr_choose_item[# i,0]; ?
 

Dagoba

Member
Sorry for double post but I would like to try that out but I am still unsure what grid[# i,0]; does because "grid" is not defined anywhere (as I trust my eyes(should not)), and using scr_item_wanted[# i,0] would of course not work.

I have not tried it yet, everything is written up but I guess it will execute an error for unknown variable "grid" because it doesn't get colored.
 

Dagoba

Member
Yeah that's what I thought :) Thanks guys for help!
Now I can finally test everything out, hope it goes well.

Will inform if something goes wrong (firstly I try to fix it by myself), but once I get it working, I will mark this as solved.
 

Dagoba

Member
Did exactly what I have been told for, and encountered this problem:


Code:
___________________________________________
############################################################################################
FATAL ERROR in
action number 1
of Draw Event
for object obj_customer:

DoAdd :: Execution Error
 at gml_Object_obj_customer_DrawEvent_1 (line 40) -         draw_text( 16, 16 + (i*22), item_name + ", " + item_quality );
############################################################################################
The Draw Event:
Code:
var i, item_name, item_quality;
    for(i = 0; i < ds_grid_height(item_wanted); i++) {
        item_name = item_wanted[# i,0];
        item_quality = item_wanted[# i,1];
        draw_text( 16, 16 + (i*22), item_name + ", " + item_quality ); // <--- I EVEN TRIED THIS (draw_text(16,16 + (i*22), item_name + ", " + string(item_quality); <- as string(variable_name) worked before I had this kind of problem.
    }
This is getting quite annoying now.. :D

EDIT: Okay fixed it by add string(variable_name) for both variables (because doAdd error means something is wrong with "+")
Solved by now!
 
Last edited:

Dagoba

Member
I don't think that is the case or is it? Now it prints it as it should print. Yet it only gets 0,0 / 0,0 / 0,0 / undefined, undefined but I have not defined everything yet so it's up to my other script if it will work or not :D

EDIT: (100th million edit) It finally works! Thank you guys, you're very awesome to make me figure out with this! :)
 
Last edited:

Dagoba

Member
Yes it is okay since we figured it out! :)

Anyways there are some errors popping on my console:

Grid 19, index out of bounds writing [3,1] - size is [2,4]

This happens with many objects, it will only create two items as defined like:
Apple, High
Carrot, Average
then after 2 items, everything is like this:
undefined, undefined

So it looks like this for every single time I check what items there are:

Let's assume we have 5 items

Carrot, High
Potato, Bad
unefined, undefined
unefined, undefined
unefined, undefined

Looks like that when drawing the grids. Is the problem on scripts above or in my scripts? My code only does for loop and decides the item in there, but it's already posted above so there's nothing else but my console prints out of bounds errors. o_o
 

jo-thijs

Member
Have you changed every items[#i, ...] to items[#..., i]?
Can you show the exact code you're using right now?
 

Dagoba

Member
There would be more than 3,000 lines of code so I will just shorten it out.
Code:
    var randomizer;
    randomizer = irandom_range(1,100)
    if (randomizer <= 20)
    {
        amount_of_wanted_items = choose(17,18,19,20,21);
    }
    else if (randomizer >= 20 && randomizer <= 70)
    {
        amount_of_wanted_items = choose(8,9,10,11,12,13,14,15,16);
    }
    else
    {
        amount_of_wanted_items = choose(1,2,3,4,5,6,7);
    }

    total_items_wanted = amount_of_wanted_items;
  
    item_wanted = ds_grid_create(2,total_items_wanted);
    var i, item_name, item_quality;
  
    //Randomize x times the item they want depending on mood
    for(i = 0; i < ds_grid_height(item_wanted); i++)
    {
           
                item_name = choose("Banana","Carrot","Potato","Apple");
                randomizer = irandom_range(1,100)
                if (randomizer <= 60)
                {
                    item_quality = "Bad";
                }
                else if (randomizer >= 61 && randomizer <= 80)
                {
                    item_quality = "Average";
                }
                else
                {
                    item_quality = "High";
                }
                item_wanted[# i,0] = item_name;
                item_wanted[# i,1] = item_quality;
           
    }
It is something like that, slightly edited but the way it would not affect anything else.
Is there something wrong in that section? Only chances and the same way creating items as I was adviced to.
 

jo-thijs

Member
First of all, that code won't compile, because of the ending {.
Secondly, you're missing some blocks { ... }.
Thirdly, you did not change item_wanted[# i,...] to item_wanted[# ..., i] here.
 
C

CedSharp

Guest
There would be more than 3,000 lines of code so I will just shorten it out.
Code:
    var randomizer;
    randomizer = irandom_range(1,100)
    if (randomizer <= 20)
    {
        amount_of_wanted_items = choose(17,18,19,20,21);
    }
    else if (randomizer >= 20 && randomizer <= 70)
    {
        amount_of_wanted_items = choose(8,9,10,11,12,13,14,15,16);
    }
    else
    {
        amount_of_wanted_items = choose(1,2,3,4,5,6,7);
    }

    total_items_wanted = amount_of_wanted_items;
 
    item_wanted = ds_grid_create(2,total_items_wanted);
    var i, item_name, item_quality;
 
    //Randomize x times the item they want depending on mood
    for(i = 0; i < ds_grid_height(item_wanted); i++)
    {
          
                item_name = choose("Banana","Carrot","Potato","Apple");
                randomizer = irandom_range(1,100)
                if (randomizer <= 60)
                {
                    item_quality = "Bad";
                }
                else if (randomizer >= 61 && randomizer <= 80)
                {
                    item_quality = "Average";
                }
                else
                {
                    item_quality = "High";
                }
                item_wanted[# i,0] = item_name;
                item_wanted[# i,1] = item_quality;
          
    }
It is something like that, slightly edited but the way it would not affect anything else.
Is there something wrong in that section? Only chances and the same way creating items as I was adviced to.
I tried fixing your code:
Code:
    var randomizer;
    randomizer = irandom_range(1,100)
    if (randomizer <= 20)
    {
        amount_of_wanted_items = irandom_range( 17,21 );
    }
    else if (randomizer >= 20 && randomizer <= 70)
    {
        amount_of_wanted_items = irandom_range( 8,16 );
    }
    else
    {
        amount_of_wanted_items = irandom_range( 1, 7 );
    }

    total_items_wanted = amount_of_wanted_items;

    item_wanted = ds_grid_create(2,total_items_wanted);
    var i, item_name, item_quality;

    //Randomize x times the item they want depending on mood
    for(i = 0; i < ds_grid_height(item_wanted); i++)
    {
          
                item_name = choose("Banana","Carrot","Potato","Apple");
                randomizer = irandom_range(1,100)
                if (randomizer <= 60)
                {
                    item_quality = "Bad";
                }
                else if (randomizer >= 61 && randomizer <= 80)
                {
                    item_quality = "Average";
                }
                else
                {
                    item_quality = "High";
                }
                item_wanted[# 0,i] = item_name;
                item_wanted[# 1,i] = item_quality;      
    }
I had to modify only the last 3 lines: siwtched i and 0 and 1 :)
'i' should be second, not first. I'll edit my posts to reflect this.
 

Dagoba

Member
Yes finally it works! Not a single problems within the code anymore. Sorry I didn't quite understand the [..., 1] thing, would've understood exactly how it was told. :D (Sometimes I'm very tired when programming (and when I'm tired, I have more motivation than normally)). And yeah jo-thijs, my code wouldn't work because I quickly edited it and now everything is working perfectly. :)
 
Top