我有一个由多维布尔数组表示的二维网格。在此网格上,您可以放置各种对象。玩家无法穿过这些物体。我想防止用户在尝试放置对象之前就无法阻挡网格的一部分。
我编写了一个广度优先搜索算法来查看如果当前单元格被封锁,网格是否会与当前网格不同。但是,我的代码开始在小到 8x8 的网格上停止游戏。有没有一种算法可以做我想做的事,但速度更快?有什么我可以添加的东西来提高效率吗?任何建议都会有所帮助。
这是我的代码:
private bool CellBlocksPathway(Vector2Int coordinates)
{
// Don't run this algorithm if we've already checked this cell.
// This list will get cleared when the state of the grid changes.
if (lastCheckedCells.Contains(coordinates))
{
return lastCheckedCells.GetResult(coordinates);
}
// Create fake grid of bools.
bool[,] fakeOccupiedGrid = new bool[width, height];
// Set everything to true.
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
fakeOccupiedGrid[i, j] = true;
}
}
// Breadth-first search the real grid for occupied spaces.
Queue<Vector2Int> queuedCoordinates = new Queue<Vector2Int>();
queuedCoordinates.Enqueue(Vector2Int.zero);
Vector2Int currentCoordinates = queuedCoordinates.Peek();
queuedCoordinates.Enqueue(queuedCoordinates.Peek() + Vector2Int.up);
queuedCoordinates.Enqueue(queuedCoordinates.Peek() + Vector2Int.right);
//occupied is the current bool 2D array
fakeOccupiedGrid[currentCoordinates.x, currentCoordinates.y] =
occupied[currentCoordinates.x, currentCoordinates.y];
List<Vector2Int> searchedCoordinates = new List<Vector2Int>();
searchedCoordinates.Add(queuedCoordinates.Dequeue());
while (queuedCoordinates.Count > 0)
{
currentCoordinates = queuedCoordinates.Dequeue();
searchedCoordinates.Add(currentCoordinates);
if (occupied[currentCoordinates.x, currentCoordinates.y])
{
continue;
}
fakeOccupiedGrid[currentCoordinates.x, currentCoordinates.y] = false;
if (currentCoordinates == coordinates)
{
continue;
}
// If the adjacent coordinate is in-bounds, and we haven't checked it yet, add it to the queue.
// Check the up neighbor.
if (currentCoordinates.y + 1 < height &&
!searchedCoordinates.Contains(currentCoordinates + Vector2Int.up))
{
queuedCoordinates.Enqueue(currentCoordinates + Vector2Int.up);
}
// Check the right neighbor.
if (currentCoordinates.x + 1 < width &&
!searchedCoordinates.Contains(currentCoordinates + Vector2Int.right))
{
queuedCoordinates.Enqueue(currentCoordinates + Vector2Int.right);
}
// Check the down neighbor.
if (currentCoordinates.y - 1 >= 0 &&
!searchedCoordinates.Contains(currentCoordinates + Vector2Int.down))
{
queuedCoordinates.Enqueue(currentCoordinates + Vector2Int.down);
}
// Check the left neighbor.
if (currentCoordinates.x - 1 >= 0 &&
!searchedCoordinates.Contains(currentCoordinates + Vector2Int.left))
{
queuedCoordinates.Enqueue(currentCoordinates + Vector2Int.left);
}
}
lastCheckedCells.Add(coordinates);
//GridsAreNotEqual does a double-for-loop to check if any spaces are different between the two grid arrays.
lastCheckedCells.Add(GridsAreNotEqual(fakeOccupiedGrid));
return lastCheckedCells.GetLatestResult();
}