GML How do I check if a FOR loop is done?

Dr_Nomz

Member
I want to delete a list position only AFTER a loop has been completed, I can't seem to get it working.

I've tried a few variations to get this to work, but the ds_list size remains the same.
Code:
for (o=argument0; o<ds_list_size(option); o++){
  ds_list_replace(option,o,option[|o]-1);
  if o==ds_list_size(option) ds_list_delete(option,argument0);
  }
Is there a correct way to check for this?
 

O.Stogden

Member
Any code after the 'for' loop should only be run once the for loop has finished.

Code:
for (o=argument0; o<ds_list_size(option); o++){
  ds_list_replace(option,o,option[|o]-1);
  }

ds_list_delete(option,argument0);
Should work
 

Dr_Nomz

Member
No it seems to be trying to run them all at once, because it's not shifting the numbers at all like that, like the reference is deleted before the for loop even begins.

I'm using a script to run this if that's important.

EDIT: Also tried to look for "else" in the manual but there's no entry for it. I was hoping to find something like that but for a for loop.
 

kraifpatrik

(edited)
GameMaker Dev.
The thing with your code is that o will never be equal to ds_list_size inside the for loop when the condition is o < ds_list_size. If you always want to delete the last element, you can just put the ds_list_delete after the for cycle (without the if o == ds_list_size check).
 
D

dannyjenn

Guest
What exactly are you trying to do?

If I'm understanding you correctly, I get the impression that you simply want to remove option[|argument0] from the list? If that's the case, there's no reason to use a loop to shift all the values around. Because ds_list_delete(option,argument0) does that automatically. (You would need to shift the values if you were using an array, but not a ds_list...)
 

Tsa05

Member
Just to clarify, why doesn't ds_list_delete(option,o); work?

You're looking through a list, moving all of the values up by one, then deleting the one.... which is the same as just having deleted the one.

[0, 1, 2, 3, 4, 5] Let's try running your idea on index 2. (You know, btw, that your game will crash if o is zero, ya?)

Each loop, we replace the element at index o with the element at o-1, starting at o=2,
[0, 1, 1, 3, 4, 5] (o is 2, replace item at 2 with item at 1)
[0, 1, 1, 1, 4, 5] (o is 3, replace item at 3 with item at 2)
[0, 1, 1, 1, 1, 5] (o is 4, replace item at 4 with item at 3)
[0, 1, 1, 1, 1, 1] (o is 5, replace item at 5 with item at 4)

I detect a problem.

Final part of your strategy: if o is ever equal to the size, delete 2. Well, that'll never happen. In a list of size ONE, the single thing in the list is at index ZERO. In a list of size 6, the sixth element in the list is index 5. The last index in a list will never be the same number as the size of the list.

Now, consider merely deleting index o in option:

[0, 1, 2, 3, 4, 5] (o is 2, delete item 2)
[0, 1, 3, 4, 5]

Tadaaa! Index 2 is removed!

So....what are you really trying to do here? Do you want to delete the item at index o and then insert something new into the front of the list, perhaps?

Edit: heh, I got side-tracked while replying and dannyjenn beat me to the essential question :D
 
Last edited:

kraifpatrik

(edited)
GameMaker Dev.
The code which the author posted is not replacing values with previous ones, but subtracting 1 from each value though. So if the question still is "where is the for loop is done", the answer is

Code:
var _size = ds_list_size(myList);
for (var i = 0; i < _size; ++i)
{
    if (i == _size - 1)
    {
        // either here
    }
}
// or here, without any checks
 
Last edited:
I'd say stop with this dialogue system until you understand data structures better. You are blindly stumbling around and it's hard for anyone to properly help because it doesn't seem like you yourself know what needs to be happening. Thinking that a loop needs an else statement or something like that is simply an incorrect mental model of how a loop functions. Try starting with something more basic, perhaps a small inventory system and explore data structures through that. Learn how to delete appropriate elements, add elements into the appropriate areas, etc. Once you have a firmer grasp on what is actually happening under the hood of these things, you will come back, laugh at your old code and be able to get what you need happening in a far better way. Simply piecing together random stitches of code that you do not understand will not build a system that you can actually use properly, all it will do is cause you grief.
 

TheouAegis

Member
I'll also add, since this topic is somewhat "resolved" in the sense that the cited issue I assume has been resolved elsewhere, another method of checking if a for loop has finished -- although this is for a much different use.

Code:
for(var i=0; i<10; i++) {
    if troops[i] == noone {
        troops[i] = instance_create(x+32, y, queued_unit);
        break;
    }
}
if i == 10 show_message("No room for any more troops!")
 
D

dannyjenn

Guest
The code which the author posted is not replacing values with previous ones, but subtracting 1 from each value though.
I noticed that too. But if he's trying to do what I think he's trying to do (and should be using an array rather than a ds_list), he should be replacing the values with the next one (i.e. option[o+1]), not the previous one (option[o-1]).

But if he did want to replace the values with the previous ones, he'd have to loop backwards. Because otherwise option[o] gets set to option[o-1], then the following iteration option[o] gets set to option[o-1] (which is the same as option[o-2]), and the third iteration option[o] gets set to option[o-1] (which is the same as option[o-3] and option[o-2]), and so on... basically changing every value from index argument0 onwards to become the value of option[argument0-1].
 
Last edited by a moderator:
Top