繁体   English   中英

我的验证(检查数字是否在数组中,然后将其更改为不同)有什么问题?

[英]What is wrong with my validation for checking that a number is in an array and then changing it so it is different?

我正在做一个宾果游戏,想要检查是否已经呼叫过一个号码,因此是否生成了一个尚未被呼叫的新号码。 bool []数字; 随机r;

    private void button1_Click(object sender, EventArgs e)
    {
        this.Numbers = new bool[90];
        this.r = new Random();
        int attempt = this.r.Next(0, 90);

        while (this.Numbers[attempt] == true)
        {
            attempt = this.r.Next(0, 90);
            this.Numbers[attempt] = true;
        }

        textBox1.Text += (attempt + 1).ToString() + " ";
        textcurrent.Text += textBox1.Text;
        textBox1.Clear();

    }

这是一个无限循环:

    while (this.Numbers[attempt] == true)
    {
        attempt = this.r.Next(0, 90);
        this.Numbers[attempt] = true;
    }

您已经将this.Numbers[attempt]设置为true然后再检查是否继续执行while循环

该代码段将导致无限循环:

 while (this.Numbers[attempt] == true)
 {
      attempt = this.r.Next(0, 90);
      this.Numbers[attempt] = true;
 }

请注意,您正在将this.Numbers[attempt]设置为true,然后检查它是否为true ,因此循环永远不会结束。

我会采取另一种方法:

var notUsed = this.Numbers.Where(used => !used)
                 .Select((val, idx) =>
                      new 
                      {
                          Idx = idx,
                          Val = val
                      }).ToList();

if (!notUsed.Any())
{
    //case when all numbers used
}
else
{
    attempt = notUsed[this.r.Next(0, notUsed.Count)].Idx;
    this.Numbers[attempt] = true;
}

编辑:注释中的OP表示分配是在循环外完成的:

 while (this.Numbers[attempt] == true)
 {
      attempt = this.r.Next(0, 90);
 }

 this.Numbers[attempt] = true;

好吧,在这种方法中,当数组中的所有值都设置为true时,也会发生infite循环。 此外,您可以attempt将设置为true的元素生成(当有许多元素设置为true时,理论上获得false元素的机会很小)。

我会采取另一种方法。 创建一个宾果号码列表,然后将其洗牌。 然后,只需阅读从顶部开始的每个数字:

void Main()
{
    //Create a list of BINGO numbers and the shuffle it randomly.
    string letters = "BINGO";
    var bingoNumbers = Enumerable.Range(1, 75)
                                 .Select(n => string.Format("{0}{1}", letters[(int)Math.Ceiling(n / 15.0) - 1], n))
                                 .OrderBy(o => Guid.NewGuid())
                                 .ToList();

    foreach (var number in bingoNumbers)
    {
        Console.WriteLine(number);        
    }                            
}

Math.Ceiling(...)位只是使用Linq创建宾果数字数组的一种技巧。 如果您不想使用Linq,也可以使用两个嵌套的for循环。

通过使用OrderBy(o => Guid.NewGuid()) ,可以对列表进行OrderBy(o => Guid.NewGuid()) 这可能不是最好的改组方法。 其他人,例如Fisher-Yates可能更好。 如果要使用其他改组方法,则可以省略OrderBy行并使用所需的任何算法进行改组。

顺便说一句,我注意到您使用的宾果数为90,但在传统游戏中只有75。如果您未使用传统的BINGO数,则可以在代码中替换BINGO字母和也是范围值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM