• 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!

Bug on for loop?

M

meme

Guest
Hey guys so I have this code right here:
GML:
var _yLength = LevelManager.gridY;
var _xLength = LevelManager.gridX;


// Indices
// _horIndexMin, _horIndexMax, _verIndexMin, _verIndexMax
var _indexPrevious = [max(playerPrevious[0] - 1, 0), min(playerPrevious[0] + 1, _xLength-1),
                    max(playerPrevious[1] - 1, 0), min(playerPrevious[1] + 1, _yLength-1)];
                    
var _indexCurrent = [max(playerGridX - 1, 0), min(playerGridX + 1, _xLength-1),
                    max(playerGridY - 1, 0), min(playerGridY + 1, _yLength-1)];


for (var i = _indexPrevious[2];i <= _indexPrevious[3];i++)
{
    for (var j = _indexPrevious[0];j <= _indexPrevious[1];j++)
    {
        gridOptimizer[i][j] = -1;
    }
}


// Set the grid optimizer using CURRENT POSITION
for (var i = _indexCurrent[2];i <= _indexCurrent[3];i++)
{
    for (var j = _indexCurrent[0];j <= _indexCurrent[1];j++)
    {
        gridOptimizer[i][j] += 1;
    }
}
playerGridX,Y is the player's position snapped on a grid. playerPrevious is just the previous grid location of the player. So I this code is used for optimization, its kinda complicated to explain how it works, but this "gridOptimizer" is the one that has a problem. "gridOptimizer" is a 2d array that will be updated when player's grid position changed (e.g. player move to other grid). It will replace a 3x3 square in this grid to be -1 for previous position(playerPrevious) and then create replace 3x3 square by adding 1 for current position (playerGridX, playerGridY). At the end of everything, a loop will check through each value of gridOptimizer, and if -1 then deactivate that grid, if 1 then activate.

PROBLEM: The "gridOptimizer" is a 2d array and "+= 1" does not execute properly, BUT if I do this:

GML:
// Set the grid optimizer using CURRENT POSITION
for (var i = _indexCurrent[2];i <= _indexCurrent[3];i++)
{
    for (var j = _indexCurrent[0];j <= _indexCurrent[1];j++)
    {
        gridOptimizer[i][j] += 1;
    }
 
    deb_grid(gridOptimizer); // Just to print 2d grid beautifully
}


It works properly and as expected...Yea the only difference is the "deb_grid" which is basically print a 2d array beautifully:
GML:
function deb_grid(_grid){
    
    for (var i = 0;i < array_length(_grid);i++)
        show_debug_message(_grid[i]);
}


I was stuck with this situation for almost 2 hours now. If you have any suggestion feel free to leave a reply!
 
Last edited by a moderator:

Nidoking

Member
What is the actual content of the deb_grid function? It's hard to take at face value that it does nothing relevant when we can't see it.

Also, is this itself in a function where gridOptimizer is passed in? You don't appear to be using array accessors, so modifying the arrays in place is only updating a copy of the arrays. Perhaps passing it to the deb_grid function is causing it to act like it's using an accessor and overwriting the original array.
 

Tazdraperm

Member
Is gridOptimizer an instance variable or an argument inside a function/script? In the second case, I would suggest you use an accessor:
Code:
gridOptimizer[@i][@j] += 1;
 

samspade

Member
I think there's some missing information in your post that could be helpful in determining what's going on. So here are some questions that might help find an answer:
  • What does not increment properly mean?
  • What are the values held by _indexCurrent
  • What does the code in deb_grid do?
  • Where is this code located?
  • Is this in a function (either method variable or script function) or directly inside an event?
  • Have you stepped through this loop in the debugger and checked all the values as they occur (paying special attention to the array references)?
 
M

meme

Guest
I think there's some missing information in your post that could be helpful in determining what's going on. So here are some questions that might help find an answer:
  • What does not increment properly mean?
  • What are the values held by _indexCurrent
  • What does the code in deb_grid do?
  • Where is this code located?
  • Is this in a function (either method variable or script function) or directly inside an event?
  • Have you stepped through this loop in the debugger and checked all the values as they occur (paying special attention to the array references)?
Sorry, I already put a proper explanation >.<
 

samspade

Member
wuuut it works! Whats the difference with this symbol "@" ?!
It's the accessor symbol and is necessary to avoid the copy on write behaviors that arrays have if you are writing to the second reference of the same array—which will always be the case if the array is an argument passed into a function or if you have copied it and are writing to the copy. You can see what is happening if you step through the loop in the debugger by paying attention to the array references. I don't actually see where this is occurring in your code though (as it doesn't seem to be in a function and I don't see a copy of the array). But I'm glad its fixed.
 
M

meme

Guest
It's the accessor symbol and is necessary to avoid the copy on write behaviors that arrays have if you are writing to the second reference of the same array—which will always be the case if the array is an argument passed into a function or if you have copied it and are writing to the copy. You can see what is happening if you step through the loop in the debugger by paying attention to the array references. I don't actually see where this is occurring in your code though (as it doesn't seem to be in a function and I don't see a copy of the array). But I'm glad its fixed.
Oh all of these occurred on user event 0, and also can you explain what second reference means? So everytime I want to modify an array its better to use "@" ?
 

samspade

Member
Oh all of these occurred on user event 0, and also can you explain what second reference means? So everytime I want to modify an array its better to use "@" ?
By second reference I mean something like this:

GML:
array_a = [0, 1, 2];
also_array_a = array_a;
You only need to use the accessor if you are modifying an array that has more than one reference to it stored in variables, and technically them only with the non-original variable, but in most cases this is just when passing an array as an argument in a function. But if you do the above then you have two variables that store a reference to the same array. This post has more information on them.
 
Top