- Home /
finding matches in match3
this script generate board and look for matches, but it does not matching correctly. Balls in matches get iD 8. I tried different ways but didn't get good result
using UnityEngine;
using System.Collections;
public class Grid : MonoBehaviour {
public static int h = 10;
public static int w = 10;
public Transform ball;
static Color [] Colors = new Color[]{
Color.red,
Color.cyan,
Color.green,
Color.white,
Color.yellow
};
public int [,] board = new int [w,h];
void Awake (){
createBalls();
}
void Start()
{
checkMatchOnLoad();
PrintField();
}
public void createBalls()
{
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
Transform cloneBall = (Transform)Instantiate(ball, new Vector3(x,y,0), Quaternion.identity) as Transform;
int randomColor = Mathf.RoundToInt(Random.Range(0,Colors.Length));
cloneBall.renderer.material.color = Colors[randomColor];
board [x,y]=randomColor;
}
}
}
public void checkMatchOnLoad(){
for (int x = 0; x < w; x++){
int countUp =0;
for (int y = 0; y < h-1; y++){
if (board[x,y]==board[x,y+1]){
countUp++;
if (countUp>=2){
for(int cU=0; cU<countUp; cU++){
if(y-cU>=0)
board[x,y-cU]=8;
}
}
}
else{
countUp = 0;
}
}
}
}
public void PrintField()
{
string str = "";
int i, j;
for (j = h - 1; j >= 0; j--)
{
for (i = 0; i <w; i++)
str += " " + board [i, j];
str += "\n";
}
Debug.Log(str);
}
}
When I run this script I can receive something like that.
If matches have 4 or more balls, they didn't get iD8. As you can see in left down corner marked only 3 balls.
Answer by NoseKills · Jan 04, 2015 at 07:02 PM
One of your biggest problems in my opinion is that you are changing the data you're checking while making the checks on it.
If you look at the bottom left corner with a row of 4 green balls, in your loop you find the 3 balls and mark them as "8". After that the 4th green ball doesn't match the 3 previous ones because they are now 8s, not 2s.
You don't explain what kind of matches you will be needing to check in the end. Even if you fix the loop logic for now, it will still mess things up.
Let's say you want to check for horizontal matches after vertical ones. You can't do it anymore since a random selection of balls is now marked as 8 and you don't know which color they should match with.
this probably works as a fix for your existing code
for (int x = 0; x < w; x++)
{
for (int y = 0; y < h; y++)
{
//start checking matches from the coordinate above
int countUp = y+1;
// store the found color so we don't get mixed up
int foundColor = board[x, y];
// matchfinding
while ( countUp < h && foundColor == board[x, countUp])
{
countUp++;
}
// how mych did the matchfinding loop increment countUp == number of matches
int foundMatches = countUp - y;
// matchfinding loop exits when no match is found or when out of array bounds - so decrement.
countUp--;
// if enough matches
while ( foundMatches > 2 && y <= countUp) // countUp < h done in matchfinding. no need to check y < h
{
board[x, y++] = 8;
}
y = countUp; // continue from last matching ball. for-loop will increment y++ next
}
}
A step into the right direction would be to attach a " Ball
" script that holds the color/type to each ball prefab. Make board
array a Ball[]
instead of a int[]
and when Instantiating(), put the scripts from the prefabs into the board array. Make a public function setType(int type)
to the Ball script that can be used to change the type/color of the ball (store the passed in type
in a field in each Ball and make the function change the renderer color because type is tied to color). Then give the Ball script a public bool matched
or something you can use to mark the ball matched without changing it's type and color.
Thanks a lot!!! It is working. I will follow your advices.