我正在开发一个尺寸为c#的扫雷游戏(8 x 8)。难度级别会增加/减少网格上的地雷数量。
我使用随机类(使用min,max set;)来生成随机单元格数。我面临的问题是,随机对象不断重复相同的数字。我试图通过维护本地列表来解决此问题我存储生成的唯一随机数。下次我调用Next(),我会检查它是否在本地列表,看看它是否已经存在。如果数字已经存在,我将继续调用Next()直到我得到一个新的数字,它是唯一的,但不在列表中。但这本身并不是一个好的解决方案,因为有时需要花费大量的时间来生成新的列表。
对此有任何建议
答案 0 :(得分:2)
即使您使用相同的随机数生成器,也可以重复值。
避免这种情况的一种方法是生成一个可能的值列表,并使用生成的随机数来访问此列表中的值(使用as indice)并减少此列表,因为您会找到放置地雷的位置。 / p>
对于8 X 8示例,您有64个可能的位置
List<int> possibleValues = new List<int>();
for (int i = 0; i < 64; i++)
{
possibleValues[i] = i;
}
List<int> result = new List<int>();
Random r = new Random();
int numberOfMines = 50; //say you want to put 50 mines there
for (int i = 0; i < numberOfMines; i++)
{
int indice = r.Next(possibleValues.Count);
int value = possibleValues[indice];
possibleValues.Remove(value);
result.Add(value);
}
答案 1 :(得分:1)
看起来你想要一个基于固定数量的单元格(8,8)的 shuffle ,例如一个Fisher-Yates shuffle。这将保证任何坐标只出现一次(而不是重复使用Random.Next(),您可以多次绘制相同的数字),并且坐标的出现顺序是随机的。
初始化一个包含单元格所有坐标的数组,对数组进行洗牌并维护下一个“随机”单元格的索引,返回索引偏移处的单元格并增加索引。
答案 2 :(得分:1)
不是挑选地雷所在的位置,而是循环通过插槽并计算那里应该有地雷的可能性。对此的实现变得非常简单,因为您只需要一个循环:
bool[] mines = new bool[64];
int cnt = 12;
Random rnd = new Random();
for (int i = 0; i < mines.Length; i++) {
if (rnd.Next(mines.Length - i) < cnt) {
mines[i] = true;
cnt--;
}
}
(改进的余地:如果您不需要初始化所有插槽,则可以在cnt
达到零时退出循环。)
答案 3 :(得分:1)
首先计算地雷数和空地。
Random rand=new Random();
int mines=GetMinesFromDifficulty(...);
int empty=TotalFields-mines;
然后为每个字段:
for(int y=0;y<height;y++)
for(int x=0;y<height;y++)
{
if(random.Next(mines+empty) < mines))
{
field[x,y]=Mine;
mines--;
}
else
{
field[x,y]=Empty;
empty--;
}
}
答案 4 :(得分:0)
如果您的网格是8x8,并且您想要随机选择一个未使用的单元格而不是拉随机数,直到您找到一个未使用的单元格,然后跟踪未使用的单元格的数量。说使用了8,留下55未使用。然后生成0到54之间的随机数。然后你必须计算,并找到第n个空单元格。
答案 5 :(得分:0)
以更线性的方式思考问题可能更容易。而不是说2D数组... Squares [8] [8]将其视为单维数组Squares [64]。
此时,您可以为随机排雷生成0-63之间的数字。如果说值为10,您可以存储以便稍后抵消后续数字。你现在可以从0-62缩小你的范围,如果你拿出值16你想为你已经在它下面拉出的每个值加上+1(所以实际上在这种情况下使用17,但是方10已经从我们的集合中排除。)
答案 6 :(得分:-1)
在没有看到任何代码的情况下,很难得到事情的要点,但从我可以告诉你的内容有以下几点:
对于游戏的网格布局的多维数组[8] [8],你现在正试图随机放置地雷?
你需要保留一个Random实例来生成数字,否则你会反复得到相同的数字。像这样的东西
private readonly Random randomNumber = new Random();
for(int i = 0; i < 10; i++)
{
Console.WriteLine(this.randomNumber.Next(1, 10));
}
这将产生10个随机数,每个数字不同。