Search Unity

Disconnecting clusters of connected blocks

Discussion in 'Scripting' started by Bluvarth, Jun 20, 2019.

  1. Bluvarth

    Bluvarth

    Joined:
    Jul 11, 2017
    Posts:
    11
    So here's the setup, I need to be able to separate and distinguish two separate groups of blocks on a grid when parts are added and removed. The adding of blocks part is simple but the disconnecting part is less so. My current implementation is to use a modified astar approach that just tries to connect the start and end points without regard as to how it got there and does this check on all neighbors of the deleted block. It should work, but I can't help but feel there may be a simpler or cheaper way to do this check.

    Image for clarity:
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,742
    I think AStar might be a bit overkill. I would select a floodfill approach to update your block ownership.

    Whenever the grid changes, say a "Block 0" is removed, then flood fill all block0 tiles (only once per startpoint) and you'll end up with two (or more?) areas marked by the floodfill. Then just go back and assign whatever numbering you want to them.

    Here's a talk about floodfill... it's basically the paint bucket tool:

    https://en.wikipedia.org/wiki/Flood_fill
     
  3. Bluvarth

    Bluvarth

    Joined:
    Jul 11, 2017
    Posts:
    11
    I guess I poorly described my current algorithm, I don't track the cost of tiles, I just close the closest "open" tile and add its neighbors to the list of open tiles. This sound pretty much the same?

    Code in case I'm still bad at articulating.
    Code (CSharp):
    1.  
    2. public static class Astar
    3. {
    4.     public static int[,] tiles;
    5.     public static void setMap(int[,] map)
    6.     {
    7.         if (map == null)
    8.         {
    9.             Debug.LogWarning("map is null");
    10.         }
    11.         else
    12.         {
    13.             if (map.Rank == 2) tiles = map;
    14.             else Debug.LogError("MAP ARRAY MUST BE TWO DIMENSIONAL");
    15.         }
    16.     }
    17.  
    18.     public static bool canPath(Vector2Int start, Vector2Int end)
    19.     {
    20.         if (tiles != null)
    21.         {
    22.             List<Vector2Int> closedTiles = new List<Vector2Int>();
    23.             List<Vector2Int> openTiles = new List<Vector2Int>();
    24.             if (start.x > 0 && start.x < tiles.GetLength(0) &&
    25.                 start.y > 0 && start.y < tiles.GetLength(1))
    26.             {
    27.                 openTiles.Add(start);
    28.             }
    29.  
    30.             // Add all blocked tiles to closed list
    31.             for (int i = 0; i < tiles.GetLength(0); i++)
    32.             {
    33.                 for (int j = 0; j < tiles.GetLength(1); j++)
    34.                 {
    35.                     if (tiles[i, j] == -1)
    36.                     {
    37.                         closedTiles.Add(new Vector2Int(i, j));
    38.                     }
    39.                 }
    40.             }
    41.  
    42.             do
    43.             {
    44.  
    45.                 // Find closest open tile to the end pos
    46.                 int closestOpenTileIndex = 0;
    47.                 int closestDist = Mathf.Abs(end.x - openTiles[0].x) + Mathf.Abs(end.y - openTiles[0].y);
    48.                 for (int i = 0; i < openTiles.Count; i++)
    49.                 {
    50.                     int dist = Mathf.Abs(end.x - openTiles[i].x) + Mathf.Abs(end.y - openTiles[i].y);
    51.                     if (closestDist > dist)
    52.                     {
    53.                         closestDist = dist;
    54.                         closestOpenTileIndex = i;
    55.                     }
    56.                 }
    57.  
    58.                 // Add neighbors to open tiles
    59.                 Vector2Int checkVector = new Vector2Int(openTiles[closestOpenTileIndex].x - 1, openTiles[closestOpenTileIndex].y);
    60.                 if (openTiles[closestOpenTileIndex].x > 0 && !closedTiles.Contains(checkVector) && !openTiles.Contains(checkVector))
    61.                 {
    62.                     openTiles.Add(checkVector);
    63.                 }
    64.                 checkVector = new Vector2Int(openTiles[closestOpenTileIndex].x + 1, openTiles[closestOpenTileIndex].y);
    65.                 if (openTiles[closestOpenTileIndex].x < tiles.GetLength(0) && !closedTiles.Contains(checkVector) && !openTiles.Contains(checkVector))
    66.                 {
    67.                     openTiles.Add(checkVector);
    68.                 }
    69.                 checkVector = new Vector2Int(openTiles[closestOpenTileIndex].x, openTiles[closestOpenTileIndex].y - 1);
    70.                 if (openTiles[closestOpenTileIndex].y > 0 && !closedTiles.Contains(checkVector) && !openTiles.Contains(checkVector))
    71.                 {
    72.                     openTiles.Add(checkVector);
    73.                 }
    74.                 checkVector = new Vector2Int(openTiles[closestOpenTileIndex].x, openTiles[closestOpenTileIndex].y + 1);
    75.                 if (openTiles[closestOpenTileIndex].y < tiles.GetLength(1) && !closedTiles.Contains(checkVector) && !openTiles.Contains(checkVector))
    76.                 {
    77.                     openTiles.Add(checkVector);
    78.                 }
    79.  
    80.                 //update open and closed tile lists
    81.                 closedTiles.Add(openTiles[closestOpenTileIndex]);
    82.                 openTiles.Remove(openTiles[closestOpenTileIndex]);
    83.  
    84.                 if (openTiles.Contains(end))
    85.                 {
    86.                     return true;
    87.                 }
    88.  
    89.             } while (openTiles.Count > 0);
    90.  
    91.             return false;
    92.         }
    93.         else
    94.         {
    95.             return false;
    96.         }
    97.     }
    98. }
    99.