链表中的随机性

Randomness in linked lists

本文关键字:随机性 链表      更新时间:2023-10-16

我们能在链表中获得随机性吗?。我正在实施太空射击游戏,在这个游戏中敌人应该随机射击子弹。我将敌人存储在链表中,我想随机选择一些敌人并从中射击。如何对链接列表执行此操作?

在我看来,随机化一个数字N,然后让飞船N射击不是正确的方法。首先,这意味着一艘船将拍摄每一帧或每一个转弯,这不一定是你想要的。

问题是,无论屏幕上有多少敌人,发射的子弹数量都是一样的。无论你有1个敌人还是100个敌人,所有敌人加在一起的射速都将是每回合/每帧一枪,这在游戏设计方面毫无意义。这也意味着一艘船有时可能在2xN转弯时不会开火(这有点像旧的武侠电影,坏人排队等待与"英雄"战斗,从不同时攻击)。

在我看来,最好的方法是对船只进行迭代,使每艘船只都有一定的概率开火,最好是基于它上次开火的时间。

long now = getCurrentTime... /*replace with real function*/
double epsilon = 0.0001; /*adjust as needed*/
while(current = enemyList.next()){
if(Math.random() < epsilon * (now - current.lastFired))
{
current.fire();
current.lastFired = now;
}
}

如果你不利用这个机会,在N个元素上迭代几乎没有任何意义。如果你使用列表,这意味着你计划迭代所有敌人并更新每个敌人。在其中的N个上再次迭代毫无意义,只是为了选择一个来开火。

您可以从第一个节点开始,调用n amount的"next"。

伪代码:

int num = Math.random() * myLinkedList.Count;
for( num ){
myLinkedList.next();
}
return myLinkedList.currentNode;

也许你可以添加第二个容器,比如array/arraylist/vvector,并从那里管理它。。。你可以随时问你的教授他/她是否同意。

如果你确切地知道你的列表中有多少项目,以及你想在每帧中拍摄多少项目,实际上有一种相对简单的方法:对于每个项目,如果在Np的列表中还有k项目要拍摄,则当前项目应当以概率p/k-射击,并且随后应当更新kp的值。这个的伪代码看起来像:

myThing curThing = myList->head;
int objectsLeft = myListCount;
int shootersLeft = numShootersPerTick;
while ( curThing )
{
if ( random(objectsLeft) < shootersLeft )
{
curThing->Shoot();
shootersLeft--;
}
objectsLeft--;
curThing = curThing->next;
}

注意,我假设random(N)返回一个介于0和N-1之间的数字;即N个事物中的一个。虽然这种算法似乎应该选择具有不同概率的不同项目(毕竟,对随机数的检查对每个项目都在变化!),但从数学上可以看出,这不仅选择了具有正确概率的每个射手,而且每组射手的可能性实际上是相等的。

假设您想从列表中选择k随机元素(N是总数)。选择的这些k元素应该是完全随机的。方法如下:

  1. 从第一个k元素开始
  2. 通过列表前进;当与第m个元素一起出现时,生成随机整数0<=r<m

    • 如果是r<k,则抛出先前随机选择的元素,并将其替换为第m个元素

一个带有概率和归纳论证的小算术表明,这给了所有元素相等的机会。