Match Mechanic Help

I’ve been trying hard to figure out how to make the match mechanic, but have not come across a situation where the mechanic is broken or that errors pop up on my script. I’m stumped. People tell me I need a 2d array of some sort. But what am I supposed to look at? How can I make the grid check for a horizontal of vertical match 3?

It would really help if you told us a little bit more about what you are trying to do, and showed the code you already have. Remember that the issue you are working at is new to us, as we are all working on different things. Also note that you have not told us anything about additional contraints, so all you are asking is for a simple way to find if you have a match of three either horizontal or vertically. I’m therefore assuming that the grid is filled with a Maximum of one such occurence.

That being said, yes, you’ll need a grid. I recommend you take a grid paper to initially model the Problem. Number the axes (top-down and across) from 0 to 9, so you can identify each field, e.g. (3, 8) is the field 3 across, 8 down. The numbering will be identical to how you access the array (I stongly suggest you read up on Arrays).

Now, how would you find if there are three items in a grid horizontal or vertical? The issue can become quite simple if you look at it the right way, but become very complex if you don’t.

Take a pen to your grid, and fill in the two possible configurations where such an event occurs - horizontal and vertical.

Now, the intuitive approach would be to look at this and say: OK, if I have a grid Position occupied at (3,8), i can simply check if its neighbour to the right (at 4,8) is also occupied, and if that is occupied, check if the one next to that (5, 8) is also occupied (note that the horizontal index increases predictably: 3-4-5). If so, you have a match. If that fails, do the same for down. So write a simple function lookRightAtGridPosition(x,y) that returns true or false for any grid position if there are three horizontally, and another one lookDownAtGridPosition(x,y) that’ll do the same looking down.

You scan the entire board for all x and y until you find a three-match, or until you have completed the scan. When you scan, remember that your scan must correctly handle the edge cases: When you start at (3,8) and start looking down, you’ll find that if you go down two rows, you’ll cross the limits of grid, which will create an error. So you may be tempted to only scan the board in the 0 though 7 range both horizontally and vertically. but that will leave a two Units wide stripe on the sides that could contain 3-matches in the not-scanned for direction (down on the side, right at the bottom). You’ll need to code for that separately.

It’s a match 3 game where you drop blocks in a 5 by 8 grid. The controls are simple, left and right to move the block, and down to scroll to the bottom. And surprisingly enough the pieces are a single unit. And right now, I’m using 6 colors: Red, Orange, Yellow, Green, Blue, and Purple. I’m making a prototype for it, but I still need that piece. Once I have that and the prototype is complete, I plan to make it a single-player campaign game for itch release. But before that, I would have to take a break, as this is giving my head a run for its money.

well, you are all set then

Well JUST to be sure you know what the absolute balls I’m talking about, it’s this:

The position (0,0) is the bottom left corner. Keep in mind that this is like puzzle league.

Right. All that you now need to do is write the code. And if you have a specific problem, describe it, post the code, and we’ll do our best to help you.

Well, for all (x,y) from (0,0) to (height - 3, width-3) check if pieces at (x+1, y), (x+2, y) or (x,y+1. x, y+2) are of the same color. If they are, score, destroy, drop down all pieces having empty square underneath. Sounds pretty easy task. What is the problem?

Actually. it’s slightly more involved (but not much) because you need to check the last two columns for 3-aligned vertical, nd the last two rows for 3-aligned horizontal. But other than that,I agree, easy.

1 Like

Well for starters, here’s the code for the grid and the pieces:

``````public class Board : MonoBehaviour
{
public static int gridwidth = 5;
public static int gridheight = 12;

public static Transform[,] grid = new Transform[gridwidth, gridheight];

// Use this for Initialization
void Start()
{
SpawnNextPiece();
}

// Update is called once per frame
void Update()
{

}
public void UpdateGrid(Piece piece)
{
for (int y = 0; y < gridheight; ++y)
{
for (int x = 0; x < gridwidth; ++x)
{
if (grid[x, y] != null)
{
if (grid[x, y].parent == piece.transform)
{
grid[x, y] = null;
}
}
}
}
foreach (Transform block in piece.transform)
{
Vector2 pos = Round(block.position);
if (pos.y < gridheight)
{
grid[(int)pos.x, (int)pos.y] = block;
}
}
}
public Transform GetTransformAtGridPosition(Vector2 pos)
{
if (pos.y > gridheight - 1)
{
return null;
}
else
{
return grid[(int)pos.x, (int)pos.y];
}
}
public void SpawnNextPiece()
{
GameObject nextPiece = (GameObject)Instantiate(Resources.Load(GetRandomPiece(), typeof(GameObject)), new Vector2(2.0f, 10.0f), Quaternion.identity);
}
public bool CheckIsInsideGrid (Vector2 pos)
{
return ((int)pos.x >= 0 && (int)pos.x < gridwidth && (int)pos.y >= 0);
}
public Vector2 Round (Vector2 pos)
{
return new Vector2(Mathf.Round(pos.x), Mathf.Round(pos.y));
}

private string GetRandomPiece()
{
int randomPiece = Random.Range(1, 7);
string randomPieceName = "Prefabs/Red";
switch (randomPiece)
{
case 1:
randomPieceName = "Prefabs/Red";
break;
case 2:
randomPieceName = "Prefabs/Orange";
break;
case 3:
randomPieceName = "Prefabs/Yellow";
break;
case 4:
randomPieceName = "Prefabs/Green";
break;
case 5:
randomPieceName = "Prefabs/Blue";
break;
case 6:
randomPieceName = "Prefabs/Purple";
break;
}
return randomPieceName;
}
}
``````
``````public class Piece : MonoBehaviour
{
float fall = 0;
public float fallSpeed = 1;
//Use this for initialization
void Start()
{

}

// Update is called once per frame
void Update()
{
CheckUserInput();
}
void CheckUserInput()
{

if (Input.GetKeyDown(KeyCode.RightArrow))
{
transform.position += new Vector3(1, 0, 0);
if (CheckIsValidPosition())
{
FindObjectOfType<Board>().UpdateGrid(this);
}
else
{
transform.position += new Vector3(-1, 0, 0);
}
}
else if (Input.GetKeyDown(KeyCode.LeftArrow))
{
transform.position += new Vector3(-1, 0, 0);
if (CheckIsValidPosition())
{
FindObjectOfType<Board>().UpdateGrid(this);
}
else
{
transform.position += new Vector3(1, 0, 0);
}
}
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
transform.position += new Vector3(0, -1, 0);
if (CheckIsValidPosition())
{
FindObjectOfType<Board>().UpdateGrid(this);
}
else
{
transform.position += new Vector3(0, 1, 0);
enabled = false;
FindObjectOfType<Board>().SpawnNextPiece();
}

}
}
bool CheckIsValidPosition()
{
foreach (Transform unit in transform)
{
Vector2 pos = FindObjectOfType<Board>().Round (unit.position);

if (FindObjectOfType<Board>().CheckIsInsideGrid (pos) == false)
{
return false;
}
if (FindObjectOfType<Board>().GetTransformAtGridPosition(pos) != null && FindObjectOfType<Board>().GetTransformAtGridPosition(pos).parent != transform)
{
return false;
}
}
return true;
}
}
``````

The code is based off of a Tetris tutorial I looked up. The main problem is where to put it and how to make the code work without errors popping up in my face on Visual. I found one idea from this link here, but my mind can only take so much. Bottom line though, will this work?