【发布时间】:2019-05-21 16:45:49
【问题描述】:
首先,大家好!这是我在这里的第一个问题,所以我希望我没有搞砸。在这里写之前我google了很多。我是编码新手,不熟悉 c++,我正在自学。
考虑到有人告诉我,只播种任何随机引擎一次是一种很好的做法(我可能在这里错了),从随机标准库中使用std::mt19937 的正确/最佳/更有效的方法是什么在一个类中,由 chrono 标准库中的 std::chrono::high_resolution_clock::now().time_since_epoch().count() 播种?
我想使用那个 chrono 值,因为它变化得非常快,而且会产生一个令人毛骨悚然的数字。我从未考虑过std::random_device,因为我认为它有点阴暗。我可能又错了。
编辑:大多数时候我在我的 Android 手机上使用 C4Droid IDE 编写代码和学习,因为我没有太多空闲时间坐在合适的电脑上,所以这就是我认为的原因std::random_device 不太可靠。
在我知道类是什么之前我已经成功完成了,但是我现在正在学习类并且做了很多试验和错误(到处都放 static_casts,尝试 const、static 等,因为代码总是出错) 来完成这项工作:
class Deck
{
private:
std::array<Card, 52> m_card;
const int m_seed {static_cast<int>(std::chrono::high_resolution_clock::now().time_since_epoch().count())};
std::mt19937 m_rng {m_seed};
int rng(int min, int max)
{
std::uniform_int_distribution<> rng{min, max};
return rng(m_rng);
}
void swapCard(Card &a, Card &b)
{
Card temp {a};
a = b;
b = temp;
}
public:
Deck()
{
int index{0};
for (int iii {0}; iii < Card::CS_MAX; ++iii)
{
for (int jjj {0}; jjj < Card::CR_MAX; ++jjj)
{
m_card[index] = Card(static_cast<Card::CardSuit>(iii), static_cast<Card::CardRank>(jjj));
++index;
}
}
}
void printDeck() const
{
for (int iii {0}; iii < 52; ++iii)
{
m_card[iii].printCard();
if (((iii + 1) % 13 == 0) && iii != 0)
std::cout << '\n';
else
std::cout << ' ';
}
}
void shuffleDeck(int xTimes = 1)
{
for (int iii {0}; iii < xTimes; ++iii)
{
for (int jjj {0}; jjj < 52; ++jjj)
{
swapCard(m_card[jjj], m_card[rng(0, 51)]);
}
}
}
};
这可行,但我不知道这是否是正确的做法。另外,有人告诉我,可以将永远不变的变量设为静态,以便在类的所有对象之间共享,但我不能将 m_seed 设为静态...
我很确定有一种更有效的方法可以做到这一点。你们能帮忙吗?
【问题讨论】:
-
“另外,有人告诉我,可以将永不改变的变量设为静态,以便在类的所有对象之间共享” 你确定你真的想要这样吗?在这种情况下,所有类实例都会产生相同的卡片序列。还有你是什么意思你不能做到
static,这样做的具体问题是什么? -
“我认为这有点阴暗。”为什么?我的意思是现代 CPU 有一个生成真正随机数的指令。
-
利用时间播种可以使您的程序在一定程度上具有可预测性。
-
@Quimby
std::random_device已知在MinGW编译器上被破坏。但除此之外,这将是我的首选(如果他们不进行简单的修复,我不会支持 MinGW)。 -
不相关,
std::shuffle(m_card.begin(), m_card.end(), m_rng)。让我们不要重新发明轮子。