简单的AI - JavaScript(使用jQuery进行动画制作)

时间:2011-05-25 21:02:17

标签: javascript jquery genetic-programming evolutionary-algorithm

首先,我想告诉您,我已经编程了几年(主要是基于C语言,iOS开发,网络资源等)作为一种爱好,现在我正在开发一种创建简单的兴趣人工智能(大多数人开始使用tic tac toe游戏是的,但我有兴趣使用geneteic编程的原理制作一些东西)。我希望读者知道这一点的原因是因为如果答案不是太复杂我会很感激(因为我还没有上过大学的计算机科学课程,所以对孩子来说并不难理解)。

这是我的目标:

条款

organim:一个CSS div 人口:一组生物(5或10)
食物来源:另一个CSS div

过程

  1. 生成一个种群,每个种群最初都具有相同的表型属性,但技能不同(为此,速度)
  2. 生成单一食物来源(每次都相同)
  3. 在建立环境约5秒后(步骤1和2),生物群体需要找到一种方式来竞争地获取食物来源
  4. 只有一种生物可以到达食物。到达它后,环境被重置除了发现食物项目的生物体现在受益并且其速度水平可能会增加而其他特别可怕的食物可能会变得更慢或被终止< / LI>
  5. 重复过程;用户可以观察人口的特征,看看哪些人在进化上取得了成功等等。
  6. 其他信息

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

3 个答案:

答案 0 :(得分:12)

Live Example

请注意,这会使用Raphael进行渲染,underscore使用语义糖。

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

  

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);

对于每个生物,你都会调用它们的开始方法。

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重复过程;用户可以观察人口的特征,看看哪些人在进化上取得了成功,等等。

Watch the live example :)

6下一步是什么:

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

<强>加成:

Travels towards food

警告:上面的链接确实朝着食物走去,但它做错了什么,我觉得那里有一个狡猾的错误。我认为我不会解决这个问题。

我将解释前往食物的逻辑

    // 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创建一个如下所示的随机向量:

enter image description here

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

因为它指向右下角,我们必须从此向量的角度移除135

enter image description here

然后我们必须计算生物和食物之间的角度。我们通过将两个点传递给Raphael.angle来计算我们的角度。

enter image description here

现在我们有角度,我们想要将运动矢量旋转那个角度。运动矢量当前朝上(黑色),我们希望将其旋转角度到它的新位置(红色)。在代码中,这是this.rotateVector

enter image description here

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

答案 1 :(得分:0)

您应该将问题分成两部分:

第1部分:生物体必须能够朝着您指定的点移动。这需要一个计时器,以及一些数学来确定你必须移动每个生物体的坐标,以使它更接近计时器的每个滴答的目标。

Google应该能够帮助您找到执行此操作的数学运算。

第2部分:有机体需要选择食物来源(可能是最接近的)并将其作为目标,然后使用第1部分所述的运动方法。

为此,您可以将每个生物和食物来源存储在阵列中。然后,在计时器的每个滴答声中,循环通过您的生物,然后在该循​​环内,循环通过食物来源寻找最近的一个。

再次,可以在Google找到用于确定两组坐标之间距离的数学计算。

我认为我不能说这些东西比我更简单,但希望这可以让你了解进入的方向。

答案 2 :(得分:0)

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

有趣的阅读:Cellular Automata