c#调试进入无限循环的方法

时间:2017-05-05 20:18:33

标签: c# winforms

以下代码正常工作,直到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)
    {

    }
}

2 个答案:

答案 0 :(得分:1)

您的问题在于您的案例陈述的方式。您正在绘制的图片和您的路径如下所示:

Path Finder

现在当你的路径在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,我希望你会发现事情更好。