Как выбрать случайную строку из массива строк только один раз

Я пытаюсь сделать Hangman на С#, и в начале игры вам понадобится слово, чтобы догадаться, и поэтому игра не будет скучной, вы можете получить много слов (только по одному). Но когда вы начинаете новую игру, вы не получите ни слова, которое вы уже догадались. Поэтому я должен выбрать случайную строку, которую я уже выбрал.

Я попробовал несколько методов для решения этой проблемы, но ни один из них не прошел.

Способ №1:

Здесь я запускаю функцию NewWord, а затем добавляю 1 к numberOfTries.

string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
int numberOfTries = 0;
int randomNumber = -1;
protected string NewWord()
{ if (!(numberOfTries >= wordArr.Length)) { randomNumber = RandomNumberFromTo(0, (wordArr.Length - numberOfTries)); ChangeWord(((wordArr.Length - numberOfTries)-1), randomNumber); return wordArr[(randomNumberl)]; } else { return "There are no more new words!! :("; }
}
private int RandomNumberFromTo(int NumberA, int NumberB)
{ System.Threading.Thread.Sleep(2); Random minRandomGenerator = new Random(); System.Threading.Thread.Sleep(3); return minRandomGenerator.Next(NumberA, NumberB);
}
protected void ChangeWord (int NumberA, int NumberB)
{ string cashe1 = wordArr[NumberA]; wordArr[NumberA] = wordArr[NumberB]; wordArr[NumberB] = cashe1; return;
}

Метод № 2 Я нашел здесь, в StackOverflow, но это не сработало.

Здесь я также запускаю функцию NewWord, а затем добавляю 1 к numberOfTries.

string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" };
int numberOfTries = 0;
Random random = new Random();
protected string NyttOrd()
{ if (!(numberOfTries >= wordArr.Length)) { var names = new List<string> { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" }; System.Threading.Thread.Sleep(3); int index = random.Next(names.Count); var name = names[index]; names.RemoveAt(index); return name; } else { return "There are no more new words!! :("; }
}
</string>

Я также попробовал версию, в которой у меня было два разных массива: один - Int-Array, а второй - String-Array. Это было действительно грязно и не сработало.

Я также очень новичок в С#, я знаю только основы, такие как + -/*, convert, functions и массивы.

6 ответов

static readonly List<string> Words = new List<string>(wordArr);
static readonly Random Rnd = new Random();
public string Next()
{ if(Words.Count < 1) return "There are no more new words!! :("; var index = Rnd.Next(0, Words.Length); var result = Words[index]; Words.RemoveAt(index); return result;
}
</string></string>


Если вы перетасовываете свой массив слов:

var r = new Random();
var shuffledWords = wordArr.OrderBy(_ => r.Next());

затем вставьте свои слова в стек:

var wordStack = new Stack<string>(shuffledWords);
</string>

теперь у вас есть структура, которая передаст вам случайное слово из коллекции, одновременно удалив его из коллекции, используя метод Pop из Stack (значительно более эффективно, чем удаление элементов из передней/средней List, хотя ваша коллекция настолько мала, это не имеет большого значения).

var someWord = wordStack.Pop();


Концептуально вы либо отслеживаете строки, которые вы уже использовали, либо удаляете строки из списка необязательных строк по мере их использования.

Чтобы реализовать первый метод, вы можете сохранить хеш-таблицу строк, которые вы уже использовали, и когда вытягиваете новую строку - посмотрите, присутствует ли она в хэш-таблице (и если да, выберите другую, пока не появится "свежая" строка выбрал).

Чтобы реализовать второй метод, просто удалите строки, которые вы выбрали из списка, когда вы их выбираете.


Используйте ************.

Ключ будет вашим словом, значение будет сколько раз его использовать, затем просто возьмите наименее используемое слово и увеличите его счетчик.

List<************<string, int="">>
</************<string,>


Вы должны представить WordArr как список. Это проще для работы с учетом ваших потребностей.

Здесь простой способ рандомизировать ваш список:

List<string> wordArr = new List<string>()
{ "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO"
};
Random random = new Random();
wordArr = wordArr.OrderBy(x => random.Next()).ToList();
</string></string>

Затем просто выберите первое слово в списке, чтобы просто удалить каждое слово, которое вы используете следующим образом:

wordArr.RemoveAt(0);

Когда wordArr пуст, вы закончите.


Поскольку вы сказали, что новичок в программировании, я быстро объясню ключевую строку:

.Except() сравнивает ваш массив с другим массивом и возвращает только уникальные элементы. .OrderBy(x => rn.Next()) вернет массив в случайном порядке. .FirstOrDefault() получит первую запись из массива или, если массив пуст, верните значение null.

public void GenerateWord()
{ Random rn = new Random(); string[] attemptedWords = LoadUsedWords(); string[] wordArr = { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO" }; string word = wordArr.Except(attemptedWords).OrderBy(x => rn.Next()).FirstOrDefault(); if (string.IsNullOrEmpty(word)) { Console.WriteLine("Oh no"); } else { Console.WriteLine(word); }
}
public string[] LoadUsedWords()
{ return new string[] { "PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL" };
}

licensed under cc by-sa 3.0 with attribution.