我试图在wpf的简单Yatsy游戏中拼凑,但遇到了一个奇怪的问题。基本上,当单击按钮在UI中重新滚动时,将调用UpdateLogic()方法。该方法循环遍历骰子列表,并应随机和单独更新每个值和图像链接。
这是一个奇怪的部分。如果我在调试模式下像往常一样运行它而没有breakboint或释放的.exe文件,所有值和图像链接总是得到相同的值。如果我在带有断点的调试模式下运行并逐步执行新值请求,它将按预期工作。
有人有任何建议吗?
namespace Yatzy
{
public partial class MainWindow : Window
{
private DiceManager dm;
private List<BitmapImage> sidesToDisplay = new List<BitmapImage>();
public MainWindow()
{
InitializeComponent();
CreateObjects();
for (int i = 0; i < 6; i++)
{
var side = new BitmapImage();
sidesToDisplay.Add(side);
sidesToDisplay[i].BeginInit();
sidesToDisplay[i].UriSource = new Uri(@"Images/Side" + (i+1) +".png", UriKind.Relative);
sidesToDisplay[i].EndInit();
}
}
private void CreateObjects()
{
dm = new DiceManager();
dm.GenerateDices();
}
private void button_Click(object sender, RoutedEventArgs e)
{
UpdateLogic();
}
private void UpdateLogic()
{
foreach (Dice dice in dm.AllDices)
{
dice.SetNewValue(sidesToDisplay);
}
Dice1.Source = dm.AllDices[0].sideToDisplay;
Dice2.Source = dm.AllDices[1].sideToDisplay;
Dice3.Source = dm.AllDices[2].sideToDisplay;
Dice4.Source = dm.AllDices[3].sideToDisplay;
Dice5.Source = dm.AllDices[4].sideToDisplay;
}
}
public class DiceManager
{
public List<Dice> AllDices { get; set; }
public DiceManager()
{
AllDices = new List<Dice>();
}
public void GenerateDices()
{
for (int i = 0; i < 5; i++)
{
AllDices.Add(new Dice());
}
}
}
public class Dice
{
public int Value { get; set; }
public BitmapImage sideToDisplay { get; set; }
public void SetNewValue(List<BitmapImage> imageList)
{
Value = new Random().Next(1, 7);
sideToDisplay = imageList[Value - 1];
}
}
}
答案 0 :(得分:4)
使用从系统时钟获取的种子值初始化Random实例。在紧密循环中创建新的Random实例时,这会产生问题。这些实例使用相同的时钟值生成,因此它们返回相同的数字序列。
诀窍是为所有骰子创建一次Random实例,并在此实例上调用Next。
public class Dice
{
public int Value { get; set; }
public BitmapImage sideToDisplay { get; set; }
public void SetNewValue(List<BitmapImage> imageList, int diceValue)
{
Value = diceValue;
sideToDisplay = imageList[Value - 1];
}
}
and in the UpdateLogic
private void UpdateLogic()
{
Random rnd = new Random();
foreach (Dice dice in dm.AllDices)
{
dice.SetNewValue(sidesToDisplay, rnd.Next(1,7));
}
....
}