我目前制作的游戏需要很多if语句,以确定用户点击的位置并相应地执行操作。它检查用户是否单击指定的坐标。下面的代码工作得非常好,但是我很难想出一个有效的方法来做到这一点(不仅仅是这个代码,而是一般的代码)。
if((mx > 78) && (mx < 113) && (my > 157) && (my < 191)) ifff(0, 0, 78, 157, 113, 191);
else if((mx > 116) && (mx < 150) && (my > 157) && (my < 191)) ifff(1, 0, 116, 157, 150, 191);
else if((mx > 153) && (mx < 188) && (my > 157) && (my < 191)) ifff(2, 0, 153, 157, 188, 191);
else if((mx > 196) && (mx < 230) && (my > 157) && (my < 191)) ifff(3, 0, 196, 157, 230, 191);
else if((mx > 233) && (mx < 267) && (my > 157) && (my < 191)) ifff(4, 0, 233, 157, 267, 191);
else if((mx > 270) && (mx < 303) && (my > 157) && (my < 191)) ifff(5, 0, 270, 157, 303, 191);
else if((mx > 311) && (mx < 345) && (my > 157) && (my < 191)) ifff(6, 0, 311, 157, 345, 191);
else if((mx > 348) && (mx < 384) && (my > 157) && (my < 191)) ifff(7, 0, 348, 157, 384, 191);
else if((mx > 388) && (mx < 421) && (my > 157) && (my < 191)) ifff(8, 0, 388, 157, 421, 191);
else if((mx > 78) && (mx < 113) && (my > 194) && (my < 229)) ifff(0, 1, 78, 194, 113, 229);
else if((mx > 116) && (mx < 150) && (my > 194) && (my < 229)) ifff(1, 1, 116, 194, 150, 229);
else if((mx > 153) && (mx < 188) && (my > 194) && (my < 229)) ifff(2, 1, 153, 194, 188, 229);
else if((mx > 196) && (mx < 230) && (my > 194) && (my < 229)) ifff(3, 1, 196, 194, 230, 229);
else if((mx > 233) && (mx < 267) && (my > 194) && (my < 229)) ifff(4, 1, 233, 194, 267, 229);
else if((mx > 270) && (mx < 303) && (my > 194) && (my < 229)) ifff(5, 1, 270, 194, 303, 229);
else if((mx > 311) && (mx < 345) && (my > 194) && (my < 229)) ifff(6, 1, 311, 194, 345, 229);
else if((mx > 348) && (mx < 384) && (my > 194) && (my < 229)) ifff(7, 1, 348, 194, 384, 229);
else if((mx > 388) && (mx < 421) && (my > 194) && (my < 229)) ifff(8, 1, 388, 194, 421, 229);
else if((mx > 78) && (mx < 113) && (my > 231) && (my < 266)) ifff(0, 2, 78, 231, 113, 266);
else if((mx > 116) && (mx < 150) && (my > 231) && (my < 266)) ifff(1, 2, 116, 231, 150, 266);
else if((mx > 153) && (mx < 188) && (my > 231) && (my < 266)) ifff(2, 2, 153, 231, 188, 266);
else if((mx > 196) && (mx < 230) && (my > 231) && (my < 266)) ifff(3, 2, 196, 231, 230, 266);
else if((mx > 233) && (mx < 267) && (my > 231) && (my < 266)) ifff(4, 2, 233, 231, 267, 266);
else if((mx > 270) && (mx < 303) && (my > 231) && (my < 266)) ifff(5, 2, 270, 231, 303, 266);
else if((mx > 311) && (mx < 345) && (my > 231) && (my < 266)) ifff(6, 2, 311, 231, 345, 266);
else if((mx > 348) && (mx < 384) && (my > 231) && (my < 266)) ifff(7, 2, 348, 231, 384, 266);
else if((mx > 388) && (mx < 421) && (my > 231) && (my < 266)) ifff(8, 2, 388, 231, 421, 266);
else if((mx > 78) && (mx < 113) && (my > 231) && (my < 266)) ifff(0, 3, 78, 231, 113, 266);
else if((mx > 116) && (mx < 150) && (my > 231) && (my < 266)) ifff(1, 3, 116, 231, 150, 266);
else if((mx > 153) && (mx < 188) && (my > 231) && (my < 266)) ifff(2, 3, 153, 231, 188, 266);
else if((mx > 196) && (mx < 230) && (my > 231) && (my < 266)) ifff(3, 3, 196, 231, 230, 266);
else if((mx > 233) && (mx < 267) && (my > 231) && (my < 266)) ifff(4, 3, 233, 231, 267, 266);
else if((mx > 270) && (mx < 303) && (my > 231) && (my < 266)) ifff(5, 3, 270, 231, 303, 266);
else if((mx > 311) && (mx < 345) && (my > 231) && (my < 266)) ifff(6, 3, 311, 231, 345, 266);
else if((mx > 348) && (mx < 384) && (my > 231) && (my < 266)) ifff(7, 3, 348, 231, 384, 266);
else if((mx > 388) && (mx < 421) && (my > 231) && (my < 266)) ifff(8, 3, 388, 231, 421, 266);
答案 0 :(得分:3)
基本思想是找到一种方法来表示代码中某些数据结构中每个行/块中的数据,然后创建这些数据结构的数组并循环遍历它们。
最简单的方法是创建一个数组,该数组将保存您想要的有关这些条件的数据。
例如,
[78, 113, 157, 191] # represents first if statement
然后,您可以创建一个包含9个此类数组的数组,这些数组将代表您在上述每个部分中的9个条件。
然后,您可以创建一个包含四个这样的数组的数组,其中每个成员最终代表代码中的每个部分。
最后,你只需遍历所有这些内容,例如:
for (i=0; i<4; i++)
for (j=0; j<9; j++)
if (mx > my_map[i][j][0]) && (mx < my_map[i][j][1]) ...
ifff(j, i, my_map[i][j][0], ....
你可以使用结构而不是数组,这将使上面的内容更容易阅读,但我不能举一个例子,因为你的代码不清楚不同的部分应该代表什么。
答案 1 :(得分:2)
为此,有interval trees之类的数据结构,请参阅Cormen一章或麻省理工学院关于此数据结构的算法课程。
答案 2 :(得分:1)
似乎是您的区间集中的某种结构。多次使用((mx > 78) && (mx < 113))
...然后您可以在代码中反映该结构,例如:
if ((mx > 78) && (mx < 113)
if (condition on my)
else if (condition on my)
...
else if (condition on mx)
if (condition on my)
else if (condition on my)
...
当然,它会破坏阅读的规律性,但一切都有代价。你甚至可以分解更多(想法是测试任何条件一次):
if (mx > 78)
if (mx < 113)
if (first condition on my)
if (second condition on my)
...
答案 3 :(得分:1)
正如我在评论中指出的那样,您的第四个else if
语句块正在遭受复制&#39; n&#39; paste-itis。它与第三个块具有相同的y范围(my > 231 && my < 266
)。因此,它永远不会有任何用处,因为如果范围匹配,第三个块优先,如果不匹配,它只会浪费时间重复一系列失败的测试。
但是,你有一个相当清晰的结构,可以通过几个表,查找函数和对ifff()
函数的单个调用来更好地表示,如下所示:
struct Range
{
int lo;
int hi;
int key;
};
static const struct Range x_range[] =
{
{ 78, 113, 0 },
{ 116, 150, 1 },
{ 153, 188, 2 },
{ 196, 230, 3 },
{ 233, 267, 4 },
{ 270, 303, 5 },
{ 311, 345, 6 },
{ 348, 384, 7 },
{ 388, 421, 8 },
};
enum { NUM_X_RANGE = sizeof(x_range) / sizeof(x_range[0]) };
static const struct Range y_range[] =
{
{ 157, 191, 0 },
{ 194, 229, 1 },
{ 231, 266, 2 },
{ 268, 299, 3 }, /* Guessed range */
};
enum { NUM_Y_RANGE = sizeof(y_range) / sizeof(y_range[0]) };
static inline int range_lookup(int val, const struct Range *range, int num_ranges)
{
for (int i = 0; i < num_ranges; i++)
{
if (val > range[i].lo && val < range[i].hi)
return i;
}
return -1;
}
extern void ifff_range(int mx, int my);
extern void ifff(int xkey, int ykey, int xlo, int ylo, int xhi, int yhi);
void ifff_range(int mx, int my)
{
int xr = range_lookup(mx, x_range, NUM_X_RANGE);
int yr = range_lookup(my, y_range, NUM_Y_RANGE);
if (xr != -1 && yr != -1)
ifff(x_range[xr].key, y_range[yr].key,
x_range[xr].lo, y_range[yr].lo,
x_range[xr].hi, y_range[yr].hi);
}
在此数据中,结构中的键值与数组中行的索引相同,因此键可以从结构中删除。
查找失败的方法有很多种。例如,mx == 114
或my == 192
将始终失败。