【问题标题】:How to allow user to try again or quit console program in C#?如何允许用户重试或退出 C# 中的控制台程序?
【发布时间】:2015-10-15 20:04:15
【问题描述】:

我创建了一个游戏,让玩家有 5 次玩机会,之后我想问玩家是想再玩还是退出。我已经看到它是用 Python 完成的,但我不知道 Python。我的代码工作得很好,但我想添加这两个额外的功能 如何在 C# 中实现这些功能? 作为参考,这是我的代码主类代码的样子。

namespace NumBaseBall
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("\t\t\t*************************************");
            Console.WriteLine("\t\t\t*      Let's Have Some Fun          *");
            Console.WriteLine("\t\t\t*           Welcome To The          *");
            Console.WriteLine("\t\t\t*       Number Baseball Game        *");
            Console.WriteLine("\t\t\t*************************************\n");

            GameResults gameresults = new GameResults();

            for (int trysCounter = 1; trysCounter <= 5; trysCounter++)
            {
                gameresults.Strikes = 0; 

                Random r = new Random();
                var myRange = Enumerable.Range(1, 9);
                var computerNumbers = myRange.OrderBy(i => r.Next()).Take(3).ToList();
                Console.WriteLine("The Game's Three Random Integers Are: (Hidden from user)");
                 foreach (int integer in computerNumbers)
                 {
                     Console.WriteLine("{0}", integer);
                 }

                 List<int> playerNumbers = new List<int>();
                 Console.WriteLine("Please Enter Three Unique Single Digit Integers and Press ENTER after each:");
                 for (int i = 0; i < 3; i++)
                 {
                      Console.Write("");
                      int number = Convert.ToInt32(Console.ReadLine());
                                  playerNumbers.Add(number);
                 }

                 gameresults.StrikesOrBalls(computerNumbers,playerNumbers);
                 Console.WriteLine("---> Computer's Numbers = {0}{1}{2}", computerNumbers[0], computerNumbers[1], computerNumbers[2]);
                 Console.WriteLine("---> Player's Numbers = {0}{1}{2}", playerNumbers[0], playerNumbers[1], playerNumbers[2]);
                 Console.WriteLine("---> Game Results = {0} STRIKES & {1} BALLS\n", gameresults.Strikes, gameresults.Balls);
                 Console.WriteLine("You have played this games {0} times\n", trysCounter);

                  gameresults.TotalStrikes = gameresults.TotalStrikes + gameresults.Strikes;

                  Console.WriteLine("STRIKES = {0} ", gameresults.TotalStrikes);

                   if (gameresults.TotalStrikes >= 3)
                   {
                       gameresults.Wins++;
                       Console.WriteLine("YOU ARE A WINNER!!!");
                       break;
                   }
               }
                       if (gameresults.TotalStrikes <3)
                       Console.WriteLine("YOU LOSE :( PLEASE TRY AGAIN!");
           }
       }
   }

【问题讨论】:

  • 请解释您的代码是如何不工作的,这样我们就不必猜测了。
  • 请花时间来格式化您的代码,所以它并没有完全正确 - 最好将其简化为 minimal 示例。根本不清楚“数组”和“列表”标签与问题有什么关系。
  • 提示解决这个问题:分离关注点。将大部分代码从您的 main 方法中移到一个名为 PlayGame 的方法中。那时,我们不需要关心里面有什么——我们只需要修复询问用户是否想再次玩,如果他们想再次调用该方法。
  • 一种可能的方法是将 for 循环放在一个单独的方法中,在该方法中初始化变量。当用户输了,再次调用该方法重置游戏。

标签: c# console console-application exit


【解决方案1】:

将您的代码插入到一个循环中,以检查用户是否要继续:

while(true) // Continue the game untill the user does want to anymore...
{

    // Your original code or routine.

    while(true) // Continue asking until a correct answer is given.
    {
        Console.Write("Do you want to play again [Y/N]?");
        string answer = Console.ReadLine().ToUpper();
        if (answer == "Y")
             break; // Exit the inner while-loop and continue in the outer while loop.
        if (answer == "N")
             return; // Exit the Main-method.
    }
}

但也许将一个大例程拆分成单独的例程会更好。

让我们将您的 Main 方法重命名为 PlayTheGame

把我的日常工作分成:

static public bool PlayAgain()
{
    while(true) // Continue asking until a correct answer is given.
    {
        Console.Write("Do you want to play again [Y/N]?");
        string answer = Console.ReadLine().ToUpper();
        if (answer == "Y")
             return true;
        if (answer == "N")
             return false;
    }
}

现在 Main-method 可以是:

static void Main(string[] args)
{
    do
    {
         PlayTheGame();
    }
    while(PlayAgain());
}

您必须将一些局部变量作为静态字段移动到类中。或者你可以创建一个 Game 类的实例,但我认为这是目前的一步。

【讨论】:

    【解决方案2】:

    有两种方法可以实现:

    https://msdn.microsoft.com/en-us/library/system.diagnostics.process.kill%28v=vs.110%29.aspx

    System.Diagnostics.Process.GetCurrentProcess().Kill();
    

    或者

    https://msdn.microsoft.com/en-us/library/system.environment.exit(v=vs.110).aspx

    int exitCode =1;
    System.Environment.Exit(exitCode);
    

    Environment.Exit 是退出程序的首选方式,因为 Kill 命令“会导致进程异常终止,应仅在必要时使用。”[msdn]

    【讨论】:

    • 正常退出 Main 函数会更好,因为 Exit 不会执行所有外部 finally 块。
    【解决方案3】:

    首先,建议将实际游戏的代码移动到一个单独的函数中。它会清理很多东西。

    类似

    private static bool PlayGame()
    {
        // Win branch returns true.
        // Loss branch returns false.
    }
    

    这可以让您大大简化Main 函数,使其只处理菜单功能。

    对于实际的菜单功能,我倾向于使用do/while 循环。你有一点额外的规定,你只在播放 5 次后才询问,但这很容易处理。

    static void Main(string[] args)
    {
        int playCount = 0;
        string answer = "Y";
        bool winner;
    
        do
        {
            if(playCount < 5)
            {
                playCount++;
            }
            else
            {
                do
                {
                    Console.Write("Play again? (Y/N): ");
                    answer = Console.ReadLine().ToUpper();
                } while(answer != "Y" && answer != "N");
            }
    
            winner = PlayGame();
        } while(!winner && answer == "Y");
    
        Console.WriteLine("Thanks for playing!");
    }
    

    您可以通过使用增量运算符将 5 场比赛的测试移动到 if 条件中来简化它。唯一的问题是,如果有人玩你的游戏十亿次左右,事情可能会变得很奇怪。

    static void Main(string[] args)
    {
        int playCount = 0;
        string answer = "Y";
        bool winner;
    
        do
        {
    
    
            if(playCount++ > 3)
            {
                do
                {
                    Console.Write("Play again? (Y/N): ");
                    answer = Console.ReadLine().ToUpper();
                } while(answer != "Y" && answer != "N");
            }
    
            winner = PlayGame();
        } while(!winner && answer == "Y");
    
        Console.WriteLine("Thanks for playing!");
    }
    

    编辑:稍微更改了一些内容,就像在您的原始代码中显示的那样,游戏在该人赢得游戏后结束。


    根据您在下面评论中的问题,您可以在 Program 类中创建 GameResults 类的静态实例。您的代码最终会如下所示

    class Program
    {
        private static GameResults results = new GameResults();
    
        public static void Main(string[] args)
        {
            // Code
        }
    
        private static bool PlayGame()
        {
            // Code
        }
    }
    

    PlayGame 中,您只需使用静态results 对象,而不是每次调用PlayGame 时都创建一个新对象。

    【讨论】:

    • @BradfordDillion 当你说“将实际游戏的代码移动到一个单独的函数中。它会清理很多东西。”你到底指的是什么代码?因为我有一个名为GameResults 的外部类,它也处理游戏的一些功能
    • @AaronLWG 可能存在于上述forloop 中的大部分代码都可以移动到单独的函数中。
    • @BradfordDillion 我可以为您提供一些额外的帮助吗?如果玩家继续玩,我正在尝试增加并保存玩家的获胜次数。然而,每次他再次尝试时,他之前的获胜次数都会被清空,然后他又从零开始。我知道这是因为我在每次玩新游戏时都会创建一个 GameResults 的新实例,但我不确定如何保存他的获胜次数。你能帮忙吗?
    • @AaronLWG 请参阅上面的编辑以回答您的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 2014-02-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多