如何更新链接到列表的数组<string>

How to update an array that's linked to a List<string>

所以我正在做这个项目,我真的是编程新手。我正在尝试使用 C# 制作 Hangman 游戏,但我有点卡住了。我可以在控制台上很好地显示所有内容,但是在猜测单词 CRYPTOZOOLOGY 时,如果用户的猜测实际上在单词中,我无法将下划线更改为正确的字母。所以现在如果用户猜测 'C' 那么游戏将继续要求用户选择一个字母。这不是我想要的。我想做的是,一旦用户猜出正确的字母,我希望下划线更新以显示正确的字母,并 'Used Letters: ' 以反映总共使用的字母。我相信我的问题可能是层次结构问题,但我已经为此工作了几个小时,此时我非常沮丧。我希望我可以让这个问题更容易回答,但我觉得我没有太多选择。下面列出了我的代码。谢谢

更新: 我添加了一个 while 循环,这样一旦主体中的所有内容都完成,代码就可以从顶部 运行 开始。我在用户做出选择后清​​除了控制台。我现在的问题是在下划线所在的正确位置输出字母。

更新:我能够将字母 'C' 添加到下划线的开头。现在,如果我输入 'R',使用的字母列表将显示我使用的字母,但即使它是正确的字母,也不会更新下划线。

        public void GameDisplay(int randomNumber, Dictionary<string, string> randomKeyValue)
        {
            bool gameRunning = true;
            if (randomNumber == 0)
            {
                // Displaying the title
                Console.WriteLine("===================================");
                Console.WriteLine("              HANGMAN          ");
                Console.WriteLine("===================================");

                while (gameRunning)
                {

                    // Pulling the definition based on the Key of the word Dictionary
                    string randomDefinition = randomKeyValue["CRYPTOZOOLOGY"];

                    string associatedWord = "CRYPTOZOOLOGY";


                    string[] arrWord = { "C", "R", "Y", "P", "T", "O", "Z", "O", "O", "L", "O", "G", "Y" };

                    Console.WriteLine("\r\nDefinition: {0}\r\n", randomDefinition);


                       for (int i = 0; i < arrWord.Length; i++)
                    {
                     
                        if (_guesses.Contains(arrWord[i])) 
                        {
                            Console.Write("{0} ", _guesses[i]);

                        }

                        else
                        {
                            Console.Write("__ ");
                        }
                    }



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


                    Console.WriteLine("Used Letters: ");

                    foreach (string miss in _misses)
                    {
                        Console.Write("{0} ", miss);
                    }



                    Console.WriteLine("\r\n========================================\r\n");


                    bool winning = false;


                    if (winning == false)
                    {

                        while (!winning)
                        {
                            GuessAgain(_guesses, _misses, arrWord, associatedWord);
                            AllMisses(_guesses);
                            Console.Clear();
                            winning = true;
                        }

                        /*Console.WriteLine("You won!");
                        _guesses.Clear();
                        winning = false;
                        */
                    }
                    else if (_guesses.Contains("C") && _guesses.Contains("R") && _guesses.Contains("Y") && _guesses.Contains("P") && _guesses.Contains("T") && _guesses.Contains("O") && _guesses.Contains("Z") && _guesses.Contains("L") && _guesses.Contains("G") && _guesses.Contains("Y"))
                    {

                        while (!winning)
                        {
                            GuessAgain(_guesses, _misses, arrWord, associatedWord);
                            AllMisses(_guesses);
                            Console.Clear();
                            winning = true;
                        }

                        // Console.WriteLine("Game over...");

                    }


                }

                Console.ReadLine();
            }
            
            // INSTRUCTIONS
            // display each letter in the word and replace with an underscore if its not within guesses


            // While the user has not won or misses 6 times
            // Call a method to display the misses
            // Call a method to allow the player to guess and make sure to validate against repeats

            // Display win/lose hangman message

        }


        public static bool AllMisses(List<string> misses)
        {
            bool winning = false;

            if (misses.Count == 6)
            {
                winning = true;
            }

            return winning;
        }

        public static void GuessAgain(List<string> guesses, List<string> misses, string[] arrWord, string actualWord)
        {

              Console.WriteLine("Choose a letter:");

            string userGuess = Console.ReadLine();
            string userGuessCaps = userGuess.ToUpper();

            while (string.IsNullOrWhiteSpace(userGuess))
            {
                Console.WriteLine("Please do not leave this blank.");
                Console.WriteLine("Choose a letter.");
                userGuess = Console.ReadLine();
            }

            for (int i = 0; i < arrWord.Length; i++)
            {
                if (userGuessCaps == arrWord[i] )
                {
                    guesses.Add(userGuessCaps);
                    break;
                }
                else if (userGuessCaps != arrWord[i]) 
                {
                    misses.Add(userGuessCaps);
                    AllMisses(misses);
                    break;

                }
            }
        }
    }

以下是可行的解决方案。

public static void Main(string[] args)
{

    string associatedWord = "CRYPTOZOOLOGY";
    List<string> arrWord = new List<string>() { "C", "R", "Y", "P", "T", "O", "Z", "O", "O", "L", "O", "G", "Y" };

    List<string> _guesses = new List<string>();
    List<string> _misses = new List<string>();
    bool winning = false;

    while (!winning)
    {

        Console.Clear();

        // Displaying the title
        Console.WriteLine("===================================");
        Console.WriteLine("              HANGMAN          ");
        Console.WriteLine("===================================");

        // Iterate through each letter in arrWord and display Correct Guesses or __ for not discovered letters
        foreach (string letter in arrWord)
        {
            // Print either the correctly guessed letter or __ for not guessed yet.
            if (_guesses.Contains(letter))
                Console.Write(" " + letter + " ");
            else
                Console.Write("__ ");
        }
                
        // Print all the letters that have been missed.
        Console.WriteLine("\r\n\r\n------------------------------------\r\n");
        Console.WriteLine("Used Letters: " + string.Join(" ", _misses));
        Console.WriteLine("\r\n========================================\r\n");
            
        // Run the method to guess the letter.
        GuessAgain(_guesses, _misses, arrWord, associatedWord);

        // If misses == 6 or if you guessed all the letters, exit.
        winning = AllMisses(_misses) || arrWord.Where(x => _guesses.Contains(x)).Count() == arrWord.Count();
    }

    if (arrWord.Where(x => !_guesses.Contains(x)).Count() > 0)
        Console.WriteLine("LOST");
    else
        Console.WriteLine("WON");
}

public static bool AllMisses(List<string> misses)
{
    // No need to use extra variables to see if the misses count has reached 6
    return misses.Count == 6;
}

public static void GuessAgain(List<string> guesses, List<string> misses, List<string> arrWord, string actualWord)
{
    Console.WriteLine("Choose a letter:");

    string userGuess = Console.ReadLine().ToUpper(); // Change user's input to upper case

    while (string.IsNullOrWhiteSpace(userGuess))
    {
        Console.WriteLine("Please do not leave this blank.");
        Console.WriteLine("Choose a letter.");
        userGuess = Console.ReadLine().ToUpper(); // Change user's input to upper case
    }

    // Only add the letter to "ONE" of the lists. either it was a guess or a miss. Your code adds 12 letters at a time.. not what you want.
    // You can also add checks to see if the letter has already been guessed before or not.
    if (arrWord.Contains(userGuess))
        guesses.Add(userGuess);

    else
        misses.Add(userGuess);
}

我在您的代码中发现需要稍作修改的地方

  1. 对 arrWord 使用列表...使用 Linq 查询使事情变得更容易。
  2. 一个循环遍历整个代码...您也可以创建一个方法,但是发现不需要多个 while 循环和 for 循环。
  3. 修改代码见注释

我喜欢刽子手!感谢“功课”。

这是另一种方法:

static void Main(string[] args)
{
    string word = "CRYPTOZOOLOGY";

    bool result = PlayHangman(word);
    Console.WriteLine();
    if (result)
    {
        
        Console.WriteLine("You guessed my word: " + word);
    }
    else
    {
        Console.WriteLine("You ran out of tries!");
        Console.WriteLine("The word was: " + word);
    }

    Console.Write("Press Enter to Quit");
    Console.ReadLine();
}

static bool PlayHangman(string word, int maxMisses = 6)
{
    int misses = 0;
    string wordToGuess = word.ToUpper();
    StringBuilder currentWord = new StringBuilder(new string('_', wordToGuess.Length));
    string validLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    string availableLetters = validLetters;
    while (currentWord.ToString() != wordToGuess && misses < maxMisses)
    {
        Console.WriteLine();
        Console.WriteLine("Guesses Left: " + (maxMisses - misses));
        Console.WriteLine("Word: " + currentWord.ToString());
        Console.WriteLine("Available Letters: " + availableLetters);
        Console.Write("Your guess: "); ;
        string guess = Console.ReadLine().Trim().ToUpper();
        if (guess.Length == 1 && validLetters.Contains(guess))
        {
            if (availableLetters.Contains(guess))
            {
                int letterFound = 0;
                for (int i = 0; i < wordToGuess.Length; i++)
                {
                    if(wordToGuess.Substring(i,1) == guess)
                    {
                        currentWord[i] = guess.ToCharArray()[0];
                        letterFound++;
                    }
                }
                availableLetters = availableLetters.Replace(guess, "");
                if (letterFound == 0)
                {
                    Console.WriteLine(guess + " was not in the word!");
                    misses++;
                }
                else
                {
                    Console.WriteLine(guess + " was found " + letterFound + " time" + (letterFound>1 ? "s" : "") + "!");
                }
            }
            else
            {
                Console.WriteLine("You already tried that letter!");
            }
        }
        else
        {
            Console.WriteLine("Invalid Input. Please try again.");
        }
    }
    return (misses < maxMisses);
}