Случайный переход в рекурсивной функции - PullRequest
0 голосов
/ 08 февраля 2020

Я написал рекурсивную функцию, которая проходит через лабиринт / туннель с условием, что вы не можете переместиться через одну и ту же плитку назад (если не осталось плиток для перемещения, функция возвращается). Кажется, все работает, но в конце после return; части функция вызывается снова без причины. Кроме того, int[,] beenThere будет использоваться далее в коде, поэтому его нужно возвращать как есть.

 static public void Movement(int x,int y, int[,] coords, ref int[,] beenThere)
    {
        string bin = Convert.ToString(coords[x, y], 2).PadLeft(4, '0');

        beenThere[x, y] = 1;

        if (bin[0] == '0') // Bottom tile open
        {
            if(beenThere[x,y+1] == 0)
            {
                y++;
                Movement(x, y, coords, ref beenThere);
            }
        }

        if (bin[1] == '0') // Right tile open
        {
            if (beenThere[x + 1, y] == 0)
            {
                x++;
                Movement(x, y, coords, ref beenThere);
            }
        }

        if (bin[2] == '0') // Top tile open
        {
            if (beenThere[x, y - 1] == 0)
            {
                y--;
                Movement(x, y, coords, ref beenThere);
            }
        }

        if (bin[3] == '0')   // Left tile open
        {
            if (beenThere[x - 1, y] == 0)
            { 
                x--;
                Movement(x, y, coords, ref beenThere);
            }
        }

        // No tiles open, return back;
        Console.WriteLine("End of the tunnel.");
        return; // HERE LINE 12 OF CODE SNIPPET (CALLING THE FUNCTION) IS BEING RUN
    }

Я попытался пошагово отладить процесс и обнаружил, что после выполнения условия конца после Проходя часть return;, программа переходит на line 12 фрагмента (та же функция вызывается еще раз, даже если она должна была вернуться). В чем причина и как это исправить?

1 Ответ

2 голосов
/ 08 февраля 2020

Это рекурсивная функция, поэтому функция вызывает себя, как вы знаете. Но сама функция, вызывающая , не заставляет эту функцию останавливать выполнение и «переходить» к новой. Таким образом, как и любой другой код, после возврата функции, код продолжает выполнять . Как и любой другой код:

public void DoStuff() {
  Console.WriteLine("Stuff");
}

public void Main() {
  Console.WriteLine("Before Stuff");
  DoStuff(); //control flow enters "DoStuff"
  //once DoStuff returns, code continues as normal - it's the same in recursion!
  Console.WriteLine("After Stuff");
}

Просто замените DoStuff() рекурсивным вызовом, и он точно такой же.

Короче: добавьте return; s после вызова Movement(...); в каждое условие.

...