22

首先,我想让你知道我已经编程了几年(主要是基于 C 的语言、iOS 开发、Web 东西等)作为一种爱好,现在我对创建一个简单的 AI 产生了兴趣(大多数人们从井字游戏开始,是的,但我有兴趣使用基因编程原理制作一些东西)。我希望读者知道这一点的原因是,如果答案不太复杂(因为我还没有参加大学计算机科学课程,对孩子来说不太难理解),我将不胜感激。

这是我的目标:

条款

organsim:一个 CSS div
种群:一组生物 (5 或 10)
食物来源:另一个 CSS div

过程

  1. 产生了一个种群,每个种群最初似乎都具有相同的表型属性,但他们的技能不同(为此,速度)
  2. 生成单一食物来源(每次都相同)
  3. 在环境建立大约 5 秒后(步骤 1 和 2),生物种群需要找到一种竞争性地到达食物来源的方法
  4. 只有一种有机体可以接触到食品。到达它后,环境被重置,除了上次找到食物的生物现在受益并且它的速度等级可能会增加,而其他做得特别糟糕的生物可能会变得更慢或被终止
  5. 重复过程;用户可以观察种群的特征并查看哪些特征在进化上取得了成功等。

附加信息

如您所见,上述步骤几乎模拟了进化,但方式非常简单(与动物的真实生活情况相比,条件更少);现在这就是我在这里问的原因:我完全迷失了。我真的不知道从哪里开始(除了生成人口,我很可能会这样做以及让他们通过 jQuery 动画移动)。但能够让他们吸引食物来源是我现在做不到的。所以,我想帮助指出正确的方向。

4

3 回答 3

12

现场示例

请注意,这使用Raphael进行渲染,并使用下划线表示语义糖。

我写了一个非常小的程序来满足你的要求。(好玩)。

1 产生了一个群体,每个群体最初似乎都具有相同的表型属性,但他们的技能不同(为此,速度)。

var Critter = function() {
    // default the speed to something random.
    this.speed = SPEED + Math.random()*SPEED;

    // logic module
    var logic = function() { ... }
}

...
// initialize an array of critters.
critters: _.map(_.range(0,COUNT), function() {
    return new Critter;    
})

为您的人口成员创建一个构造函数,然后填充这些人的数组。我已经将一个长度计数数组映射到一个小动物数组。(厚颜无耻的循环)。

您创建的每个小动物都将相似但具有不同的技能(基于Math.random()),但它们将包含相同的逻辑单元。

2 生成单一食物来源(每次都相同)

// trivial Food object.
var Food = function() {
    // rectangle with random x, random y, and SIZE as width / height
    this.el = paper.rect(Math.random()*WIDTH, Math.random()*HEIGHT, SIZE, SIZE);    
};

食物对象构造函数只是在屏幕上随机放置一个正方形

3 在环境建立约 5 秒后(步骤 1 和 2),生物种群需要找到一种竞争性地到达食物来源的方法

设置环境:

_.invoke(this.critters, "start", this.food.el.getBBox(), out_of_bounds);

对于每个小动物,您调用它们的 start 方法。

this.start = function(food) {
    // create a player (circle);
    this.el = paper.circle(Math.random()*WIDTH, Math.random()*HEIGHT, SIZE / 2);  
    // set an interval to run the logic over and over.
    loop = setInterval(_.bind(logic, this, food), 25);    
};

每个小动物只是将自己随机放置在屏幕上,然后在循环中一遍又一遍地调用自己的逻辑。

4 只有一种生物可以接触到食品。到达它后,环境被重置,除了上次找到食物的生物现在受益并且它的速度等级可能会增加,而其他做得特别糟糕的生物可能会变得更慢或被终止

var logic = function(food) {
    // if you hit food you win
    if (this.el.collision(food)) {
        this.win();
    }
}

// you won
this.win = function() {
    console.log("win");
    // increase speed
    this.speed += Math.random()*5;  
    // end round
    Game.end();
};

小动物将在逻辑循环中检测它是否有食物。一旦它有了食物,它就会调用自己的获胜方法。这结束了当前的游戏回合。

当小动物获胜时,它会获得速度提升。

当你打电话时游戏会自动重启.end(在移除所有当前的小动物之后)

end: function () {
    // tell all critters to end their round
    _.invoke(this.critters, "remove");
    // remove the food
    this.food.el.remove();
    // start again !
    this.start();
},

5 过程重复;用户可以观察种群的特征并查看哪些特征在进化上取得了成功等。

观看现场示例 :)

6 下一步:

  • 调整全局数字和其他硬编码数字
  • logic函数中实现一些 AI。
  • 浏览从 /1 到 /180 的所有 jsfiddles,看看它是如何构建的。
  • 抱怨评论不够详细
  • 既然您已经看到了一个示例,请扔掉我的代码并从头开始。
  • 出生代码只是创建了一个“基本”小动物。它不是从两个现有的小动物中繁殖出来的,也没有增加技能。这意味着没有进化。

奖金:

走向食物

警告:上面的链接确实指向食物,但它做错了,我认为那里有一个狡猾的错误。我不认为我会解决这个问题。

我将解释前往食物的逻辑

    // angle between critter and food
    var angle = Raphael.angle(
        this.el.getBBox().x,
        this.el.getBBox().y,
        food.x,
        food.y) - 135; // the 135 is the default direction (bottom right)
    // get a random speed
    var rand = Math.random()*this.speed;
    // travel towards the food box by rotating your vector by the angle
    var points = this.rotateVector([rand, rand], angle);

    // move towards the box
    this.el.translate(points[0], points[1]);

首先rand创建一个如下所示的随机向量:

在此处输入图像描述

Math.random()决定了小动物移动的距离/速度。这是指向右下角。

因为它指向右下角,所以我们必须135从这个向量的角度移除度数

在此处输入图像描述

然后我们必须计算小动物和食物之间的角度。我们通过传入两个点来做到这一点Raphael.angle,它会为我们计算角度。

在此处输入图像描述

现在我们有了角度,我们想将我们的运动矢量旋转该角度。运动矢量当前指向上方(黑色),我们希望将其旋转一定角度到新位置(红色)。在代码中这是this.rotateVector

在此处输入图像描述

现在正指向正确的方向!我们可以打电话this.el.translate(points[0], points[1])

于 2011-05-25T23:13:10.520 回答
0

您可以查看Conway 的 LIFE的各种实现以获取灵感。我相信你可能已经看过类似的东西了?

有趣的阅​​读:元胞自动机

于 2011-05-25T21:25:09.057 回答
0

你应该把你的问题分成两部分:

第 1 部分:有机体必须能够向您指定的点移动。这将需要一个计时器和一些数学来确定您必须移动每个生物体的坐标,以便在计时器的每个滴答声中使其更接近其目标。

谷歌应该能够帮助您找出完成这项工作的数学运算。

第 2 部分:生物需要选择食物来源(可能是最近的)并瞄准,然后使用第 1 部分中描述的移动方法。

为此,您可以将每个生物体和食物来源存储在数组中。然后,在计时器的每个滴答声中,循环遍历您的生物体,然后在该循​​环中,循环遍历食物来源以寻找最近的食物来源。

同样,确定两组坐标之间距离的数学方法可以在 Google 中找到。

我认为我不能比我更简单地说明这些东西,但希望这能让您了解前进的方向。

于 2011-05-25T21:16:04.750 回答