Это игра с палачом. Единственное слово — «слово», и я не планирую его менять, так как не собираюсь публиковать эту игру или что-то еще.
Если мне нужно избавиться от ненужного / плохого кода, сообщите мне об этом.
Вот мой код:
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 ответ
Есть еще несколько вещей, чем я хотел бы сейчас остановиться, но есть два важных вопроса ™, которые я хочу затронуть. Один из них 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;
}
}
}
}
}
ConsoleKey restartInput = Console.ReadKey().Key; Console.WriteLine(); if (restartInput == ConsoleKey.Y) { restart } else { exit }
— может работать более дружелюбно для пользователя.— эспот
lock
for Random — это своего рода избыточность в одном потоке, и это выглядит странно. Кстати, если вам нужен классный потокобезопасность, попробуйте[ThreadStatic]
вышеRandom
строка определения вместоlock
.— эспот
сэр. это самый запутанный код C #, который я читал в своей жизни
— user13988674
@ user13988674 изменения в вашем коде настолько минимальны, что я искренне удивлен этим комментарием.
— Джесси С. Слайсер