我目前正在尝试制作蛇寻路算法。我试图做点什么,但是我发现问题很难找到。问题是我以递归方式实现算法,该方法没有找到一条路径,但是由于控制台窗口大,所以可以搜索导致堆栈溢出异常的所有可用路径。
“网格”是一个二维布尔数组,与控制台一样大,如果在控制台上有类似蛇的部分,则值为true。 / em>
方向 是一个包含Up,Down,Left,Right值的枚举。 位置是一个带有两个整数的结构,称为X和Y。
ScheduledDirections 是一个列表,其中包含将来用于蛇在控制台上绘图的路线。
我想要做的是快速添加一个可用路径到该列表。 我知道像A *这样的寻路算法,但我发现它太复杂而且难以实现。
这是我用来查找可用路径的方法:
private static void FindAvailablePath(Position currentPosition, Direction currentDirection)
{
// break if the snake's path search has ended or it went out of the console
if (currentPosition.X < 0 || currentPosition.X >= Console.WindowWidth ||
currentPosition.Y < 0 || currentPosition.Y >= Console.WindowHeight ||
AIController.isReady)
{
return;
}
// break if there is something that is blocking the snake's path
if (Snake.Grid[currentPosition.X, currentPosition.Y])
{
return;
}
// break if the snake has reached its destination
if (currentPosition.Equals(AIController.Destination))
{
AIController.isReady = true;
return;
}
// if the current path is available, adds it to the collection and checks for the next one
if (!Snake.Grid[currentPosition.X, currentPosition.Y])
{
AIController.scheduledDirections.Add(currentDirection);
FindAvailablePath(new Position(currentPosition.X + 1, currentPosition.Y), Direction.Right); // right
FindAvailablePath(new Position(currentPosition.X, currentPosition.Y - 1), Direction.Up); // up
FindAvailablePath(new Position(currentPosition.X - 1, currentPosition.Y), Direction.Left); // left
FindAvailablePath(new Position(currentPosition.X, currentPosition.Y + 1), Direction.Down); // down
}
}
如果某人有更好的想法,我会很高兴听到他们。 谢谢!
答案 0 :(得分:1)
你必须确保蛇不会回到已经“访问过”的位置,否则你的代码将不得不探索无限多种可能性(在相同的四个方格中圈出一次,两次,三次,......,四十亿次等。)。
这意味着您必须记录所访问的职位并检查该职位。
这应该可以解决问题:
private static void FindAvailablePath(Position currentPosition, Stack<Position> previousPositions, Direction currentDirection, Stack<Drection> previousDirections)
{
// break if the snake's path search has ended or it went out of the console
if (currentPosition.X < 0 || currentPosition.X >= Console.WindowWidth ||
currentPosition.Y < 0 || currentPosition.Y >= Console.WindowHeight)
{
return;
}
// break if there is something that is blocking the snake's path
if (Snake.Grid[currentPosition.X, currentPosition.Y])
{
return;
}
// break if the snake has reached its destination
if (currentPosition.Equals(AIController.Destination))
{
if(AIController.scheduledDirections == null || AIController.scheduledDirections.Count > previousDirections.Count + 1)
{
AIController.scheduledDirections = previousDirections.ToList();
AIController.scheduledDirections.Add(currentDirection);
}
return;
}
// Break if previously visited
if(previousPositions.Contains(currentPosition))
{
return;
}
// if the current path is available, adds it to the collection and checks for the next one
previousPositions.Push(currentPosition);
previousDirections.Push(currentDirection);
FindAvailablePath(new Position(currentPosition.X + 1, currentPosition.Y), previousPositions, Direction.Right, previousDirections); // right
FindAvailablePath(new Position(currentPosition.X, currentPosition.Y - 1), previousPositions, Direction.Up, previousDirections); // up
FindAvailablePath(new Position(currentPosition.X - 1, currentPosition.Y), previousPositions, Direction.Left, previousDirections); // left
FindAvailablePath(new Position(currentPosition.X, currentPosition.Y + 1), previousPositions, Direction.Down, previousDirections); // down
previousPositions.Pop();
previousDirections.Pop();
}
此外,专业提示:向您的位置结构添加“左”,“右”,“顶部”,“向下”方法,这些方法返回正确方向的新位置。这使您的代码更具可读性。