我的游戏在结束屏幕上有一个 "restart game" 按钮,它调用 StartGame() 方法。如何避免递归和最终的堆栈溢出?

My game has a "restart game" button on the end screen which calls the StartGame() method. How do I avoid recursion and eventual stack overflow?

MCVE 在下方。如何避免递归调用 StartGame() 和 DisplayEndScreen?一种方法是遍历 StartGame(),但这似乎不是一个可扩展的解决方案,更像是一种 hack。另一种解决方案可能是:当用户点击 R 重新启动时,return 到主菜单并以某种方式将 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

            }
        }
    }
}

在 StartGame() 内部调用 StartGame() 会导致递归。避免它的方法就是不在其自身内部调用方法。

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

考虑运行一款游戏,最基本的解决方案通常如下所示:

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