C# 生成从1到6的随机数,并在最后一个数处停止

C# 生成从1到6的随机数,并在最后一个数处停止,c#,random,numbers,C#,Random,Numbers,我有以下代码: int GetRandNumber() { Random r = new Random(); return r.Next() % 6 + 1; } 我正在开发一个windows应用商店应用程序。我有一个文本框,其中生成了一个从1到6的数字。对于每个数字,我都做了一个特定的事件。我需要确保每个数字只生成一次,这样事件就不会重复。看起来您只需要洗牌数字。我建议创建一个从1到6的数字数组,然后将数组洗牌。您可以看到一些关于如何洗牌数组/列表的

我有以下代码:

int GetRandNumber()
{
    Random r = new Random();
    return r.Next() % 6 + 1;             
}

我正在开发一个windows应用商店应用程序。我有一个文本框,其中生成了一个从1到6的数字。对于每个数字,我都做了一个特定的事件。我需要确保每个数字只生成一次,这样事件就不会重复。

看起来您只需要洗牌数字。我建议创建一个从1到6的数字数组,然后将数组洗牌。您可以看到一些关于如何洗牌数组/列表的代码

看起来你只需要洗牌就可以了。我建议创建一个从1到6的数字数组,然后将数组洗牌。您可以看到一些关于如何洗牌数组/列表的代码

首先,您需要小心使用此实现,如果您在非常接近的位置多次调用GetRandomNumber,它将给出相同的结果。更好的功能是

int GetRandNumber(Random r)
{
    return r.Next(1, 7); //This does the same as "r.Next() % 6 + 1" but removes bias.
}

//used like
Random rand = new Random();
foreach(var foo in bar)
{
    //The same instance of rand is used for each call instead of a new one each time.
    foo.SomeProp = GetRandNumber(rand);
 }
然而,这与您需要做的完全不同,您不应该在1到6之间生成随机数。您需要做的是创建一个1到6的列表,然后洗牌列表,而不是使用随机数。您可能会在洗牌过程中使用它们,但这是一个实现细节

List<int> numbers = new List<int>();
for(int i = 1; i <= 6; i++)
{
    numbers.Add(i);
}

MyShuffleListFunction(numbers);

这个网站上有很多关于如何实现洗牌功能的内容。

首先,你需要小心这个实现,如果你多次调用GetRandomNumber,非常接近它,它会给你同样的结果。更好的功能是

int GetRandNumber(Random r)
{
    return r.Next(1, 7); //This does the same as "r.Next() % 6 + 1" but removes bias.
}

//used like
Random rand = new Random();
foreach(var foo in bar)
{
    //The same instance of rand is used for each call instead of a new one each time.
    foo.SomeProp = GetRandNumber(rand);
 }
然而,这与您需要做的完全不同,您不应该在1到6之间生成随机数。您需要做的是创建一个1到6的列表,然后洗牌列表,而不是使用随机数。您可能会在洗牌过程中使用它们,但这是一个实现细节

List<int> numbers = new List<int>();
for(int i = 1; i <= 6; i++)
{
    numbers.Add(i);
}

MyShuffleListFunction(numbers);

本网站上有关于如何制作洗牌功能的内容。

也许我错了,但据我所知,您希望这样的输出:

344213266125

要实现这一点,您应该跟踪哪些数字已经生成,如果所有数字都已滚动至少一次,请停止。 让我们将布尔数组初始化为6个假值,在每次滚动后生成随机数后,将数组的对应元素设置为真。检查数组中是否有任何假值,如果没有,则再次滚动

也可以考虑根据其他答案生成数字,因为它们当然是正确的:这不是一个理想的方式。 更新

好的,根据你问题的更新,我也更新了我的伪代码,或者我应该称之为: 如上所述,跟踪已滚动的数字。生成新编号时,请检查是否已生成该编号。如果以前滚动过,则再次滚动,直到滚动新的阵列:然后相应地更新阵列。另外,确保在开始滚动之前,检查是否有有效的数字或所有数字都已滚动


但现在对我来说,你真正想要的只是一个洗牌,这已经在其他答案中提出了。

也许我错了,但据我所知,你想要这样的东西作为输出:

344213266125

要实现这一点,您应该跟踪哪些数字已经生成,如果所有数字都已滚动至少一次,请停止。 让我们将布尔数组初始化为6个假值,在每次滚动后生成随机数后,将数组的对应元素设置为真。检查数组中是否有任何假值,如果没有,则再次滚动

也可以考虑根据其他答案生成数字,因为它们当然是正确的:这不是一个理想的方式。 更新

好的,根据你问题的更新,我也更新了我的伪代码,或者我应该称之为: 如上所述,跟踪已滚动的数字。生成新编号时,请检查是否已生成该编号。如果以前滚动过,则再次滚动,直到滚动新的阵列:然后相应地更新阵列。另外,确保在开始滚动之前,检查是否有有效的数字或所有数字都已滚动


但现在对我来说,你真正想要的似乎只是一个洗牌,这已经在其他答案中提出了。

也许这对你有用。这种方法是将随机结果记录在一个列表中,如果结果已经存在于列表中,则跳过输出

class Program
{
    static int tmp;

    static void Main(string[] args)
    {
        List<int> alreadyFired = new List<int>();                   

        while (alreadyFired.Count != 6)
        {

            Random rng = new Random();

            int diceresult = rng.Next(1,7);

            foreach (var item in alreadyFired)
            {
                if (item == diceresult)
                {
                    tmp = item;
                }
            }

            if (!(tmp == diceresult))
            {
                alreadyFired.Add(diceresult);                 
                Console.WriteLine(diceresult);
            }
        }

        Console.WriteLine("no events left");
        Console.ReadKey();
    }
}

也许这对你有用。这种方法是将随机结果记录在一个列表中,如果结果已经存在于列表中,则跳过输出

class Program
{
    static int tmp;

    static void Main(string[] args)
    {
        List<int> alreadyFired = new List<int>();                   

        while (alreadyFired.Count != 6)
        {

            Random rng = new Random();

            int diceresult = rng.Next(1,7);

            foreach (var item in alreadyFired)
            {
                if (item == diceresult)
                {
                    tmp = item;
                }
            }

            if (!(tmp == diceresult))
            {
                alreadyFired.Add(diceresult);                 
                Console.WriteLine(diceresult);
            }
        }

        Console.WriteLine("no events left");
        Console.ReadKey();
    }
}

在这种情况下有些吹毛求疵,但在某些情况下,像这样使用模%并不能得到公平的分布。例如,见;使用不同的Next重载应该可以在您需要的范围内获得一个好的、公平的数字。在这种情况下有些挑剔,但在某些情况下,使用模%这样的方法无法获得公平的分布。例如,见;使用
不同的Next过载应该会让你在你需要的范围内得到一个好的、公平的数字。很抱歉打扰你,我仍然没有让它工作。看看我对这个问题所做的修改。现在更清楚了。@user3473574如果您已对问题进行了重大更改,我将回滚更改并提出一个新问题。很抱歉打扰您,我仍然没有使其生效。看看我对这个问题所做的修改。现在更清楚了。@user3473574如果您已对问题进行了重大更改,我将回滚更改并提出一个新问题。很抱歉打扰您,我仍然没有使其生效。看看我对这个问题所做的修改。现在更清楚了。在这种情况下,根据我在回答中给出的建议,你应该在每次掷骰后更新数组:查看你掷骰的数字是否已经掷过一次,如果已经掷过,然后再次掷骰,如果没有,那么在数组中设置标志并返回该数字。像这样?如果生成.Text.ContainsGetRandNumber.ToString{numbers.Visibility=Windows.UI.Xaml.Visibility.Collapsed;}numbers.Text=GetRandNumber.ToString;不,这似乎不对。但是您应该将现有代码添加到问题中,或者创建一个新代码,因为问题似乎与原始问题不同。int GetRandNumber{Random r=new Random;return r.Next1,7;}private void Button\u Click\u 1object sender,RoutedEventArgs e{if generated.Text.ContainsGetRandNumber.ToString{numbers.Visibility=Windows.UI.Xaml.Visibility.Collapsed;}numbers.Text=GetRandNumber.ToString;}私有无效编号\u TextChangedobject发送方,TextChangedEventArgs e{generated.Text=numbers.Text+generated.Text;}很抱歉打扰您,我仍然没有让它工作。看看我对问题所做的更改。现在更清楚了。在这种情况下,根据我在回答中给出的建议,您应该在每次滚动后更新数组:查看您滚动的数字是否已滚动一次,如果是,则再次滚动,如果不是,则在数组a中设置标志nd返回该数字。是否这样?如果生成.Text.ContainsGetRandNumber.ToString{numbers.Visibility=Windows.UI.Xaml.Visibility.Collapsed;}numbers.Text=GetRandNumber.ToString;不,这似乎不对。但您应该将现有代码添加到问题中,或者创建一个新代码,因为问题似乎与原始问题不同。int GetRandNumber{Random r=new Random;返回r.Next1,7;}私有无效按钮\u单击\u 1对象发送方,路由EventTargets e{如果生成。Text.ContainsGetRandNumber.ToString{numbers.Visibility=Windows.UI.Xaml.Visibility.Collapsed;}numbers.Text=GetRandNumber.ToString;}私有无效数字\u TextChangedobject发送者,TextChangedEventArgs e{generated.Text=numbers.Text+generated.Text;}很抱歉打扰你,我仍然没有让它工作。看看我对这个问题所做的更改。现在更清楚了。基本上你需要1到6,但随机绑定到某个事件。我的建议是将1到6保留在一个数组中,洗牌数组,这样当你读取时,它是随机的,然后读取数组并绑定你的事件。你没有重复事件,数组的洗牌应该会给你随机的数字。很抱歉打扰你,我仍然没有让它工作。看看我对问题所做的更改。现在更清楚了。基本上你需要1到6,但随机绑定到某个事件。我的建议是在数组中保留1到6,洗牌数组以便在你它是随机的,然后读取数组并绑定你的事件。你不会有重复的事件,数组的无序排列会给你随机的数字。