Assistance with Match-3 Style Game Logic

Hi guys,

I would like to build a “connect the dots” style game.

I already know how to fill in the grid for the game and i know how to remove the objects when the user selects a pair.

The problem is, i am not sure how to fill in spaces when objects are removed.

For example, if 2 items are removed from row 1 and 1 item is removed from row 2. what would be the algorithm to drop the items in row 2 down to slots, and the items in row 1 down 1 position above where the item was removed.

I hope i exlained my question well. For this game i will be using Libgdx(which is java) so any java pseudocode will be GREAT. I will also be using sprites of libgdx and tween engine to move objects.

Thanks so much guys, hope i can find the help i need.

I’m doing something similar currently, so I can help I guess :smiley:

My first solution was something like this


for( x = 0; x < MAX_CELLS_X; x++ ) {
     for( y = 0; y < MAX_CELLS_Y; y++) {
          if( cell[x][y].isEmpty() ) {
               for( d = y + 1; d < MAX_CELLS_Y; d++ ) {
                    cell[x][d].getOccupant().moveBy( 0, -((d-y)*CELL_SIZE));
                    }
          }
     }

So this was off the top of my head, sorry if it won’t compile ;D. Anyway, the moveBy is a scene2D function. You may have your own implementation here of course (like setting a boolean doFall or something) and have the occupants update each frame or something like that.

Hope it helps.

Ah. Thank you for that. :slight_smile:

But how exactly does the cell[][] work?

Of what type is it?

And how do you go about updating the occupant?

I’m guessing get occup just returns the sprite.

Thanks a lot for your help so far!

Judging from that statement I would say you need to take a step back fromd games and try to learn Java first. That is of a multi deminsional array type, which pretty much means it holds a bunch of references to blocks of memory (your objects). This is basic coding though, and I highly stress you stop trying to make a game and spend the time to learn programming first. You’re only hurting yourself right now.

LOL. Actually i know java very well. I was asking what data type is it. Sprite, int, etc. :wink: I am fully aware of what an array is. This is like my 5th game. Just not sure how the match-3 thing works.

@Siesmic how do you go about updating the occupants each frame?

Well if you do it with scene2D you don’t need to update them manually, you just add the action. But if you do the other method, where you set a boolean (like needsToFall or something), then you iterate through each of your Cell-occupants (extensions of Sprite), check if they need to fall (have the boolean set to true) and update their y-position accordingly.

Edit: Also, once they’ve fallen CELL_SIZE update the cell below to hold a reference to the sprite, set the needToFall boolean to false, so they don’t fall forever :slight_smile:

Yes I will be using sprites.

But how do I iterate through to check if the sprite needs to be moved down?

With a for loop like above


for( x = 0; x < MAX_X; x++ ) {
     for( y = 0; y < MAX_Y; y++ ) {
          if( cells[x][y].getOccupant().needsToFall() {
               cells[x][y].getOccupant().fall(delta);
               }
          }
    }

So basically.

It first checks if a cell is empty or needs to fall. Then, if it is empty, we go up one row and move that item down to the empty position, and this will continue to happen for all the empty positions until the loop finishes? Correct?

But what if, more than 1 item is removed from a column? Or if more than 1 item is empty in column?

I ask because in my game, the user can connect as many matching sprites as possible. This means they can remove more than 1 item from a column, vs jus 3.

wrote this up in a couple minutes, assuming I understand your question correctly and I didn’t make any dumb mistakes due to the fact that I didn’t test this and wrote it up so quick, it should work.


public void scanForDrops(int maxX, int maxY)
{
	int spaces = 0; //counts spaces
	int occupantsAbove = 0; //occupants above the point the loop is at
	boolean firstOccupantFound = false; //becomes true when the first cell in the column with a Piece is found
	for(int x = 0; x < maxX; x++)
	{
		spaces = 0;  
		occupantsAbove = 0; 
		firstOccupantFound = false;
		for(int y = 0; y < maxY; y++)
		{
			if(cell[x][y].hasOccupant() )
			{
				if(!firstOccupantFound)
				{
					firstOccupantFound = true; 
				}
				occupantsAbove++;  
			}
			else if(!cell[x][y].hasOccupant() && firstOccupantFound) //spaces above the first occupant dont matter
			{
				spaces = checkSpaces(x, y, maxY);  //gets spaces under this starting at this point
				dropAbove(x, y--, occupantsAbove, spaces); //drops all the pieces spaces amount of times starting at the piece above this space
				y+= spaces + 1; //puts y down past the spaces and one extra because we did a y-- on the last line
				spaces = 0; //now there are no spaces in between and itll keep checking down the line
			}
			
		}
	}
}

public int checkSpaces(int x, int y, int maxY)
{
	int spaces = 0;
	while(y < maxY && !cell[x][y].hasOccupant())
	{
		spaces++;
		y++;
	}
	return spaces;
}

public void dropAbove(int x, int y, int above, int spaces) // drops every piece above spaces amount of times
{
	for(int i = 0; i < above; i++)
	{
		cell[x][y - i].getOccupant().moveTo(x, y - i + spaces); // something like this dunno how your code looks
	}
}

@LionKing

Nice! Thanks for that. I understand what your code does for the most part. :slight_smile:

A few questions, for the cell array, should this be a extended class of the sprite class as the data type?

And then create a method hasOccupant() in the Sprite class? Or does it have some type of other data type it should hold?

Also, how would i go about determining if a cell has an occupant?

Thanks so much man.

Ok, so i have it semi-working with this code:

private void moveObjectsDown(int x, int y) {
		
		
		// TODO Auto-generated method stub
		
		
		for (GameObject o : gameObjects) {
			
			if(o.getX() == x && o.getY() == y+1){
				
				// Animation of an object position to the coordinates (100,200), in one second
				Tween.to(o, Accessor.POSITION_Y, 1.0f).target(y, y).start(game.tweenManager);
				//o.setPosition(x, y);
				
				y++;
				
				
			}
			
			
			
			
			
		}
		
	}/code]

This works flawlessly when only one item is removed from a row. But when i remove two items or more from a row, it only moves the items left in that column to the highest position.

I guess a way i could fix this would be to figure out the item with the lowest y position in that particular column and then drop the items according, but i am not sure how to do this.