#c#
#c#
Вопрос:
Я новичок в C #, и я изучаю его в течение последних нескольких недель, в основном выполняя задания и задачи, чтобы улучшить свои знания. Я наткнулся на создание консольного приложения «Hangman», и я близок к его завершению. На самом деле, я могу сказать, что я сделал это, но я хотел бы кое-что улучшить и узнать одну новую вещь.
Это пример моего вопроса, если вы не можете его понять, извините, английский не мой основной язык. Вы знаете, как, когда вы играете в hangman, как только вы угадываете правильную букву, эта буква «показывает себя» на своей позиции в слове.
etc. word Head
you guess "e" and it prints _e__
you guess "d" and it prints _e_d
you guess "H" and it prints He_d
you guess "a" and it prints Head
Вот мой код :
using System;
namespace Hangman
{
class Program
{
static void Main(string[] args)
{
Random random = new Random();
string word1;
Console.Write("Please enter a random word: ");
word1 = Console.ReadLine();
word1.ToLower();
Console.Clear();
int i = 0;
int j = 0;
do
{
string guess;
Console.Write("Please enter a letter: ");
guess = Console.ReadLine();
if (guess == ""
"")
{
i = 1;
Console.WriteLine($"Not allowed. You have {word1.Length - i} tries left.n");
}
else if(word1.Contains(guess) == true)
{
Console.WriteLine("You guessed correctly !n");
j = 1;
}
else
{
i = 1;
Console.WriteLine($"You guessed wrongly ! You have {word1.Length - i} tries leftn");
}
/* If you guessed all the letters correctly this will print that you won */
if (j == word1.Length)
{
Console.Clear();
Console.WriteLine($"You won ! The guessing word was {word1}.n");
}
/* If you tried too many times it will end your program and you will lose.
* If you guessed all letters in a word correctly you win and the game is done. */
if(i == word1.Length)
{
Console.Clear();
Console.WriteLine($"You lost ! The guessing word was {word1}.n");
}
} while (i != word1.Length amp; j != word1.Length);
}
}
}
Комментарии:
2. Я действительно не вижу способа сделать это с помощью метода, который вы опубликовали. Не могли бы вы немного объяснить?
3. Вы можете напечатать символ в указанной позиции, о чем просил заголовок вашего вопроса, нет?
Ответ №1:
В вашем коде есть несколько ошибок, если хотите —
Если вы вводите слово head
и продолжаете угадывать h
, вы выигрываете.
Когда вы вводите свое предположение, вы можете фактически ввести строку, а не только один символ.
Также код не учитывает возможность ввода нескольких символов. Например, если слово alexleo
— и я предполагаю l
— это даст мне только одно совпадение.
Что нам нужно сделать, так это отслеживать статус каждой буквы в слове, то есть угадана буква или нет.
На каждой итерации:
- Пользователь угадывает букву —
- Если буква содержится в слове — меняем статус на угадано.
- Если буква уже угадана, мы предупреждаем пользователя.
- Если буква не содержится в слове — увеличиваем наш флаг
totalGuessCounts
на 1. - Мы оставляем отзыв пользователю и показываем то, что было угадано до сих пор.
Цикл завершается, когда мы либо выигрываем, либо у пользователя заканчиваются догадки.
Во-первых, я определил свой класс настройки букв
public class LetterSetting
{
public char Letter { get; set; }
public bool HasBeenGuessed { get; set; }
public LetterSetting(char letter, bool hasBeenGuessed)
{
this.Letter = letter;
this.HasBeenGuessed = hasBeenGuessed;
}
}
Затем я определил класс hangman word — здесь мы отслеживаем угаданную букву, логику, чтобы увидеть, выиграли ли мы, и отображение того, что у нас есть на данный момент.
static class HangmanWord
{
static List<LetterSetting> LettersStatus = new List<LetterSetting>();
public static void Initialise(string word)
{
foreach (char letter in word)
{
LettersStatus.Add(new LetterSetting(letter, false));
}
}
public static bool SetGuessStatus(char letter)
{
List<LetterSetting> tempLettersStatus = new List<LetterSetting>();
foreach (LetterSetting item in LettersStatus)
{
if (item.Letter == letter amp;amp; item.HasBeenGuessed)
{
return false;
}
tempLettersStatus.Add(item.Letter == letter ? new LetterSetting(letter, true) : item);
}
LettersStatus = tempLettersStatus;
return true;
}
public static void Display()
{
StringBuilder hangManWord = new StringBuilder();
foreach (var item in LettersStatus)
{
hangManWord.Append(!item.HasBeenGuessed ? '_' : item.Letter);
}
Console.SetCursorPosition(50, 1);
Console.Write(hangManWord.ToString());
Console.SetCursorPosition(0,1);
}
public static bool HaveWeWon()
{
return !LettersStatus.Any(letter => letter.HasBeenGuessed == false);
}
}
Ваш основной класс просто инкапсулирует для извлечения слова и игрового цикла:
class Program
{
static void Main(string[] args)
{
int totalGuessCounts = 0;
int maxNumberOfGuess = 0;
Console.Write("Please enter a random word: ");
string word = Console.ReadLine()?.ToLower();
while (word != null amp;amp; word.Contains(" ") || string.IsNullOrWhiteSpace(word))
{
Console.Clear();
Console.WriteLine("Word must not contain spaces or be nothing ");
Console.Write("Please enter a random word: ");
word = Console.ReadLine()?.ToLower();
}
maxNumberOfGuess = word.Length;
HangmanWord.Initialise(word);
Console.Clear();
HangmanWord.Display();
do
{
Console.Write("Please enter a letter: ");
char guess = Console.ReadKey().KeyChar;
Console.WriteLine("n");
Console.Clear();
if (!char.IsLetterOrDigit(guess))
{
continue;
}
if (word.Contains(guess))
{
Console.WriteLine(HangmanWord.SetGuessStatus(guess)
? "You guessed correctly!"
: "You already guessed that letter.");
}
else
{
totalGuessCounts ;
Console.WriteLine($"You guessed wrongly ! You have {word.Length - totalGuessCounts} tries leftn");
}
if (HangmanWord.HaveWeWon())
{
Console.WriteLine($"You won ! The guessing word was {word}.n");
break;
}
if (totalGuessCounts == maxNumberOfGuess)
{
Console.WriteLine($"You lost ! The guessing word was {word}.n");
}
HangmanWord.Display();
} while (totalGuessCounts != word.Length);
}
}
вы можете изменить макет обратной связи — на свой вкус — добавить словарь слов, чтобы вам не приходилось вводить слово самостоятельно — нарисуйте палача, пока пользователь угадывает — В идеале вы можете перенести всю логику в класс HangmanWord — то есть для неудачи, успеха и полной обратной связи.
Комментарии:
1. Спасибо! Весь этот новый код немного сложен для понимания, но я постараюсь понять, что он делает и как он работает.
2. Хорошо, никаких проблем — вот консольное приложение, которое все вместе может помочь вам понять — codeshare.io/5Mrrwn если вам нужна дополнительная информация, дайте мне знать.
3. забыл упомянуть codeshare.io/5Mrrwn истекает через 24 часа
Ответ №2:
Я закодировал что-то вроде этого. Это мое предложение для решения этой проблемы, но помните, что оно, вероятно, не самое лучшее. Вы можете попробовать оптимизировать его.
bool[] guessed = new bool[wordToGuess.Length];
int index = 0;
while ((index = wordToGuess.IndexOf(guess, index, wordToGuess.Length - index)) != -1)
{
guessed[index] = true;
index ;
}
for(int i = 0; i < wordToGuess.Length; i )
{
if(guessed[i])
Console.Write(wordToGuess[i]);
else
Console.Write('_');
}
Я использовал String.Метод indexOf(String, Int32, Int32) для этой цели.
Комментарии:
1. Спасибо. Я пытался оптимизировать для себя, но у меня это не работает.