怎样产生随机方向(上下左右)?
2012-7-23
(3)
比如坦克游戏,敌人坦克移动的四个方向通常不会用 1~4 这样四个数值表示,而是用 dx、dy 这样的 x、y 轴上的增量表示。对应关系如下:
dx = 0; dy = -1; 表示向上
dx = 0; dy = 1; 表示向下
dx = -1; dy = 0; 表示向左
dx = 1; dy = 0; 表示向右
如果用 1~4 表示 4 个方向,敌人坦克前进一步的代码要这样写:
switch(dir)
{
case 1: x += 1;
case 2: y -= 1;
case 3: x -= 1;
case 4: y += 1;
}
但是用 dx、dy 表示之后,每次只需要这样做就可以,好处很明显 :
x += dx;
y += dy;
问题来了:怎样产生一组随机的 dx、dy?
最容易想到的办法就是:
n = rand() % 4;
switch(n)
{
case 0: dx = 0; dy = -1; 表示向上
case 1: dx = 0; dy = 1; 表示向下
case 2: dx = -1; dy = 0; 表示向左
case 3: dx = 1; dy = 0; 表示向右
}
x += dx;
y += dy;
还有人这么写:
int a[4][2] = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}};
int r = rand() % 4;
x += a[r][0];
y += a[r][1];
这种写法应该是比较理想的。多用了点内存相信多数情况下都能接受。
我以前见过国外有人这么做:
double a = (rand() % 4) * PI / 2;
dx = Round(cos(a)); // 注:Round 是自定义的四舍五入函数。
dy = Round(sin(a));
x += dx;
y += dy;
这种做法也很巧妙,只是执行速度有点慢。
别的还有很多思路,不再多说。这里说一个我想到的做法:
int n = (rand() % 4) * 2 + 1;
dx = n / 3 - 1;
dy = n % 3 - 1;
我将 -1、0、1 当做三进制的三种符号,三进制的十位表示 dx,三进制的个位表示 dy,那么这个三进制和十进制的对应关系如下:
三进制 十进制
-1 -1 0
-1 0 1
-1 1 2
0 -1 3
0 0 4
0 1 5
1 -1 6
1 0 7
1 1 8
容易看出,十进制的 1、3、5、7 对应的三进制就是我们需要的。于是,先用
int n = (rand() % 4) * 2 + 1;
得到随机的十进制数字 1、3、5、7,然后再分拣出三进制的十位和个位分别赋值给 dx、dy,于是,就得到了前面的算法。
int n = rand()%4;
dx = (n%2)*(n/2*2-1);
n = 3-n;
dy = (n%2)*(n/2*2-1);
// 0,1,2,3分别对应w,a,s,d