所以我犯了一个错误,而不是将项目创建为C#控制台应用程序 创建了.NET Core。这是一个简单的游戏(Conway的生活游戏),实现的功能之一是创建一个随机板(2D阵列),对其进行转换,然后将其打印到控制台上。
在.NET Core中,随机生成电路板效果很好,但是,如果我尝试将包括Program.cs的CS文件粘贴到.NET Framework或C#应用程序中,则除了上述随机生成之外,其他所有功能似乎都可以正常工作。当我调试时,它似乎也可以正常工作,但是从BoardGenerator.cs中的GenerateRandom返回随机生成的板时,它返回的数组是所有真值或所有假值。
我没有更改任何代码行,我试图删除所有构建文件并重新构建,但没有任何效果,这真让我发疯。
Program.cs
class Program
{
static void Main()
{
var game = new Game();
Console.WriteLine("CONWAY'S GAME OF LIFE");
Console.WriteLine();
var folder = @"D:\_programming projects\game-of-life\GameOfLife\patterns\";
var files = Directory.GetFiles(folder, "*.txt");
for (var i = 0; i < files.Length; i++)
{
Console.WriteLine(i + 1 + ": " + Path.GetFileNameWithoutExtension(files[i]));
}
Console.WriteLine(files.Length + 1 + ": Random");
Console.Write("Enter number to load board: ");
var input = Console.ReadLine();
int.TryParse(input, out var option);
option--;
try
{
if (option == files.Length)
game.SetBoard(new BoardGenerator().GenerateRandom(Constants.BoardRows, Constants.BoardColumns));
else
game.SetBoard(new BoardGenerator().GenerateFromFile(
files[option],
Constants.BoardRows,
Constants.BoardColumns));
}
catch (Exception)
{
Console.WriteLine("Error");
}
game.PrintBoard();
while (true)
{
Thread.Sleep(200);
Console.Clear();
game.MutateBoard();
game.PrintBoard();
}
}
}
BoardGenerator.cs
public class BoardGenerator
{
private readonly bool[] _values = { true, false };
private bool[,] _board;
public bool[,] GenerateRandom(int noRows, int noColumns)
{
_board = new bool[noRows, noColumns];
BoardProcessor.ProcessValue(_board, tile => _values[new Random().Next(0, _values.Length)]);
return _board;
}
[...]
}
BoardProcessor.cs
public static class BoardProcessor
{
public static void ProcessValue(bool[,] board, Func<bool, bool> func)
{
for (var i = 0; i < board.GetLength(0); i++)
for (var j = 0; j < board.GetLength(1); j++)
board[i, j] = func(board[i, j]);
}
}
同样,此代码在.NET Core中有效。有什么问题吗?
答案 0 :(得分:2)
.NET Framework和.NET Core具有Random
默认构造函数的不同实现。两者都尝试生成一些默认种子来启动伪随机序列,但是它们生成种子的方式不同。特别是.NET Core实现使用内部全局随机对象生成随机种子,该种子可为new Random()
的所有顺序调用保证使用不同的种子。但是,框架实现使用Environment.TickCount
作为种子,这带来了这样的风险:被足够快地调用的new Random()
的顺序调用将获得相同的种子(因为在实例初始化期间未更新滴答计数) ),对于在该期间使用默认构造函数初始化的Random
的所有实例,int意味着相同的伪随机序列。这就是您的情况中最有可能发生的情况。修复很简单-建议使用Random
调用之前初始化的BoardProcessor.ProcessValue
单个实例。