我的游戏在结束屏幕上有一个“重新启动游戏”按钮,该按钮调用StartGame()方法。如何避免递归和最终的堆栈溢出?

时间:2019-11-18 14:34:25

标签: c# recursion menu stack-overflow

MCVE在下面。如何避免递归调用StartGame()和DisplayEndScreen?一种方法是循环遍历StartGame(),但这似乎不是一个可扩展的解决方案,更多的是hack。另一个解决方案可能是:当用户按下R键重新启动时,以某种方式返回主菜单并输入Enter键作为switch语句的输入。

什么是好的解决方案?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Main Menu: Press Enter to start the game >>");

            switch (Console.ReadKey(true).Key)
            {
                case ConsoleKey.Enter:
                    StartGame();
                    break;

                    // Other Menu Items

            }
        }

        private static void StartGame()
        {
            // Do Game

            DisplayEndScreen();    // NB: This causes recursion! I don't want this.
        }

        private static void DisplayEndScreen()
        {
            Console.WriteLine("Game Over! Select an option >> \n\n" +
                "R:\tPlay again\n" +
                "M:\tReturn to Main Menu\n" +
                "Q:\tQuit");

            switch (Console.ReadKey(true).Key)
            {
                case ConsoleKey.R:
                    StartGame();    // NB: This causes recursion! I don't want this.
                    break;

                    // Other Menu Items

            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

在StartGame()中调用StartGame()会导致递归。避免这种情况的方法就是根本不在自身内部调用方法。

我认为这些函数的名称对于您的程序有些混乱,您确定“ StartGame”正确地描述了该函数的作用吗?似乎更有可能是实际的游戏(game()?)本身。如果名称反而告诉您游戏实际上正在运行(看起来像正在运行),那么再次调用它对您来说意义不大。

考虑到运行游戏,大多数基本解决方案通常如下所示:

    bool game = true;
    while(game)
    {
      //game running
      if(exit)
      {
        game = false;
      }
    }