Игра в палач с одним словом

Это игра с палачом. Единственное слово — «слово», и я не планирую его менять, так как не собираюсь публиковать эту игру или что-то еще.

Если мне нужно избавиться от ненужного / плохого кода, сообщите мне об этом.

Вот мой код:

using System;
using System.Threading;

namespace Hangman
{
    class Program
    {
        static void Restart()
        {
            try
            {
                Console.Write("restart? (y/n): ");

                char restart_input = Convert.ToChar(Console.ReadLine().ToLower());

                if(restart_input == 'y')
                {
                    Console.WriteLine("----------");
                    Main();
                }
                
                else if (restart_input == 'n')
                {
                    Console.Write("nPress any key to exit");
                    Console.ReadKey();
                }
                
                else if (restart_input != 'y' && restart_input != 'n')
                {
                    Console.WriteLine("ninvalid input");
                    Restart();
                }

            }

            catch(Exception e)
            {
                Console.Write("n" + e);
                Restart();
            }

        }

        static void Main()
        {
            Console.Title = "Hangman";

            int i = 0;
            int j = 1;

            bool has_guessed_the_letter = false;

            string word = "word";

            int failed_attempts = 0;
            int score = 0;

            Random random = new Random();
            int random_int = random.Next(0, 2);

            char[] char_array = word.ToCharArray();
            char?[] hidden_letters = new char?[i];

            foreach (char letter in char_array)
            {
                switch (random_int)
                {
                    case 1:
                        Console.Write(letter);
                        Thread.Sleep(200);
                        random_int = random.Next(0, 2);
                        break;

                    case 0:
                        Console.Write("_");
                        Thread.Sleep(200);
                        random_int = random.Next(0, 2);
                        Array.Resize(ref hidden_letters, j);
                        hidden_letters[i] = letter;
                        i++;
                        j++;
                        break;
                }
            }

            if (hidden_letters.Length == 0)
            {
                Console.Write("nthere are no hidden letters, lucky :)");
            }
            
            else if (hidden_letters.Length == word.Length)
            {
                Console.Write("nall letters are hidden, no luck :(");
            }
            
            else
            {           
                try
                {
                    label:

                    i = 0;
                    j = 1;

                    has_guessed_the_letter = false;

                    Console.Write("nninput: ");

                    char user_input = Convert.ToChar(Console.ReadLine());

                    while (has_guessed_the_letter == false && j <= hidden_letters.Length)
                    {
                        if (user_input == hidden_letters[i])
                        {
                            has_guessed_the_letter = true;
                            hidden_letters[i] = null;
                        }

                        else
                        {
                            i++; j++;
                        }

                    }

                    if (has_guessed_the_letter == true)
                    {
                        Console.WriteLine("Congratulations! " + j + ". hidden letter was " + user_input);
                        score++;                             
                        if (score == hidden_letters.Length)
                        {
                            Console.Write("nCongratulations! the hidden word was: " + word);
                        }
                        else
                        {
                            Console.WriteLine("score: " + score + " (must reach: " + hidden_letters.Length + ")");
                            Console.Write("failed attempts: " + failed_attempts + " (failed attempts left: " + ((word.Length * 2) - failed_attempts) + ")");
                            goto label;
                        }
                    }
                    else
                    {
                        Console.WriteLine("failed attempt: " + user_input);
                        failed_attempts++;
                        if (failed_attempts == (word.Length * 2))
                        {
                            Console.Write("ngame over. the hidden word was: " + word);
                        }
                        else
                        {
                            Console.WriteLine("score: " + score + " (must reach: " + hidden_letters.Length + ")");
                            Console.Write("failed attempts: " + failed_attempts + " (failed attempts left: " + ((word.Length * 2) - failed_attempts) + ")");
                            goto label;
                        }
                    }
                }

                catch(Exception e)
                {
                    Console.Write("n" + e);
                }                
            }
            Console.WriteLine("n----------");
            Restart();
        }
    }
}

1 ответ
1

Есть еще несколько вещей, чем я хотел бы сейчас остановиться, но есть два важных вопроса ™, которые я хочу затронуть. Один из них goto а другой — рекурсия в Restart метод. В конце концов, рекурсия взорвет стек. И goto — это просто дурной тон за прошлый 1985 год. Вот переработанная версия, в которой рассматриваются оба эти пункта (плюс небольшая поточная безопасность вокруг Random на всякий случай):

namespace Hangman
{
    using System;
    using System.Threading;

    internal static class Program
    {
        private static readonly Random _Random = new ();

        private enum ShouldRestart
        {
            Invalid,

            No,

            Yes
        }

        private static ShouldRestart Restart()
        {
            Console.Write("restart? (y/n): ");

            char restartInput = Convert.ToChar(Console.ReadLine()?.ToLower() ?? string.Empty);

            if (restartInput == 'y')
            {
                Console.WriteLine("----------");
                return ShouldRestart.Yes;
            }

            if (restartInput == 'n')
            {
                Console.Write("nPress any key to exit");
                Console.ReadKey();
                return ShouldRestart.No;
            }

            Console.WriteLine("ninvalid input");
            return ShouldRestart.Invalid;
        }

        private static void Main()
        {
            Console.Title = "Hangman";

            while (true)
            {
                int i = 0;
                int j = 1;

                const string Word = "word";

                int failedAttempts = 0;
                int score = 0;
                int randomInt;

                lock (_Random)
                {
                    randomInt = _Random.Next(0, 2);
                }

                char[] charArray = Word.ToCharArray();
                char?[] hiddenLetters = new char?[i];

                foreach (char letter in charArray)
                {
                    switch (randomInt)
                    {
                        case 1:
                            Console.Write(letter);
                            Thread.Sleep(200);
                            lock (_Random)
                            {
                                randomInt = _Random.Next(0, 2);
                            }

                            break;

                        case 0:
                            Console.Write("_");
                            Thread.Sleep(200);
                            lock (_Random)
                            {
                                randomInt = _Random.Next(0, 2);
                            }

                            Array.Resize(ref hiddenLetters, j);
                            hiddenLetters[i] = letter;
                            i++;
                            j++;
                            break;
                    }
                }

                if (hiddenLetters.Length == 0)
                {
                    Console.Write("nthere are no hidden letters, lucky :)");
                }
                else if (hiddenLetters.Length == Word.Length)
                {
                    Console.Write("nall letters are hidden, no luck :(");
                }
                else
                {
                    while (true)
                    {
                        i = 0;
                        j = 1;

                        bool hasGuessedTheLetter = false;

                        Console.Write("nninput: ");

                        char userInput = Convert.ToChar(Console.ReadLine() ?? string.Empty);

                        while (!hasGuessedTheLetter && j <= hiddenLetters.Length)
                        {
                            if (userInput == hiddenLetters[i])
                            {
                                hasGuessedTheLetter = true;
                                hiddenLetters[i] = null;
                            }
                            else
                            {
                                i++;
                                j++;
                            }
                        }

                        if (hasGuessedTheLetter)
                        {
                            Console.WriteLine("Congratulations! " + j + ". hidden letter was " + userInput);
                            score++;
                            if (score == hiddenLetters.Length)
                            {
                                Console.Write("nCongratulations! the hidden word was: " + Word);
                                break;
                            }

                            Console.WriteLine("score: " + score + " (must reach: " + hiddenLetters.Length + ")");
                            Console.Write("failed attempts: " + failedAttempts + " (failed attempts left: " + ((Word.Length * 2) - failedAttempts) + ")");
                        }
                        else
                        {
                            Console.WriteLine("failed attempt: " + userInput);
                            failedAttempts++;
                            if (failedAttempts == (Word.Length * 2))
                            {
                                Console.Write("ngame over. the hidden word was: " + Word);
                                break;
                            }

                            Console.WriteLine("score: " + score + " (must reach: " + hiddenLetters.Length + ")");
                            Console.Write("failed attempts: " + failedAttempts + " (failed attempts left: " + ((Word.Length * 2) - failedAttempts) + ")");
                        }
                    }
                }

                Console.WriteLine("n----------");

                ShouldRestart shouldRestart = ShouldRestart.Invalid;

                while (shouldRestart == ShouldRestart.Invalid)
                {
                    shouldRestart = Restart();
                }

                if (shouldRestart == ShouldRestart.No)
                {
                    break;
                }
            }
        }
    }
}

  • 1

    ConsoleKey restartInput = Console.ReadKey().Key; Console.WriteLine(); if (restartInput == ConsoleKey.Y) { restart } else { exit } — может работать более дружелюбно для пользователя.

    — эспот

  • 1

    lock for Random — это своего рода избыточность в одном потоке, и это выглядит странно. Кстати, если вам нужен классный потокобезопасность, попробуйте [ThreadStatic] выше Random строка определения вместо lock.

    — эспот


  • сэр. это самый запутанный код C #, который я читал в своей жизни

    — user13988674


  • @ user13988674 изменения в вашем коде настолько минимальны, что я искренне удивлен этим комментарием.

    — Джесси С. Слайсер

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *