人工智能-基本组群

——译:zh1110

   你是否想过让一群对象移动,并使他们具有群体观念,就象鱼群或领头的水牛。

这有如下几个难点,他们必须有一定的行为规则:

 

#组群必须向一中心靠拢。
#组群每个对象必须保持最小距离,当他与相邻对象靠近时
#组群对象必须以一定的速度及加速度移动

 

   想一下场景...非洲的斑马群。斑马群有一只领头的,但是他们要与相邻的斑马保持距离,外面的斑马会向内靠拢(远离狮子).

我向你展示一个例子:

Little Bo-Peep has lost her sheep
 

   我们先创建对象"sheep"(我认为羊比较有趣). 让他们开始时随机分布,你可看到上图是运行后的结果.

Private Type SHEEPTYPE

sngX As Single   'X坐标

sngY As Single   'Y坐标

sngXSpeed As Single    'X方向速度

sngYSpeed As Single    'Y方向速度

End Type

Dim mudtSheep() As SHEEPTYPE

Const NUM_SHEEP = 19   '羊的数量

Const MIN_SEPERATION = 15   '相邻羊的最小距离

Dim i As Integer

Dim j As Integer

Dim blnSeperation As Boolean

ReDim mudtSheep(NUM_SHEEP - 1)

Randomize

For i = 0 To UBound(mudtSheep)

blnSeperation = False

Do While Not (blnSeperation)

mudtSheep(i).sngX = Rnd() * frmFlock.ScaleWidth

mudtSheep(i).sngY = Rnd() * frmFlock.ScaleHeight

blnSeperation = True

For j = 0 To i - 1

If CalcDist(i, j) <= MIN_SEPERATION Then

blnSeperation = False

Exit For

End If

Next j

Loop

Next i

 

一小段代码就能显示这些羊群!首先我们为羊群数据建立UDT(用户自定义类型) 然后创建动态数组,数组尺寸通过 NUM_SHEEP 常量赋值 .用For loop 为每只羊分配启始的随机位置。为了不使羊重叠我们用了另外一个 For loop 检察它!

 

Sheep of a feather flock together

好,现在他们要靠成一群。继续代码!

Private Function CalcDist(intIndex1 As Integer, intIndex2 As Integer) As Single

 CalcDist = Sqr((mudtSheep(intIndex1).sngX - mudtSheep(intIndex2).sngX) ^ 2 + (mudtSheep(intIndex1).sngY - mudtSheep(intIndex2).sngY) ^ 2)

End Function

这段代码返回相邻羊的距离(通过他在数组中的索引).记住,我们还要保持羊的速度相近。

Const MAX_NOISE = 250

Dim sngXSum As Single

Dim sngYSum As Single

Dim sngXAvg As Single

Dim sngYAvg As Single

For j = 0 To UBound(mudtSheep)

sngXSum = sngXSum + mudtSheep(j).sngX

sngYSum = sngYSum + mudtSheep(j).sngY

Next j

sngXAvg = (sngXSum / NUM_SHEEP) + (Rnd() * MAX_NOISE) - (MAX_NOISE / 2)

sngYAvg = (sngYSum / NUM_SHEEP) + (Rnd() * MAX_NOISE) - (MAX_NOISE / 2)

    这段代码计算出所有羊的平均中心位置. 它加入了一些噪音,这样看上去羊会象是在拥挤的样子.减去(MAX_NOISE / 2)的理由是让波动位置正负平均,我们可取值 -125 到 125.

   最后就是移动每一只羊向中心靠拢——根据它的 X 和 Y 速度。如果移动会引起一只羊侵犯另一只羊,移动要被停止. 看一下原代码 source code 如果您希望。