- Home /
Match3 - How can I ensure the board starts with no matches?
I have followed a couple of tutorials and have gotten the basics down on how to create a "match 3" game:
Build a grid x*y and populate each 'cell' with random prefab
Detect click/tap to select object to move and which cell to move to
Check 2 switched objects for adjacent matching objects
Destroy if 3+ adjacent
Repopulate empty cells
This is all working fine (needs some cosmetic tweaks) but I almost always start off with matches in place on my grid.
I would like to check for matches post-repopulate - for combos and the like - so need some insight as to how to do that, but also I would like the first board the players sees to be match-free (rather than the game start and matches get made for you to clear any matches).
I have looked at Grim Grin's tutorials on Youtube but even that appears to be subject to this.
Thanks
If you're already able to check for matching prefabs then you can use a similar algorithm for spawning the grid. If there's two prefabs which would make a third prefab match don't just spawn it randomly, remove it from a list of possible prefabs then randomly select from those remaining.
Alternatively, after spawning the complete grid randomly, check for matching prefabs and swap the middle one. Though after swapping you'll need to ensure it doesn't then create a new type of matching prefabs (or replace it with the same prefab which was removed).
Answer by DoomGoober · Mar 12, 2016 at 02:49 PM
You can build the board so it doesn't have matches. As you move from lower left corner to upper right corner adding pieces to the board, simply check that the two pieces to the left or two pieces down are not the same color as the piece you are adding. If they are, choose another color.
Code below is straight from a game I'm working on so some parts of it might look weird. colorTypes is a List and represents the final output board (as 1D array):
//Generate the random board
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
ColorType colorType = ColorType.None;
do
{
int randomIndex = Random.Range(0, gemList.PrefabCount);
GameObject gemPrefab = gemList.GetPrefabFromIndex(randomIndex);
Gem gem = gemPrefab.GetComponent<Gem>();
colorType = gem.colorType;
}
while ((x >= 2 &&
colorTypes[(x - 1) + (y * width)] == colorType &&
colorTypes[(x - 2) + (y * width)] == colorType)
||
(y >= 2 &&
colorTypes[x + ((y - 1) * width)] == colorType &&
colorTypes[x + ((y - 2) * width)] == colorType));
colorTypes.Add(colorType);
}
}
Algorithm from: https://www.raywenderlich.com/66877/how-to-make-a-game-like-candy-crush-part-1
Thank you I have been looking everywhere for a code to do just this. Any pointer in its implementation would be very helpful.
thank you
Answer by Kiwasi · Jul 17, 2014 at 10:51 PM
Your overall strategy needs to be something like this.
Set up a virtual board
Iterate through all positions of the board, checking for matches
Replace any matches with another random tile
Repeat until the board is valid
Make the board visible to the player
An alternative way to keep generating random boards until one with no matches is found. This depends on the cost of generating a new board, and the likelihood of a random board being valid.
Hi Bored$$anonymous$$ormom, thanks for your response. Your step for replacing matches - would you suggest checking each tile in the way a move is checked and replace that specific tile, or the whole matched set? Then once changed, start the check again from 0,0?
Thanks
It depends a lot on your architecture.
Randomly replacing the specific tile, then checking that for matches, and repeating until no matches are found should work. However you may get a situation where this takes a while, or is impossible.
For an impossible solution consider a game with only four colours (red, blue, green, yellow). Consider a tile that has two red above, two blue to the left, two green below and two yellow to the right. No matter what tile you pick it will always form a match.
As for the rechecking, you can probably save yourself some time by only rechecking from the point that tiles could be affected. So if you make a change on line 3 it might not be necessary to go back to line 1.
Sorry I couldn't be more specific, a lot depends on your exact implementation of the game.
Another approach is to populate one cell at a time. From the list of all available tile pieces remove any that would cause a match at that location, then select a piece at random from the remaining set.
Example: available pieces are [A,B,C,D,E]... cell neighbours are A,A,C,D... select from [B,E] of that slot.
This should be a faster and potentially more robust algorithm.
To avoid the 'impossible' case make sure there are at least 5 distinct pieces to choose from (on a square board... for anything else it's "degrees of freedom" + 1).
The are no 'impossible' cases which require at least "5 distinct pieces", it's possible to complete a square board with only two unique objects where no three objects lie on a horizontal, vertical or diagonal line.
Its pretty clear now that my original answer was perhaps the least efficient way that would actually work.
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
finding matches in match3 1 Answer
Making a bubble level (not a game but work tool) 1 Answer
How to Destroy items in Match 3. 2 Answers