我正在制作一个简单的游戏来提高我的C#技能。我读到了Random()类以及它如何从datetime生成种子,并找到了一些如何从一个实例获取伪随机生成器的结果。
玩家等级:
Random dice = new Random();
public int RollDice()
{
int dice1 = dice.Next(1, 7);
int dice2 = dice.Next(1, 7);
int sum = dice1 + dice2;
Console.WriteLine("D1: " + dice1 + " D2: " + dice2 + " SUM: " + sum);
return sum;
}
主:
//infiniteloop{
player1.RollDice();
Console.ReadKey();
player2.RollDice();
}
输出后,我不再等待多长时间按键并重新调用player2.DiceRoll()它仍会滚动相同的数字。如果我只有一个玩家,那就完美了。我怎样才能改善这个?
答案 0 :(得分:3)
伪随机数生成器在创建时将播种一次。在播种后,他们按照固定的数字循环(根据他们的种子)生成下一个数字。
使用不带参数的Random
构造函数时,当前时间用作种子。在实际生成数字的所有后续调用中,不再使用当前时间,因此在这些调用之间等待的时间并不重要。
您看到的问题是每个玩家都有自己的Random
对象,并且这些对象同时创建。请参阅以下示例:
// these are created pretty much at the same time
var r1 = new Random();
var r2 = new Random();
Console.WriteLine(r1.Next(1, 7));
Console.WriteLine(r2.Next(1, 7));
Console.WriteLine(r1.Next(1, 7));
Console.WriteLine(r2.Next(1, 7));
Console.WriteLine(r1.Next(1, 7));
Console.WriteLine(r2.Next(1, 7));
Console.WriteLine(r1.Next(1, 7));
Console.WriteLine(r2.Next(1, 7));
如果运行该代码,您将看到两个随机生成器中的数字始终相同。这是因为它们是同时播种的。
为了解决这个问题,您必须以不同方式为这些生成器设定种子,或者确保在之后实际创建一个
。然而,更好的解决方案是引入一个负责创建随机掷骰的对象。然后,您的Player
对象将使用相同的die生成器,该生成器只有一个随机数生成器。所以随机数将来自同一个发生器,防止它们相同。像这样:
public class DieGenerator
{
private Random rand = new Random();
public int Roll()
{
return rand.Next(1, 7);
}
}
然后您将创建一个此对象并将其传递给Player
,以便他们可以使用它来掷骰子而不是依赖于他们自己的随机数生成器。
答案 1 :(得分:0)
您的随机生成器dice
不会在调用player2.RollDice()
的位置创建。它是在创建player2
实例时创建的,我假设它是在player1
同时创建的,这就是为什么你看到相同的卷; dice
都有相同的种子。
要解决此问题,一种方法是创建一个唯一的随机生成器并将其注入Player
个实例。
例如,注入via构造函数将如下所示:
public class Player
{
private readonly Random dice;
public Player(Random dice)
{
Debug.Assert(dice != null);
this.dice = dice;
}
public int RollDice() => dice.Next(1, 7);
}
你可以这样使用它:
var dice = new Random();
var player1 = new Player(dice);
var player2 = new Player(dice);
答案 2 :(得分:0)
正如其他答案所指出的那样,你的问题是你正在使用两个(同种子)随机数发生器,每个发生器会生成相同的序列。有几种方法可以解决这个问题:
选项一:在播放器构造函数
中对每个Random进行不同的播种Player(int seed) {
this.dice = new Random(seed);
}
然后在你的main.cs
var player1 = new Player(1);
var player2 = new Player(2);
选项2:创建一个Random
并将其传递给您的构造函数(或调用RollDice
)
@sdgfsdh
详细介绍了此方法 选项3:Random
Player
静态
Random dice = new Random();
更改为
static Random dice = new Random();
这意味着,无论您创建了多少Players
,它们都将使用相同的Random
,从而避免原始问题。
答案 3 :(得分:0)
对于两个玩家来说,很可能同时构建dice
,这给了他们两个相同的种子。我建议为两位玩家制作一个骰子:
// Removed "Random dice = new Random(); "
public int RollDice(Random dice)
{
int dice1 = dice.Next(1, 7);
int dice2 = dice.Next(1, 7);
int sum = dice1 + dice2;
Console.WriteLine("D1: " + dice1 + " D2: " + dice2 + " SUM: " + sum);
return sum;
}
// Main
var dice = new Random();
while (true)
{
player1.RollDice(dice);
Console.ReadKey();
player2.RollDice(dice);
}