我在c ++中有一个代表游戏领域的2D地图。在每个场地上都有一种运输工具(例如汽车,飞机......(以前都在枚举中定义))。
bool MainClass::isTrue(int x, int y, int w, int h)
{
for (int m = y; m < h; m++)
{
for (int n = x; n < w; n++)
{
if (map_.at(n-1).at(m-1) == SubClass::PartOfEnum::CAR ||
map_.at(n-1).at(m-1) == SubClass::PartofEnum::BOAT ||
map_.at(n-1).at(m-1) == SubClass::PartofEnum::SHIP ||
map_.at(n-1).at(m-1) == SubClass::PartofEnum::PLANE)
return (0);
}
}
return (1);
// other code ..
}
正如有人可以看到的那样,我正在迭代这个地图的一部分,并想知道在某些定义的坐标上是否有这些传输方式之一。问题是for循环内部的代码重复枚举的每个部分。所以我的问题是,如果有这种问题的解决方案只需编写一行代码而不是四行代码。也许将枚举的部分保存在一个单独的变量中,然后将此变量用于循环。原始枚举还包含一些其他对象,这些对象不应该是此循环的一部分(在原始枚举中还有一些其他的传输方式,如自行车,但这里只有这四个是相关的)。提前致谢
答案 0 :(得分:6)
所以我的问题是,如果这种问题的解决方案只需编写一行代码而不是四行
您需要进行四次比较,但不需要多次访问map_
。一个方便的实用程序应该:
bool isVehicle(SubClass::PartOfEnum test) {
return test == SubClass::PartOfEnum::CAR ||
test == SubClass::PartofEnum::BOAT ||
test == SubClass::PartofEnum::SHIP ||
test == SubClass::PartofEnum::PLANE;
}
然后你测试一下:
for (int n = x; n < w; n++)
{
if (isVehicle(map_.at(n-1).at(m-1)))
return (0);
}
一个相当简单的重构。单一访问之外的其他好处是,可以告诉条件检查的内容,而无需深入了解如何检查它的详细信息。现在,如果需要,您可以相当容易地在多个地方使用相同的条件。更不用说该功能的任何更新都将适用于您使用它执行检查的所有位置。
答案 1 :(得分:2)
一种方法是使用位掩码。这是一种将4个比较转换为1个比较的方法,它可能会提升您的表现。说PartOfEnum
定义如下:
enum PartOfEnum {
CAR = 1 << 0,
BOAT = 1 << 1,
SHIP = 1 << 2,
PLANE = 1 << 3,
VEHICLE = CAR | BOAT | SHIP | PLANE
};
然后测试看起来像:
for (int n = x; n < w; n++)
{
if (map_.at(n-1).at(m-1) & PartOfEnum::VEHICLE)
return (0);
}
如果使用enum class
,则需要提供相关的运算符重载。
答案 2 :(得分:1)
与@ DeiDei的解决方案类似,但是对于enum
是顺序的:
#include <iostream>
enum Vehicle
{
CAR,
BOAT,
SHIP,
PLANE
};
int main()
{
int seaVehicle = 1 << BOAT | 1 << SHIP;
int map_content = CAR;
std::cout << "Is this a Sea Vehicle? " << std::boolalpha << bool(1 << map_content & seaVehicle) << std::endl;
map_content = BOAT;
std::cout << "Is this a Sea Vehicle? " << std::boolalpha << bool(1 << map_content & seaVehicle) << std::endl;
}
Is this a Sea Vehicle? false
Is this a Sea Vehicle? true