我正在尝试用C#制作Hangman,并且在游戏开始时你需要一个词来猜测,所以游戏不会无聊你可以得到很多单词(一次只有一个)。但是当你开始一个新游戏时,你不会得到你已经猜到的一个词。所以我必须选择一个我尚未选择的随机字符串。
我尝试过多种方法来解决这个问题,但没有一种方法能够成功。
方法#1:
这里我运行NewWord函数,然后在numberOfTries中添加1。
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函数,然后在numberOfTries中添加1。
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!! :(";
}
}
我还尝试了一个版本,其中我有两个不同的数组,一个是Int-Array,另一个是String-Array。这真的很乱,没用。
我也是C#的新手我只知道基础知识,比如+ - / *,转换,函数和数组。
答案 0 :(得分:2)
从概念上讲,您要么跟踪已经使用过的字符串,要么在使用它们时从可选字符串列表中删除字符串。
要实现第一种方法,您可以保留已经使用的字符串的散列表,并在拉出新字符串时 - 查看它是否存在于散列表中(如果是,请选择另一个,直到“新鲜” “挑选字符串。”
要实现第二种方法,只需在选择时删除从列表中选取的字符串。
答案 1 :(得分:2)
如果你改变你的单词数组:
var r = new Random();
var shuffledWords = wordArr.OrderBy(_ => r.Next());
然后将你的单词推入堆栈:
var wordStack = new Stack<string>(shuffledWords);
现在你有了一个结构,可以使用Pop
Stack<T>
方法从集合中随机删除它,同时从集合中移除它(比从前面删除项目要高效得多)在List<T>
的中间,虽然你的收藏很小,但这并不重要。)
var someWord = wordStack.Pop();
答案 2 :(得分:0)
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;
}
答案 3 :(得分:0)
答案 4 :(得分:0)
既然你说过你是编程新手,我会快速解释一下关键线:
.Except()将您的数组与另一个数组进行比较,并仅返回唯一元素。 .OrderBy(x =&gt; 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" };
}
答案 5 :(得分:0)
您应该将WordArr
列为清单。它可以更轻松地满足您的需求。
这是一种随机化列表的简便方法:
List<string> wordArr = new List<string>()
{
"PROGRAMMERING", "CSHARP", "STOL", "ELEV", "VISUAL", "STUDIO"
};
Random random = new Random();
wordArr = wordArr.OrderBy(x => random.Next()).ToList();
然后只需要总是拿下列表中的第一个单词,这样就可以简单地删除你使用的每个单词:
wordArr.RemoveAt(0);
当wordArr
为空时,您就完成了。