Я делаю игру, где стены сделаны из квадратных блоков. Стены расположены на двумерной сетке, как это:Поиск минимального количества стен
[X][X][X][X]
[ ][X][ ][ ]
[ ][X][ ][ ]
[ ][X][ ][ ]
Теперь, как я оптимизации моего обнаружения столкновений, это помогает уменьшить количество стенок до минимума. В приведенном выше случае имеется семь стеновых блоков, но только две стены, если блоки объединены. Мне сложно найти оптимальное решение для поиска этих объединенных стен и получить разные результаты в зависимости от того, на каком этапе начинается поиск (блоки хранятся в неупорядоченном списке, порядок поступает из того порядка, в котором они были заложены редактор). Любые мысли о том, как это решить? Это должно быть довольно рудиментарно, но, знаете, в пятницу, и я не могу нормально функционировать. :)
Вот мой субоптимальный код на данный момент, он в основном выполняет две проверки, как для горизонтальной, так и для вертикальной «непрерывности», а затем проверяет, какой из них лучше. Он также хранит «уже обработанные» блоки стен, поэтому они не будут распознаваться дважды, но это, конечно же, заставляет задуматься в местах пересечения.
public void CreateCollidersForExport()
{
List<Wall> handledWalls = new List<Wall>();
foreach (Wall w in walls)
{
if (handledWalls.Contains(w)) continue;
handledWalls.Add(w);
// Search how many walls there is horizontally
Vector3 horizontalCenter = new Vector3(w.X, w.Y, w.Z);
List<Wall> tmpWallsHorizontal = new List<Wall>();
tmpWallsHorizontal.Add(w);
foreach (Wall other in walls)
{
if (handledWalls.Contains(other) || tmpWallsHorizontal.Contains(other)) continue;
bool canAdd = false;
foreach (Wall _w in tmpWallsHorizontal)
{
if (other.X == _w.X + Wall.size && other.Y == _w.Y && other.Z == _w.Z)
{
canAdd = true;
horizontalCenter.X += Wall.size/2;
break;
}
else if (other.X == _w.X - Wall.size && other.Y == _w.Y && other.Z == _w.Z)
{
canAdd = true;
horizontalCenter.X -= Wall.size/2;
break;
}
}
if (canAdd)
{
tmpWallsHorizontal.Add(other);
}
}
// Search how many walls there is vertically
Vector3 verticalCenter = new Vector3(w.X, w.Y, w.Z);
List<Wall> tmpWallsVertical = new List<Wall>();
tmpWallsVertical.Add(w);
foreach (Wall other in walls)
{
if (handledWalls.Contains(other) || tmpWallsVertical.Contains(other)) continue;
bool canAdd = false;
foreach (Wall _w in tmpWallsVertical)
{
if (other.X == _w.X && other.Y == _w.Y && other.Z == _w.Z + Wall.size)
{
canAdd = true;
verticalCenter.Z += Wall.size/2;
break;
}
else if (other.X == _w.X && other.Y == _w.Y && other.Z == _w.Z - Wall.size)
{
canAdd = true;
verticalCenter.Z -= Wall.size/2;
break;
}
}
if (canAdd)
{
tmpWallsVertical.Add(other);
}
}
if (tmpWallsHorizontal.Count > tmpWallsVertical.Count)
{
// tmpWallsHorizontal has the longest "wall" now
}
else if (tmpWallsVertical.Count > tmpWallsHorizontal.Count)
{
// tmpWallsVertical has the longest "wall" now
}
else
{
// Both ways are the same length
}
}
}
Покажите нам, пожалуйста, ваш менее чем оптимальный код. – Bazzz
Это результат, который вы хотите? '(0,0) - (0,3) и (0,1) - (3,1)'? –
Кажется, вам нужно было бы рассчитать все возможные комбинации, чтобы найти оптимальный. Было бы так плохо, если бы у вас было 3 стены вместо 2? Или 2 перекрывающиеся? – dtb