如何生成两个随机数,X和Y,并确保它们永远不会重复?

时间:2014-08-08 12:16:24

标签: c# random

好的,我正在WinForms中编写一个Minesweeper应用程序。这是我的第一个C#应用程序,因此它是一个巨大的学习过程。我想随机生成两个数字,放入两个独立的数组,mineX& mineY。这两个阵列是将所有地雷放置在电路板上的坐标。

这是问题,我想确保当它随机生成这些数字时,X,Y将永远不会相同。我已完成研究,知道如何生成单个数字并使每个数字都独一无二。我的问题是我希望两个随机数的组合是唯一的。

这是我的placeMines方法的代码。

    private void placeMines()
    {
        Random rnd = new Random();

        for (int i = 0; i < MINE_COUNT; i++)
        {               
                bombX[i] = rnd.Next(0, BOARD_X);
                bombY[i] = rnd.Next(0, BOARD_Y)'
        }
    }

这似乎是一个需要解决的简单问题,但我无法解决这个问题。

2 个答案:

答案 0 :(得分:7)

  1. 创建可能的矿位列表。
  2. 从列表中选择一个随机项,删除该项。
  3. 重复2直到有足够的地雷。
  4. 示例代码:

    const int BOARD_X = 10;
    const int BOARD_Y = 6;
    const int MINE_COUNT = 30;
    
    List<int> positions = Enumerable.Range(0, BOARD_X * BOARD_Y).ToList();
    var rnd = new Random();
    for (int i = 0; i < MINE_COUNT; i++) {
        int index = rnd.Next(positions.Count);
        int pos = positions[index];
        positions.RemoveAt(index);
        int x = pos % BOARD_X, y = pos / BOARD_X;
        Console.WriteLine("({0}, {1})", x, y);
    }
    

    注意:如果位置数量很大,您可以使用位向量优化空间算法。我会留下这个练习。

答案 1 :(得分:3)

在数组中生成所有位置(让它成为带有两个int字段x,y的struct)并随机播放该数组。

Random _rand = new Random();
Position[] allPositions = GenerateAllPositions();

for (int i=allPositions.Length-1; i>=1; i--)
{
     int j = _rand.Next(0, i+1);
     // now swap
     Position tempPosition = allPositions[i];
     allPositions[i] = allPositions[j];
     allPositions[j] = tempPosition;
}

现在你可以拥有temp int变量lastQueriedPositionIndex = 0,当你选择任何位置时,将它增加1。如果lastQueriedPositionIndex == allPositions.Length生成lastQueriedPositionIndex=0并调用此&#34;交换&#34;例行公事。这是O(n)最坏情况的解决方案,而不是Athari提出的O(n^2)解决方案 - 但是在小板尺寸中,您不会看到任何差异。