我正在尝试为我的游戏实施一个简单的洪水填充算法,以便在程序生成的洞穴中找到洞穴的大小;然而,我似乎缺少一些基本点,因此我使用的算法连续排队甚至检查点。 我的代码如下:
List<Point> sector = new List<Point>();
List<Point> checkd = new List<Point>();
List<Point> queue = new List<Point>();
queue.Add(new Point(startX, startY));
while (queue.Count > 0) {
Point origin = queue[0];
queue.RemoveAt(0);
sector.Add(origin);
checkd.Add(origin);
for (int offsetX = -1; offsetX < 2; offsetX++) {
for (int offsetY = -1; offsetY < 2; offsetY++) {
if (offsetX == 0 && offsetY == 0 || offsetX == offsetY ||
offsetX == -offsetY || -offsetX == offsetY)
continue;
Point target = new Point(offsetX, offsetY);
if (target.X < 0 || target.Y < 0 ||
target.X >= cells.Width || target.Y >= cells.Height ||
!checkd.Contains (target))
queue.Add(target);
}
}
}
答案 0 :(得分:3)
这里有很多不妥之处。我尽可能地保留原始代码。
Point target = new Point (offsetX, offsetY);
不计算位置。您可能想要使用Point target = new Point(origin.X + offsetX, origin.Y + offsetY);
checkd
,则无法在if (target.X < 0 || target.Y < 0 || target.X >= cells.Width || target.Y >= cells.Height || !checkd.Contains (target))
中的一个if语句中完成,因为这也会在cells
之外的队列中添加点1}} grid。List<Point>.Contains(Point p)
仅返回true。从来没有这种情况,因为目标是使用Point target = new Point(...)
创建的。所以这是我的版本。它遍历所有点并最终将它们添加到checkd。
List<Point> checkd = new List<Point>();
List<Point> queue = new List<Point>();
queue.Add(new Point(startX, startY));
while (queue.Count > 0)
{
Point origin = queue[0];
queue.RemoveAt(0);
sector.Add(origin);
checkd.Add(origin);
for (int offsetX = -1; offsetX < 2; offsetX++)
{
for (int offsetY = -1; offsetY < 2; offsetY++)
{
// do not check origin or diagonal neighbours
if (offsetX == 0 && offsetY == 0 || offsetX == offsetY || offsetX == -offsetY || -offsetX == offsetY) continue;
Point target = new Point(origin.X + offsetX, origin.Y + offsetY);
// skip out of bounds point
if (target.X < 0 || target.Y < 0 || target.X >= cells.Width || target.Y >= cells.Height) continue;
if (!Contains(checkd, target) && !Contains(queue, target))
{
queue.Add(target);
}
}
}
}
为了检查收容,我使用了以下方法:
private bool Contains(List<Point> list, Point point)
{
return list.Any(p => p.X == point.X && p.Y == point.Y);
}
尝试从头开始实施泛洪填充算法可能是一个很好的练习。对于一个严肃的项目,您应该考虑使用已经实现了此功能(可能还需要更多)的图形库。