我希望评估游戏的几种不同的潜在规则/评分系统。该游戏涉及掷三个骰子,最多掷三次。为了考虑每种可能性的结果,我迭代了九次可能的骰子掷中每一次的所有可能值。
\n我的问题是以下强力风格编码是否是最好的方法。
\n// get the result for each possible game\nvoid Evaluate( const ScoringSystem& sys )\n{\n for( int d1=0; d1<6; ++d1 )\n {\n for( int d2=0; d2<6; ++d2 )\n {\n for( int d3=0; d3<6; ++d3 )\n {\n for( int d4=0; d4<6; ++d4 )\n {\n for( int d5=0; d5<6; ++d5 )\n {\n for( int d6=0; d6<6; ++d6 )\n {\n for( int d7=0; d7<6; ++d7 )\n {\n for( int d8=0; d8<6; ++d8 )\n {\n for( int d9=0; d9<6; ++d9 )\n {\n int rolls[] = { d1, d2, d3, d4, d5, d6, d7, d8, d9 };\n\n // get the result for this particular game\n sys.GetGameResult( rolls );\n }\n }\n }\n }\n }\n }\n }\n }\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n该代码可以运行,但很丑陋,并且无法扩展到具有更多骰子的游戏。我有一个支持 C++17 的环境,因此我愿意接受更新的想法 \xe2\x80\x94,只要它们不会使代码看起来太糟糕。
\n(正切:6^9 超过 1000 万。我可能最好使用伪随机数,并且只是“掷”九个骰子一百万次。但我仍然想知道是否有一种聪明的方法来完成排列。)
\nKev*_*vin 11
如果您发现嵌套的循环看起来几乎相同,您应该考虑使用递归。
void generateDiceRolls(const ScoringSystem& sys, std::vector<int>& rolls, size_t index)
{
if (index == rolls.size())
{
// Reached the end - all the dice have been rolled
sys.GetGameResult(rolls);
}
else
{
// For each value of a die at this index, generate dice rolls for the rest of them
for (int i = 0; i < 6; i++)
{
rolls[index] = i;
generateDiceRolls(sys, rolls, index + 1);
}
}
}
void Evaluate(const ScoringSystem& sys)
{
std::vector<int> rolls(9); // Change 9 to however many dice you want to use
generateDiceRolls(sys, rolls, 0);
}
Run Code Online (Sandbox Code Playgroud)
一些库如range-v3建议cartesian_product允许更简单:
std::array<int, 6> dice_range{1, 2, 3, 4, 5, 6};
for (auto t : ranges::view::cartesian_product(dice_range, dice_range, dice_range,
dice_range, dice_range, dice_range,
dice_range, dice_range, dice_range))
{
std::cout << std::get<0>(t)
<< std::get<1>(t)
<< std::get<2>(t)
/* << .. */
<< std::endl;
std::apply([](auto... args){ (std::cout << ... << args) << std::endl; }, t); // C++17
}
Run Code Online (Sandbox Code Playgroud)
如果没有外部库,您可以使用“增加”的向量:
bool increase(std::vector<std::size_t>& it, std::size_t max)
{
for (std::size_t i = 0, size = it.size(); i != size; ++i) {
const std::size_t index = size - 1 - i;
++it[index];
if (it[index] >= max) {
it[index] = 0;
} else {
return true;
}
}
return false;
}
template <typename F>
void iterate(F f, std::size_t size, std::size_t max = 6)
{
std::vector<std::size_t> it(size, 0);
do {
f(it);
} while (increase(it, max));
}
int main()
{
iterate([](const auto& v){ for (auto e : v) std::cout << 1 + e; std::cout << std::endl; }, 4);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1117 次 |
| 最近记录: |