尝试制作一个没有重复的随机选择器.它有效,但只有4次?(C#窗体)
本文关键字:有效 选择器 窗体 4次 随机 一个 | 更新日期: 2023-09-27 18:23:55
正如标题所说,我正在尝试制作一段代码,使用C#在windows窗体中随机选择一个没有重复的组(a-H)。这似乎奏效了,但在4次之后,它将返回所有组都已被选中。当我删除代码行以输出它们已被选中时,我会得到一个无限循环。有人看到我的问题了吗?
public Form1()
{
InitializeComponent();
}
//these booleans are set to true if the group has already been selected
bool A = false;
bool B = false;
bool C = false;
bool D = false;
bool E = false;
bool F = false;
bool G = false;
bool H = false;
private void selectButton_Click(object sender, EventArgs e)
{
string selection = "error";
while (selection == "error")
{
int group = RandomNumber();
if (group == 1 && A == false)
{
selection = "A";
A = true;
}
else if (group == 2 && B == false)
{
selection = "B";
B = true;
}
else if (group == 3 && C == false)
{
selection = "C";
C = true;
}
else if (group == 4 && D == false)
{
selection = "D";
D = true;
}
else if (group == 5 && E == false)
{
selection = "E";
E = true;
}
else if (group == 6 && F == false)
{
selection = "F";
F = true;
}
else if (group == 7 && G == false)
{
selection = "G";
G = true;
}
else if (group == 8 && H == false)
{
selection = "H";
H = true;
}
else if (A == true && B == true && C == true && D == true && E == true && F == true && G == true && H == true)
{
selection = "all have been selected";
}
//else
// {
// selection = "oops";
// };
};
outputRichTextBox.Text = selection;
}
private int RandomNumber()
{
Random rnd = new Random();
int num = rnd.Next(1, 9);
return num;
}
}
}
您不应该为每次使用重新创建Random
。将其改为实例或静态字段。
private Random rnd = new Random();
private int RandomNumber()
{
int num = rnd.Next(1, 9);
return num;
}
除此之外,您可能最好使用数组来存储您的值。这只会让你的代码更可读。
只是为了让这个更容易理解,这就是我要做的。
public Form1()
{
var poss = (new [] { "A", "B", "C", "D", "E", "F", "G", "H" })
.OrderBy(c => RandomNumber())
.GetEnumerator();
}
private IEnumerator<string> selections;
private Random rnd = new Random();
private void selectButton_Click(object sender, EventArgs e)
{
if (selections.MoveNext())
outputRichTextBox.Text = selections.Current;
else
outputRichTextBox.Text = "all have been selected";
}
private int RandomNumber()
{
int num = rnd.Next();
return num;
}
这里的想法是在开始时创建并随机化列表(通过随机数排序),然后在每次单击时循环,直到列表为空。
.NET中的第一个Random
不会生成真正的随机数,并且根据传递给它的构造函数的种子,它可以一次又一次地生成精确的序列。这不是bug。它的设计是为了针对伪随机数据系列测试您的应用程序,您必须使用RNGCryptoServiceProvider
来生成真实的随机数:
public class SampleRandomNumber
{
static readonly object Lock = new object();
static readonly RNGCryptoServiceProvider Random = new RNGCryptoServiceProvider();
public static int NextInt32()
{
lock (Lock)
{
var bytes = new byte[4];
Random.GetBytes(bytes);
return BitConverter.ToInt32(bytes, 0);
}
}
}
NextInt32
给了我们一个int
(包括偶数负数;当然你可以使用它的abs)。