I am making a game in Unity where a player can delete a number of cells from my simulation.
Assume that all the cells are connected only to the top row through their neighbors.
The player comes in and deletes cells creating a group of cells that are separated. I would like to get them.
As an example in the image below after the player deletes the green cell I would like to get the cells that are in the red perimeter.

- 83,094
- 9
- 75
- 115

- 3
- 1
-
Make sure to provide images and write your code if that is part of the question. Make sure your question is clearer to help the people that are trying to solve your problem. – gbe Apr 29 '21 at 23:03
-
@ken: Do **not** advise to post pictures of code! Code must be pasted as **text only**, no pictures! – sticky bit Apr 29 '21 at 23:05
-
I just changed it. – gbe Apr 29 '21 at 23:07
-
To get a good answer you are going to need to put some effort in. Funny enough tho a few days ago solved a [LeetCode](https://leetcode.com/problems/critical-connections-in-a-network/) question that could be of some use. It is finding a list of all critical connections in a graph. It is an option, but until we know more about your setup it is hard to say one way or the other. If you want to know some solutions to this problem, you can view the Discussion board to see if it will help. – TEEBQNE Apr 30 '21 at 01:42
1 Answers
Well it is quite broad and depends a lot on your data structure. What I can think of quick and dirty but straight forward would be
For each cell store its neighbours - that's obviously something you have to set up when creating the board - like e.g.
public class Cell
{
public bool Enabled;
public Vector2Int position;
public Cell top;
public Cell bottom;
public Cell left;
public Cell right;
}
Then you can collect all groups of enabled cells by doing
- iterate through the entire board and find the first enabled cell
- create a new group
- add this cell to the group
- for each four directions check if there is another enabled cell
- if yes add to the group and repeat the last step
- ignore cells if you encounter them the second time (=when they are already in the group)
- you are done if there is no more enabled cells in all directions that are not already in the group
- go back to the first step but skip cells that already are in any group
- you are done when you reach the end of the board
In code this might look somewhat like
// Assuming you have a board grid like
private Cell[,] grid = new Cell[width, height];
public List<HashSet<Cell>> FindGroups()
{
var output = new List<HashSet<Cell>>();
var alreadyTracked = new HashSet<Cell>();
// Iterate the grid
for(var x = 0; x < width; x++)
{
for(var y = 0; y < height; y++)
{
var current = grid[x,y];
// skip if not enabled
if(!current.Enabled) continue;
// skip if cell was already tracked in any group before
if(alreadyTracked.Contains(current)) continue;
// Create new group and fill it recursively
var group = new HashSet<Cell>();
current.FindConnectedEnabledCells(current, alreadyTracked, group);
// Add that new group to the final output
output.Add(group);
}
}
return output;
}
// Finds all cells connected to the given cell that are enabled recursively
// and adds them to the given collections
private void GetConnectedEnabledCells(Cell current, HashSet<Cell> alreadyTracked, HashSet<Cell> group)
{
// This cell is not enabled -> ignore
if(!current.Enabled) return;
// This cell is already in the group -> ignore
if(group.Contains(current)) return;
// Add the current cell to the collections itself
group.Add(current);
alreadyTracked.Add(current);
// Recursively fetch all connected cells that are not null (e.g. Edge cells) and are enabled
if(current.top?.Enabled) current.top.GetConnectedEnabledCells(cells);
if(current.bottom?.Enabled) current.bottom.GetConnectedEnabledCells(cells);
if(current.left?.Enabled) current.left.GetConnectedEnabledCells(cells);
if(current.right?.Enabled) current.right.GetConnectedEnabledCells(cells);
}
And then since you seem to already know the top row is always there you can ignore the first group since that's the one connected to your "ceiling".
If it's the most efficient way I don't know ;)
You might want to exchange HashSet
with List
depending on the size of your grid. HashSet
is better in Contains
but worse in Add
for large collections.
If you consider diagonals as "connected" then add, fill and check the according additional four cell entries to the Cell
class.
Note: If your cell class is a MonoBehaviour
then instead of e.g.
if(current.top?.Enabled)
rather use
if(current.top && current.top.Enabled)

- 83,094
- 9
- 75
- 115
-
My data structure is a 2D array filled with 1 (enabled) and 0 (disabled) using cellular automata. I will "map" this array to my game screen. Every index in the array is a cell. – Costel Catalin Apr 30 '21 at 20:50
-
Basically I am trying to get all indexes or groups of indexes that are surrounded by zeros. The recursive part of the problem is throwing me off but I will try to understand and adapt your code. Thanks Costel. – Costel Catalin Apr 30 '21 at 20:57