• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Legacy GM [SOLVED]Ds_List: adding /deleting random items in a ds list

N

nicoltoons

Guest
Hello, I'm relatively new to ds_ lists.

Question: How do I randomly add or delete items from a ds list?

If you have 3 deleted items from a ds_list, how do you randomly add one of them back?
How do you also delete an item from a ds_list randomly?
 
To delete a random entry you would find the length of the list (minus one), and set a random range from 0 to that length. Whatever the random range returns - you delete that index. Look up 'random_range' / 'irandom_range' in the manual - I'm not quite sure of the difference between them, but they have a minimum and maximum value and will return a random choice from between the two points. i think 'irandom_range' is the one you'd want, as it returns a rounded own value and you want a whole number.

But if you want to know what you've deleted (so it can be restored), then you'd want another list which stores the information of deleted indexes so you could compare the two. If you wanted the "resurrection" to be random, then you'd repeat the random range step.
 
Np - you'll find the functions for randomizing things under 'Real Number Functions'. I edited my previous post because I'm not quite sure which one of the two you'll need.

Your code would probably be like this:

var size = ds_list_size(active_list) - 1; // gets the list size, and minuses one - as indexes start at zero
var list_range = irandom_range(0, size); // sets the random range to between zero and end size
var value = ds_list_find_value(active_list, list_range); // finds the value at that index position (the returned number of list_range)
ds_list_add(destroyed_list, value); // adds the value found at that index to the destroyed list
ds_list_delete(active_list, list_range); // deletes the previously returned index position from the original list

That's off the top of my head, but I'm reasonably sure it's what you'd need. One thing to note is that every random function always returns the same result when first run, so they won't differ until the function is called again. This is intentional, but can be set to truly random by having the command 'randomize()' set right at the start of your game. It's explained why in the manual.
 
N

nicoltoons

Guest
Np - you'll find the functions for randomizing things under 'Real Number Functions'. I edited my previous post because I'm not quite sure which one of the two you'll need.

Your code would probably be like this:

var size = ds_list_size(active_list) - 1; // gets the list size, and minuses one - as indexes start at zero
var list_range = irandom_range(0, size); // sets the random range to between zero and end size
var value = ds_list_find_value(active_list, list_range); // finds the value at that index position (the returned number of list_range)
ds_list_add(destroyed_list, value); // adds the value found at that index to the destroyed list
ds_list_delete(active_list, list_range); // deletes the previously returned index position from the original list

That's off the top of my head, but I'm reasonably sure it's what you'd need. One thing to note is that every random function always returns the same result when first run, so they won't differ until the function is called again. This is intentional, but can be set to truly random by having the command 'randomize()' set right at the start of your game. It's explained why in the manual.
Thanks a bunch! I'm testing it now
 
N

nicoltoons

Guest
Hi @the_dude_abides i forgot to mention that the items collide with another item before they get deleted.At that point, I add them to the deleted_list but irandom_range can only give me the position of the random item selected and not the index ie spr_orange so it doesn't do what I want it to do.

The deleted items go into the destroyed list to be added to the active list when a powerup collides with the collision object too.

Another powerup takes items from the active List and adds them to the destroyed list
 
I think I may have misunderstood your post. My answer was about randomly getting indexes. By the sounds of it, what you want to do is a bit trickier to explain and I may need a clearer explanation. But this may help you......

ds_list_find_index will look for a value within a list, and return its index if it exists, or -1 if the value is not found. So if there's a specific value you want to check for - that's the function.

It can be used with numerical values (assign a number to each powerup - bombs = 1, mine = 2 etc) , or strings - such as "bomb" / "mine".
 
N

nicoltoons

Guest
Thanks @the_dude_abides . Thanks for being patient with me.
Let me try to explain better.
I am spawning an object obj_fruit randomly and assigning different sprites to it using a ds list
The aim of the game is to collect the right fruits and avoid the wrong ones
so I have a rightfruit ds list and a wrong fruit ds list . The right fruit ds list has sprites like spr_apple, spr_banana, spr_orange, spr_grapes, spr_peach
the wrong fruit ds list has fruit like spr_kiwi, spr_carrot, spr_augberine etc

If you collect the right fruit, it gets cancelled from a shopping list. You have 2 powerups.

The negative powerup ,if collected, returns a random rightfruit you have collected to the rightfruit ds list and un-cancels it.
the positive powerup, if collected, deletes an item from the rightfruit ds list.
 

Hyomoto

Member
At it's simplest you are simply wanting to add and subtract items from a list:
Code:
var _index = ds_list_find_index( list, fruit_to_find );

ds_list_delete( list, _index );
That takes care of getting rid of one of our fruit. To find a random fruit in that list:
Code:
var _random_fruit_to_choose = irandom( ds_list_size( list ) - 1 );
The -1 in this case is important. All data starts at position 0. So if we have a list of 3 items, they are index 0, 1 and 2, but if we count them we get 3. However, irandom will return a number 0 through 3, and 3 would be too high. So we reduce that number by 1 and get 0 through 2, which represents the positions in our list. The hardest part of what you are asking is adding a fruit back to the list, but this just requires you to also have a list of all the possible fruit to add back:
Code:
var _random_fruit_to_choose = irandom( ds_list_size( list_of_collected_fruit ) - 1 );

ds_list_add( list_of_fruit_to_collect, list_of_collected_fruit[| _random_fruit_to_choose ] );
ds_list_delete( list_of_collected_fruit, _random_fruit_to_choose ] );
The main idea here is that if you've tracked which fruit you have collected, it's very easy to just randomly pick one of those to put back. I hope this information gets you started, but if you still don't understand we'll certainly try our best until you do.
 
Last edited:
N

nicoltoons

Guest
At it's simplest you are simply wanting to add and subtract items from a list:
Code:
var _index = ds_list_find_index( list, fruit_to_find );

ds_list_delete( list, fruit_to_find );
That takes care of getting rid of one of our fruit. To find a random fruit in that list:
Code:
var _random_fruit_to_choose = irandom( ds_list_size( list ) - 1 );
The -1 in this case is important. All data starts at position 0. So if we have a list of 3 items, they are index 0, 1 and 2, but if we count them we get 3. However, irandom will return a number 0 through 3, and 3 would be too high. So we reduce that number by 1 and get 0 through 2, which represents the positions in our list. The hardest part of what you are asking is adding a fruit back to the list, but this just requires you to also have a list of all the possible fruit to add back:
Code:
var _random_fruit_to_choose = irandom( ds_list_size( list_of_collected_fruit ) - 1 );

ds_list_add( list_of_fruit_to_collect, list_of_collected_fruit[| _random_fruit_to_choose ] );
ds_list_delete( list_of_collected_fruit, _random_fruit_to_choose ] );
The main idea here is that if you've tracked which fruit you have collected, it's very easy to just randomly pick one of those to put back. I hope this information gets you started, but if you still don't understand we'll certainly try our best until you do.
Thank you Hymoto. I'll try this and let you know. Thanks again
 
N

nicoltoons

Guest
You guys are fantastic @the_dude_abides and @Hyomoto . You have solved my problems!

You gave me the same codes; all I needed to do was to find the value denoted by the random index. This is the code for the item that adds the item to the original list
random_fruit = irandom(ds_list_size(destroyed_list) -1)
value = ds_list_find_value(destroyed_list,random_fruit)
ds_list_add(rightfruit,value)
ds_list_delete(destroyed_list,random_fruit)

and I used another variable to check if the item has been added to the list or collected by the cart. It works perfectly!

@the_dude_abides and @Hyomoto you guys rock!!!! Thanks for this!
 
N

nicoltoons

Guest
I have just seen that the positive powerup doesn't always cancel out an item.
Is this because its checking the ds list while the same ds list is spawning objects? Sometimes it returns an undefined value.
What do you think I can do about this?
 
The list size (if populated with data) is always one more than how the indexes are numbered. When you are getting the list size you are taking off one, as indexes start at zero. A list of 6 entries would have a final index number of 5.

If the list size is zero, then taking off one would equal minus one. Accessing any position before zero, or beyond the final index, will return "undefined".

To stop this - before accessing the list, use:
Code:
if ds_list_size(whatever) > 0
{do whatever}
I'd imagine that is your current problem - the list is empty
 
N

nicoltoons

Guest
The list size (if populated with data) is always one more than how the indexes are numbered. When you are getting the list size you are taking off one, as indexes start at zero. A list of 6 entries would have a final index number of 5.

If the list size is zero, then taking off one would equal minus one. Accessing any position before zero, or beyond the final index, will return "undefined".

To stop this - before accessing the list, use:
Code:
if ds_list_size(whatever) > 0
{do whatever}
I'd imagine that is your current problem - the list is empty
Yes I did that before spawning. My code

if(!ds_list_empty(rightfruit))
{
rightitems = instance_create(xpos, ypos, obj_stew);
rightitems.sprite_index = ds_list_find_value(rightfruit, 0);
{
ds_list_delete(rightfruit, 0);

}

}
 
N

nicoltoons

Guest
Yes I did that before spawning. My code

if(!ds_list_empty(rightfruit))
{
rightitems = instance_create(xpos, ypos, obj_stew);
rightitems.sprite_index = ds_list_find_value(rightfruit, 0);
{
ds_list_delete(rightfruit, 0);

}

}
Yes I did that before spawning. My code

if(!ds_list_empty(rightfruit))
{
rightitems = instance_create(xpos, ypos, obj_stew);
rightitems.sprite_index = ds_list_find_value(rightfruit, 0);
{
ds_list_delete(rightfruit, 0);

}

}
Yes I did that before spawning. My code



if(!ds_list_empty(rightfruit))
{
rightitems = instance_create(xpos, ypos, obj_stew);
rightitems.sprite_index = ds_list_find_value(rightfruit, 0);
{
ds_list_delete(rightfruit, 0);

}

}



My code for removing an item from the list
if ds_list_size(rightfruit) > 0
{
random_fruit = irandom(ds_list_size(rightfruit) -1)
value = ds_list_find_value(rightfruit,random_fruit)
ds_list_add(destroyed_list,value)
ds_list_delete(rightfruit,random_fruit)
}

The object only does this sometmes
 
As far as I know - there's only two ways for a created list to return "undefined" when accessed.

1) Checking an index that's beyond the number of entries. Unlike checking an array position that's out of bounds this just returns undefined, rather than throwing an error.

2) If undefined was actually entered as a value into the list, since it does have a numerical value. Something like -1, or - 4. Can't recall off the top of my head what the value is. [EDIT Not sure of this actually, since entering undefined into a list just shows undefined when you access it]

I would set up a for loop in a draw event, and have it show onscreen what is in each ds_list. Also do the same for the variables you are using, and just make sure that all the values are what you expect them to be. If everything is present and as you expect - then its something else, and would need further investigation.
 
N

nicoltoons

Guest
Thanks @the_dude_abides I set up a do loop to check if value is an undefined value and to do the irandom function all over again if it was. I'll check my code again. There must be something I'm doing wrong
 
N

nicoltoons

Guest
@Hyomoto your idea worked. What I needed to do was to add the first line from @the_dude_abides code
var index = irandom(ds_list_size(duplicate_list) -1)
value = ds_list_find_value(duplicate_list,index)
ds_list_delete( duplicate_list, index );

so I made a duplicate list for the right items because the original list was spawning the objects and deleting their positions on the list immediately.
the duplicate list was just there to delete remaining items.

Thanks guys!
If I haven't said it before, you guys really ROCK!!!!!!!!
 
Top