# Shifting values or tiles on a 2D grid (1D array)

I recently turned my practice project into a match3-type game.

The game uses a 6x10 grid, internally stored into a single array, with each item being a positive integer (0-based). I have a function to detect groups of the same type of a given size, but once the group has been deleted, the tiles above need to be shifted down.

The unordered index of each deleted tile is also stored into a separate array.

The language I'm working with is Linden Scripting Language (LSL), although language-specific answers aren't needed (but very helpful), so even general examples are welcome.

Edit: My recursive function so far:

shift(integer i) // i == index of Grid, COLS == columns/width (6)
{
if( (integer)grid[i] != -1 ) return; // blocked by deleted value

Grid[i] = (integer)Grid[i-COLS]; // copy value from above

if(i >= COLS) // haven't reached upper limit of grid
{
shift(i-COLS); // recursive call up
}
else
{
Grid[i] = (integer)llFrand(TYPES); // reached top, randomize tile
// TYPES == integer, maximum amount of types
}
}


Improvements needed:

• Don't copy deleted values from above (skip over)
• Stop recursing early if multiple values were deleted vertically
• Move horizontally and find the lowest point to begin recursing from

Limitations of the environment:

• Limited to 64KB of memory (bytecode + stack/heap)
• Each call may potentially use 512 bytes of stack
• What's the problem? Commented Jun 21, 2016 at 13:49
• I've added my current (unfinished) function to the question with clearer requirements. Commented Jun 21, 2016 at 17:31

What you should do, is store neighbor information in each of your Tile objects. This way, it makes things a heck of a lot easier when dealing with this type of game logic.

public class Tile {
public Tile Left;
public Tile Right;
public Tile Top;
public Tile Bottom;
}


Associate these neighbors in your initialization code somewhere, making sure you set the the links properly. You should be able to figure out how to do this, if not you will need to provide more information on your data, as I cannot guess how you are storing your level information.

Then you can easily do something like this:

for (int n = 0; n < Tiles.Count; n++)
{
if (Tiles[n].Bottom != null) {
if (Tiles[n].Bottom.Type == TileType.Empty) {
Move(Tiles[n], Tiles[n].Bottom);
}
}
}


And your Move function would look like:

void Move(Tile tile, Tile position) {
position = tile;
tile.Clear();
}

• To clarify: I'm working in a scripting environment (Linden Scripting Language) where you cannot create classes/objects/enums, and my entire grid/level is stored as a single "list" of integers, with additional width/height constants. Commented Jun 21, 2016 at 13:59
• I'm not asking anything more than what you already answered (which I appreciate!), but you did ask exactly how I was personally storing my data. Commented Jun 21, 2016 at 14:02
• Ah ok sorry. I was trying to figure out what you wanted me to elaborate on. Commented Jun 21, 2016 at 14:03