慢羊羊的空间

无为,无我,无欲,居下,清虚,自然

怎样产生随机方向(上下左右)? 铜牌收录

比如坦克游戏,敌人坦克移动的四个方向通常不会用 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,于是,就得到了前面的算法。 

评论 (3) -

  • 足智多谋,但多此一举!每个方向对应的是,2维平面向量,直接用一个数组表示即可。
    • 也许是早年的想法,不成熟!现在确实太。。。。。
  • 我有个想法不知道有没有撞车
    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

添加评论