随机的没有';t拉动相同的值两次,除非拉动范围内的所有值(C#)

本文关键字:两次 范围内 随机 | 更新日期: 2023-09-27 18:25:26

我有一个数组,其中的值应该随机显示,但我不希望一个值显示两次,除非已经显示了所述数组中的所有值。

这是我迄今为止的代码:

//Array of strings that will be displayed
static string[] array1 = { "value1", "value2", "value3", "value4", "value5" };
//Common int rndIndex
int rndIndex;
//Method that runs the random number generator (will be used within other methods)
//There will be one method that will call this method and display the value before the loop
private void runRnd(ref int rndIndex)
{
    Random rnd = new Random();
    rndIndex = rnd.Next(4);
    textBlock.Text = array1[rndIndex];
}
private void textBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Space)
    {
        e.Handled = true;
        //This will check whether user input matches what is displayed, then will call runRnd method again
        bool checkEquals = textBox.Text.Equals(array1[rndIndex], StringComparison.OrdinalIgnoreCase);
        if (checkEquals == true)
        {
            runRnd(ref rndIndex);
        }
    }
}

有人能帮我吗?

随机的没有';t拉动相同的值两次,除非拉动范围内的所有值(C#)

任何时候你不想让随机数重复,你都需要洗牌,因为随机值可以重复。

我不希望一个值显示两次,除非所有值。。。已显示

第二次以相同的顺序出现的第二组/迭代似乎没有太大的价值。随机通常意味着不可预测,因此这将重新洗牌:

Random rng = new Random();
Stack<String> shoe = new Stack<string>();
private void button1_Click(...
{
    if (shoe.Count == 0)
    {
        // refill when empty
        shoe = new Stack<string>(GetNewValues());
    }
    // display next, remove from "deck"
    lb1.Items.Add(shoe.Pop());
}
private string[] GetNewValues()
{
    string[] values = { "value1", "value2", "value3", 
                        "value4", "value5" };
    //simple, usually-good-enough randomizer
    return values.OrderBy(r => rng.Next()).ToArray();
}

使用Stack可以避免为数组或列表保留索引变量。获取下一个值(Pop)会自动使用它们。当它为空时,是时候获取更多值了。或者,使用Fisher Yates洗牌:

private void ShuffleArray(string[] items)
{
    string tmp;
    int j;
    for (int i = items.Length - 1; i >= 0; i--)
    {
        j = rng.Next(0, i + 1);
        tmp = items[j];
        items[j] = items[i];
        items[i] = tmp;
    }
}

为此,GetNewValues()将是:

...
ShuffleArray(values);
return values;

如果确实想要在第二个集合中有相同的顺序,可以将搅乱的数组附加到其自身:

// shuffle or OrderBy, either will work
values = values.OrderBy(r => rng.Next()).ToArray();
// append second set to first
return values.Concat(values).ToArray();

创建数组的副本?

static string[] array1 = { "value1", "value2", "value3", "value4", "value5" };
List<String> list1 = array1.ToList();
int rndIndex;
//Method that runs the random number generator (will be used within other methods)
//There will be one method that will call this method and display the value before the loop
private void runRnd(ref int rndIndex)
{
    Random rnd = new Random();
    rndIndex = rnd.Next(list1.Count-1);
    textBlock.Text = list1[rndIndex];
    list1.RemoveAt(rndIndex);
    if(list1.Count == 0)
    { 
      list1 = array1.ToList();
    }
}

将创建数组的副本,删除它使用的每个值,直到它为空,然后重复。

(未测试)