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

Ale*_*lex 22 javascript jquery genetic-programming evolutionary-algorithm

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

这是我的目标:

条款

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

处理

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

附加信息

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

Ray*_*nos 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;    
})
Run Code Online (Sandbox Code Playgroud)

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

你创建的每个生物都是相似的但具有不同的技能(基于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);    
};
Run Code Online (Sandbox Code Playgroud)

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

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);    
};
Run Code Online (Sandbox Code Playgroud)

每个生物只是随意地将自己置于屏幕上,然后在循环中反复调用自己的逻辑.

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();
};
Run Code Online (Sandbox Code Playgroud)

生物将检测它是否在逻辑循环中有食物.一旦它有食物,它就称之为自己的胜利方法.这结束了当前的游戏回合.

当一个生物获胜时,它会获得速度提升.

当你打电话.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();
},
Run Code Online (Sandbox Code Playgroud)

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]);
Run Code Online (Sandbox Code Playgroud)

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

在此输入图像描述

Math.random()确定了小动物移动多远/快.这指向右下角.

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

在此输入图像描述

然后我们必须计算生物和食物之间的角度.我们通过传递两个点来实现这一点,Raphael.angle并为我们计算角度.

在此输入图像描述

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

在此输入图像描述

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

  • 非常棒的开始Raynos,快! (4认同)

Kev*_*ity 0

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

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

谷歌应该能够帮助你找出完成这项工作所需的数学原理。

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

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

同样,可以通过 Google 找到确定两组坐标之间距离的数学公式。

我认为我无法比现在更简单地阐述这些内容,但希望这能让您了解应该朝哪个方向前进。