Вызывать функцию повторно, пока не будет получен желаемый результат

#c# #recursion #stack-overflow

#c# #рекурсия #stack-overflow

Вопрос:

Я создаю своего рода автоматический статистический ролик, и я хочу, чтобы он продолжал работать, пока я не получу желаемый результат. Вот код:

 class Program
{
    static void Main(string[] args)
    {
        _getStats();
    }

    static void _getStats()
    {
        Random rnd = new Random();
        int stat1 = 0;
        int stat2 = 0;
        int stat3 = 0;
        int stat4 = 0;
        int stat5 = 0;
        int stat6 = 0;

        for (int i = 0; i < 6; i  )
        {

            int roll1 = rnd.Next(1, 7);
            int roll2 = rnd.Next(1, 7);
            int roll3 = rnd.Next(1, 7);
            int roll4 = rnd.Next(1, 7);
            int tempStatTotal = 0;
            List<int> rollList = new List<int>();

            rollList.Add(roll1);
            rollList.Add(roll2);
            rollList.Add(roll3);
            rollList.Add(roll4);
            rollList.Sort();
            rollList.RemoveAt(0);

            foreach (int j in rollList)
            {
                tempStatTotal  = j;
            }

            if (i == 0)
            {
                stat1 = tempStatTotal;
            }
            else if(i == 1)
            {
                stat2 = tempStatTotal;
            }
            else if (i == 2)
            {
                stat3 = tempStatTotal;
            }
            else if (i == 3)
            {
                stat4 = tempStatTotal;
            }
            else if (i == 4)
            {
                stat5 = tempStatTotal;
            }
            else
            {
                stat6 = tempStatTotal;
            }
        }

        if(stat1 == 18 || stat2 == 18 || stat3 == 18 || stat4== 18 || stat5 == 18 || stat6 == 18)
        {
            Console.WriteLine(stat1);
            Console.WriteLine(stat2);
            Console.WriteLine(stat3);
            Console.WriteLine(stat4);
            Console.WriteLine(stat5);
            Console.WriteLine(stat6);
        }
        else
        {
            Main(null); //Start the process all over again until one of the stats is 18
        }
    }
}
  

Когда я запускаю этот код, в нескольких случаях консоль регистрирует 6 чисел, и 1 из них равен 18. В большинстве случаев приложения прерываются и выдается ошибка System.StackOverflowException . Я понимаю, что это как-то связано с бесконечными циклами, и это происходит потому, что я рекурсивно вызываю свой метод, но как мне обойти это?

Комментарии:

1. Не используйте рекурсию, вместо этого используйте цикл do-while.

Ответ №1:

Используйте цикл do-while:

 class Program
{
static void Main(string[] args)
{
    _getStats();
}

static void _getStats()
{
    do
    {
        Random rnd = new Random();
        int stat1 = 0;
        int stat2 = 0;
        int stat3 = 0;
        int stat4 = 0;
        int stat5 = 0;
        int stat6 = 0;

        for (int i = 0; i < 6; i  )
        {

            int roll1 = rnd.Next(1, 7);
            int roll2 = rnd.Next(1, 7);
            int roll3 = rnd.Next(1, 7);
            int roll4 = rnd.Next(1, 7);
            int tempStatTotal = 0;
            List<int> rollList = new List<int>();

            rollList.Add(roll1);
            rollList.Add(roll2);
            rollList.Add(roll3);
            rollList.Add(roll4);
            rollList.Sort();
            rollList.RemoveAt(0);

            foreach (int j in rollList)
            {
                tempStatTotal  = j;
            }

            if (i == 0)
            {
                stat1 = tempStatTotal;
            }
            else if (i == 1)
            {
                stat2 = tempStatTotal;
            }
            else if (i == 2)
            {
                stat3 = tempStatTotal;
            }
            else if (i == 3)
            {
                stat4 = tempStatTotal;
            }
            else if (i == 4)
            {
                stat5 = tempStatTotal;
            }
            else
            {
                stat6 = tempStatTotal;
            }
        }

        if (stat1 == 18 || stat2 == 18 || stat3 == 18 || stat4 == 18 || stat5 == 18 || stat6 == 18)
        {
            Console.WriteLine(stat1);
            Console.WriteLine(stat2);
            Console.WriteLine(stat3);
            Console.WriteLine(stat4);
            Console.WriteLine(stat5);
            Console.WriteLine(stat6);
            break;
        }
    } while (true);
}
}
  

Комментарии:

1. Спасибо, Кристоф, это работает именно так, как я хотел, чтобы это было сейчас!

Ответ №2:

Ах, рекурсия. Это все забавы, пока вы не получите исключение StackOverflowException.

Вы правы, что причиной этого является использование рекурсии. Рекурсия — полезный инструмент, но она может израсходовать вашу память во время длительных операций. Как уже предлагали другие, используйте цикл while . Вы могли бы использовать цикл do-while, но я думаю, что обычный цикл будет работать просто отлично.

 static void _getStats()
{
    Random rnd = new Random();
    int stat1 = 0;
    int stat2 = 0;
    int stat3 = 0;
    int stat4 = 0;
    int stat5 = 0;
    int stat6 = 0;

    while (stat1 < 18 || stat2 < 18 || stat3 < 18 || stat4 < 18 || stat5 < 18 || stat6 < 18)
    {
        // rest of your code
    }

    // Move your printing after the while loop. Once one of the stats hits 18 or above,
    // print the results.
    Console.WriteLine(stat1);
    Console.WriteLine(stat2);
    Console.WriteLine(stat3);
    Console.WriteLine(stat4);
    Console.WriteLine(stat5);
    Console.WriteLine(stat6);
}