if语句-缩短C++if条件
if statement - Shortening C++ If condition
我有一个很长的if语句,用于检查井字游戏板的获胜条件:
if
((tttPositions[i][j][0] && tttPositions[i][j][1] && tttPositions[i][j][2] == 1)
|| (tttPositions[i][j][3] && tttPositions[i][j][4] && tttPositions[i][j][5] == 1)
|| (tttPositions[i][j][6] && tttPositions[i][j][7] && tttPositions[i][j][8] == 1)
|| (tttPositions[i][j][0] && tttPositions[i][j][3] && tttPositions[i][j][6] == 1)
|| (tttPositions[i][j][1] && tttPositions[i][j][4] && tttPositions[i][j][7] == 1)
|| (tttPositions[i][j][2] && tttPositions[i][j][5] && tttPositions[i][j][8] == 1)
|| (tttPositions[i][j][0] && tttPositions[i][j][4] && tttPositions[i][j][8] == 1)
|| (tttPositions[i][j][2] && tttPositions[i][j][4] && tttPositions[i][j][6] == 1))
{
if (j = 0)
cout << "x wins" << endl;
if (j = 1)
cout << "o wins" << endl;
}
这看起来真的很难看。。有没有一种方法可以单独跟踪获胜条件,从而大大缩短if语句的长度?
我把多个井字板放在一个3D矢量中,每个盒子是2x9,第一行代表"x"位置,第二行代表"o"位置,就像:
110000011
001110000
表示:
x x o
o o _
_ x x
您可以创建一个接受3个整数的lambda,并检查它们是否在数组中设置。您还可以将tttPositions[i][j]
绑定到引用,这样键入它就不那么麻烦了。
auto& pos = tttPositions[i][j];
auto check = [&pos](int a, int b, int c) {
return (pos[a] == 1) && (pos[b] == 1) && (pos[c] == 1);
};
// these three lines don't shorten the code, but
// they do make the if statememt more readable, imo
bool horizontal = check(0, 1, 2) || check(3, 4, 5) || check(6, 7, 8);
bool vertical = check(0, 3, 6) || check(1, 4, 7) || check(2, 5, 8);
bool diagonal = check(0, 4, 8) || check(2, 4, 6);
有了这一点,if
就变得简单多了(由于变量名的原因,它可以自我记录(:
if (horizontal || vertical || diagonal)
进一步的简化(同样,不是在代码大小上,而是在可读性上(是将所有这些因素考虑到一个函数中。我不确定tttPositions[i][j]
是什么类型,但假设它是一个9 int的数组,您可以这样做:
bool check_win_condition(int const (&pos)[9]) {
// all the stuff I did before, except instead of an if statement, just return
return horizontal || vertical || diagonal;
}
然后在你的另一个函数中,if
变成了简单的:
if (check_win_condition(tttPositions[i][j]))
您可能需要考虑在编译时创建一个数据结构来存储获胜线,然后在运行时遍历该数据结构,以检查玩家位置是否包括获胜线而不是大量if
s。
我注意到你的身体状况有很多重复检查。例如,您要检查tttPositions[i][j][4]
四次。成本可能微不足道,但如果能降低成本就好了。
一种可以用来存储获胜线的数据结构是一种树。在树的顶部将是一个精心选择的位置,这些位置包括在所有获胜线中,对于作为孩子的每个父位置,你都有包括这些位置的获胜线。
树只需要有两个级别,我曾将其命名为Parent
和Child
,并存储在一个平面阵列中。Parent
存储其子级的开始索引和结束索引。Child
存储获胜线上的另外两个位置:
struct Parent {
int pos;
int children_start;
int children_end;
};
using Child = std::pair<int, int>;
using Parents = std::array<Parent, 4>;
using Children = std::array<Child, 8>;
// Position indexes:
// 0 | 1 | 2
// ----------
// 3 | 4 | 5
// ----------
// 6 | 7 | 8
// centre top-left bottom-right
constexpr Parents parents = {{ {4,0,4}, {0,4,6}, {8,6,8} }};
// | | |
// +-----+--+--+-----+ +--+--+ +--+--+
// | | | | | | | |
constexpr Children children = {{ {0,8},{2,6},{1,7},{3,5},{1,2},{3,6},{2,5},{7,6} }};
添加几个begin
和end
函数,这样我们就可以在Parent
:上进行基于范围的循环
Children::const_iterator begin(const Parent& p) {
return children.begin() + p.children_start;
}
Children::const_iterator end(const Parent& p) {
return children.begin() + p.children_end;
}
有了这个,我们就可以编写一个函数来检查一个位置是否是一个胜利:
using PlayerPositions = std::array<int, 9>;
bool isWin(const PlayerPositions& pos) {
for (auto& parent : parents) {
if (pos[parent.pos]) {
for (auto& child : parent) {
if (pos[child.first] && pos[child.second])
return true;
}
}
}
return false;
}
现场演示。
在这种情况下,这是否会让事情变得更简单,这是有争议的,但更容易概括为更复杂的游戏规则。你甚至可以在运行时加载你的获胜位置。
- 将按位if条件转换为普通if条件
- 为什么简单的算术减法在"if"条件下不起作用?
- 为什么这个if(s[j]==s[i] && i>0)条件不适用于这个[{()}]
- 如何改进一堆在已知值范围内评估变量的 else-if 条件?
- 当我的 if 条件计算结果为 false 时,我的 else 块将不会执行
- 使用枚举作为条件,if 条件将返回什么,真或假?
- 为什么循环没有中断,并且 if 条件没有按预期工作?
- 使用 if 条件对数字进行分组
- 我们可以在第一个else-if条件结束后使用另一个else-if条件吗
- 调用一个小函数两次(例如在if条件和主体中)比将结果存储在局部变量中更可取
- 在if条件下,右或左改变值的相等性检查是否有任何区别
- 为什么当 while 循环中的 if 条件变为 false 时,我的函数不输出最后一条语句?
- 将子字符串与字符串数组进行比较的 IF 条件会在C++中产生错误
- 在 constexpr-if 条件下比较 constexpr 函数参数会导致错误
- 带有逻辑 OR 运算符的 if 条件的缩写?
- 为什么我可以将 ifstream 文件置于 if 条件?
- 如何将特征张量的值作为'if'条件表达式
- 在 c++ 中检查 if 条件中的向量位置范围
- 如何在Char数组中搜索Char在IF条件语句中
- 未正确评估'If'条件