以下代码正常工作,直到StepMaker方法将数据提供给modeOffroad,它就像进入无限循环...
该方法应检查3x3矩阵以查找非障碍物的单元格,并将其坐标返回到将矩阵中心移动到新坐标的stepmaker。是什么造成这个错误?我该怎么办呢?
public partial class Form1 : Form
{
public class PathFinderOutput
{
public byte NextX { get; set; }
public byte NextY { get; set; }
public bool Blocked { get; set; }
public byte CurrentX { get; set; }
public byte CurrentY { get; set; }
public byte[,] Map { get; set; }
public PathFinderOutput(byte nextX, byte nextY, bool blocked, byte currentX, byte currentY, byte[,] map)
{
NextX = nextX;
NextY = nextY;
Blocked = blocked;
CurrentX = currentX;
CurrentY = currentY;
Map = map;
}
}
public class StepMakerOutput
{
public byte CurrentX { get; set; }
public byte CurrentY { get; set; }
public StepMakerOutput(byte currentX, byte currentY)
{
CurrentX = currentX;
CurrentY = currentY;
}
}
public byte[,] ObstacleGenerator(byte[,] map, byte leftX, byte rightX, byte TopY, byte bottomY)
{
// akadályt építi fel
for (int i = TopY; i <= bottomY; i++)
{
for (int j = leftX; j <= rightX; j++)
{
map[i, j] = 1;
}
}
return map;
}
public byte[,] MapGenerator()
{
// a térképet építi fel
byte[,] map = new byte[102, 102];
for (int i = 0; i < map.GetLength(0); i++)
{
for (int j = 0; j < map.GetLength(1); j++)
{
//a térkép grafikusan nem látható pereme
if (i == 0 || j == 0 || i == map.GetLength(0) - 1 || j == map.GetLength(1) - 1)
{
map[i, j] = 253;
}
else
//járható út
{
map[i, j] = 0;
}
}
}
return map;
}
public void PictureBuilder(byte[,] map, Graphics g)
{
for (int i = 0; i < map.GetLength(0); i++)
{
for (int j = 0; j < map.GetLength(1); j++)
{
//láthatatlan perem
if (map[i, j] == 0)
{
Brush aBrush = (Brush)Brushes.NavajoWhite;
g.FillRectangle(aBrush, i, j, 1, 1);
}
//út
else if (map[i, j] == 253)
{
}
//akadály
else if (map[i, j] == 1)
{
Brush aBrush = (Brush)Brushes.Black;
g.FillRectangle(aBrush, i, j, 1, 1);
}
//bejárt út
else if (map[i, j] == 2)
{
Brush aBrush = (Brush)Brushes.Red;
g.FillRectangle(aBrush, i, j, 1, 1);
}
}
}
}
public PathFinderOutput Pathfinder(byte[,] map, StepMakerOutput input, byte endX, byte endY)
{
byte distance;
byte distanceMin = byte.MaxValue;
byte currentX = input.CurrentX;
byte currentY = input.CurrentY;
byte nextX = 1;
byte nextY = 1;
bool blocked = false;
//bejárt utat jelöli meg
map[currentX, currentY] = 2;
for (int i = (currentX - 1); i <= currentX + 1; i++)
{
for (int j = (currentY - 1); j <= currentY + 1; j++)
{
//robot saját posízióját ne szkennelje
if ((i == currentX) && (j == currentY))
{
continue;
}
int a = (endX - i) * (endX - i);
int b = (endY - j) * (endY - j);
distance = (byte)(Math.Sqrt(a + b));
if (distanceMin > distance)
{
distanceMin = distance;
nextX = (byte)i;
nextY = (byte)j;
if (map[i, j] == 1)
{
blocked = true;
}
}
}
}
PathFinderOutput output = new PathFinderOutput(nextX, nextY, blocked, currentX, currentY, map);
return output;
}
public StepMakerOutput ModeOffroad(PathFinderOutput input)
{
int xDirection = input.NextX - input.CurrentX;
int yDirection = input.NextY - input.CurrentY;
StepMakerOutput temp = new StepMakerOutput(0, 0);
//az akadály helyzetének megállapítása a robottól nézve
int switcher = 0;
if (xDirection == -1 && yDirection == 1)
{
switcher = 1;
} else if (xDirection == 0 && yDirection == 1)
{
switcher = 2;
} else if (xDirection == 1 && yDirection == 1)
{
switcher = 3;
} else if (xDirection == -1 && yDirection == 0)
{
switcher = 4;
} else if (xDirection == 1 && yDirection == 0)
{
switcher = 6;
} else if (xDirection == -1 && yDirection == -1)
{
switcher = 7;
} else if (xDirection == 0 && yDirection == -1)
{
switcher = 8;
} else if (xDirection == + 1 && yDirection == -1)
{
switcher = 9;
}
//akadálymentes cella keresése
switch (switcher)
{
case 1:
{
if (input.Map[input.CurrentX - 1, input.CurrentY + 1] != 1)
{
temp.CurrentX = (byte)(input.CurrentX - 1);
temp.CurrentY = (byte)(input.CurrentY + 1);
break;
}
else
goto case 2;
}
case 2:
{
if (input.Map[input.CurrentX + 0, input.CurrentY + 1] != 1)
{
temp.CurrentX = (byte)(input.CurrentX + 0);
temp.CurrentY = (byte)(input.CurrentY + 1);
break;
}
else
{
goto case 3;
}
}
case 3:
{
if (input.Map[input.CurrentX + 1, input.CurrentY + 1] != 1)
{
temp.CurrentX = (byte)(input.CurrentX + 1);
temp.CurrentY = (byte)(input.CurrentY + 1);
break;
}
else
{
goto case 6;
}
}
case 4:
{
if (input.Map[input.CurrentX - 1, input.CurrentY + 0] != 1)
{
temp.CurrentX = (byte)(input.CurrentX - 1);
temp.CurrentY = (byte)(input.CurrentY + 0);
break;
}
else
{
goto case 1;
}
}
case 6:
{
if (input.Map[input.CurrentX + 1, input.CurrentY + 0] != 1)
{
temp.CurrentX = (byte)(input.CurrentX + 1);
temp.CurrentY = (byte)(input.CurrentY + 0);
break;
}
else
{
goto case 9;
}
}
case 7:
{
if (input.Map[input.CurrentX - 1, input.CurrentY - 1] != 1)
{
temp.CurrentX = (byte)(input.CurrentX - 1);
temp.CurrentY = (byte)(input.CurrentY - 1);
break;
}
else
{
goto case 4;
}
}
case 8:
{
if (input.Map[input.CurrentX - 0, input.CurrentY - 1] != 1)
{
temp.CurrentX = (byte)(input.CurrentX - 0);
temp.CurrentY = (byte)(input.CurrentY - 1);
break;
}
else
{
goto case 7;
}
}
case 9:
{
if (input.Map[input.CurrentX + 1, input.CurrentY - 1] != 1)
{
temp.CurrentX = (byte)(input.CurrentX + 1);
temp.CurrentY = (byte)(input.CurrentY - 1);
break;
}
else
{
goto case 8;
}
}
}
return temp;
}
public StepMakerOutput Stepmaker(PathFinderOutput input)
{
byte currentX;
byte currentY;
//robot útja szabad/ akadályozott pálya esetén
if (input.Blocked == false)
{
currentX = input.NextX;
currentY = input.NextY;
}
else
{
StepMakerOutput temp = ModeOffroad(input);
currentX = temp.CurrentX;
currentY = temp.CurrentY;
}
StepMakerOutput output = new StepMakerOutput(currentX, currentY);
return output;
}
public Form1()
{
InitializeComponent();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
Invalidate();
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
//start és végpontok
byte startX = 3;
byte startY = 3;
byte endX = 99;
byte endY = 99;
byte[,] map = MapGenerator();
map = ObstacleGenerator(map, 20, 80, 25, 40);
map = ObstacleGenerator(map, 15, 75, 60, 75);
PathFinderOutput outputP;
StepMakerOutput outputS = new StepMakerOutput(startX, startY);
while ((outputS.CurrentX != endX) && (outputS.CurrentY != endY))
{
outputP = Pathfinder(map, outputS, endX, endY);
outputS = Stepmaker(outputP);
}
Graphics g = e.Graphics;
PictureBuilder(map, e.Graphics);
}
private void button1_Click(object sender, EventArgs e)
{
}
}
答案 0 :(得分:1)
您的问题在于您的案例陈述的方式。您正在绘制的图片和您的路径如下所示:
现在当你的路径在24,33处撞到矩形的一侧时,它会调用case 3,它试图将+ 1,+ 1移动到25,34。它不能,所以......
case 6: +1,+0 (Wall is to the right, so no go)
case 9: +1,-1 (Wall is still to the right, so no go)
case 8: +0,-1 (No wall above so it moves up to 24,32)
现在在下一步中,确定最短路径是向下移动到24,33。然后它又开始尝试移动+ 1,+ 1到25,34,创建无限循环。 您可以尝试使用计算来选择要测试的最佳方向,而不是仅仅迭代预设方向。
如果它不能移动到+ 1,+ 1并且+1的测试显示它被阻止,则应该假设下一个测试将是0,+ 1而不是0,-1。您可以循环浏览在设置切换器值时创建的案例比较数组,而不是使用。对于切换台3,您可以:
byte[] DirectionTester = new byte[] { 3, 6, 2, 9, 1, 4, 8, 7 }
这将确保首先测试最积极的动作。
答案 1 :(得分:0)
要找出导致错误的原因,请使用Visual Studio启动程序。当它进入循环时,在工具栏上查找“暂停”按钮(在Debug =&gt; Break All下的菜单上)或在循环区域中设置断点。
程序将暂停执行。 Visual Studio将跳转到当前代码行并以黄色突出显示。您可以检查所有变量的当前值,并使用F10和F11键一次一行地执行您的程序,并确认它的工作方式与预期的一致。
最终,该程序会做一些你不期望的人。看看变量,直到你明白为什么。然后停止程序,修复代码,使其不再执行此操作,然后重试。这就是调试的工作原理。
在这种情况下,你在那里有一些goto
语句的迷宫。重写不使用goto,我希望你会发现事情更好。