【问题标题】:How to randomly distribute an attribute over a certain number of objects?如何将属性随机分布在一定数量的对象上?
【发布时间】:2021-12-30 00:52:35
【问题描述】:

我想知道在一定数量的对象上分配某些东西的最佳方式是什么。我正在尝试创建一个扫雷游戏,其中有一定数量的瓷砖和一定数量的地雷,但我不确定在一定范围内随机分配数字的最佳方法。

具体来说,如果我有一个包含 400 个对象的向量,那么随机分配一个布尔属性以使这 400 个对象中有 30 个为真而其余为假的最佳方法是什么?

struct Tile {
  bool mine;
  // ...
};

std::vector<Tile> v(400);

我在想可能类似于概率系统的东西,我的一组图块绝对必须具有该属性,我可以创建所有对象的编号向量并滚动随机数,然后从向量中删除这些对象,直到设置了地雷的数量。

【问题讨论】:

  • 您可以创建一个包含 400 个布尔值的数组,将前 30 个设置为 true,其余设置为 false,对数组进行打乱,然后按顺序使用打乱后的值。
  • 我添加了一些代码以使您的要求更清楚。如果您认为这改变了意图,或者您可以改进它,请随时对其进行编辑。

标签: c++ object random boolean distribution


【解决方案1】:

使用您想要的每个值的设定数量生成数组,然后将它们打乱。

https://en.cppreference.com/w/cpp/algorithm/random_shuffle

【讨论】:

    【解决方案2】:
    int N = 400;
    int numMines = 30;
    vector<bool> hasMine;
    for(int i = 0; i < N; i++){
       if(i < numMines) hasMine.push_back(true);
       else hasMine.push_back(false);
    }  
    random_shuffle(hasMine.begin(), hasMine.end());
    

    如果您太在意 shuffle 的准确性,您可以使用带有单独随机生成器的 shuffle 方法(阅读更多关于它的信息here)。但这对于一个简单的游戏来说应该已经足够了。

    【讨论】:

    • random_shuffle 已在 C++17 中删除,因此您现在必须使用 shuffle
    【解决方案3】:

    您在这里尝试做的是转换向量的随机采样子集。 range-v3 库具有可用于此目的的 views::sample

    for (auto & tile : v | ranges::views::sample(30))
        tile.mine = true;  
    

    这是demo

    此解决方案的优点是不需要制作向量的副本,也不需要任何额外的内存。此外,这无需在矢量中的任何对象周围移动即可工作。

    这个视图将被添加到 C++23 中,尽管它只是 Tier 3 优先级。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 2020-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-10
      相关资源
      最近更新 更多