【问题标题】:Making AI chase nearest food让人工智能追逐最近的食物
【发布时间】:2015-11-27 23:18:18
【问题描述】:

前段时间我问了一个关于如何让人工智能在我的 Agar.io 克隆中追逐食物的问题,我最终自己弄清楚了,但现在我不知道如何让它追逐最近的食物给它。我尝试通过创建两个数组,其中食物单元和其中的计算机之间的距离为 (x, y)(如 this fiddle 中所示,但 AI 仍然追求更远的距离。以下是我的代码的相关部分:

返回必要的值:

var x = [];
var y = [];
x.push(cell.x - computerX);
y.push(cell.y - computerY);
return [Math.min.apply(null, x), Math.min.apply(null, y)];

应用它们:

this.xxx = xy()[0];
this.yyy = xy()[1];
this.dist2 = Math.sqrt(this.xxx * this.xxx + this.yyy * this.yyy);
this.speedX = (this.xxx / this.dist2) * this.speed.x;
this.speedY = (this.yyy / this.dist2) * this.speed.y;
computerX += 28 * this.speedX / computerRadius;
computerY += 28 * this.speedY / computerRadius;

(注意:'xy' 是返回值的函数)

我如何让 AI 尝试吃离它最近的食物而不是任何细胞?

【问题讨论】:

  • 投票否决。回答它的问题的相关部分不包含在问题中,并且“最小测试用例”不包括在内。您发布的代码出现“奇怪”:return [Math.min.apply(null, x), Math.min.apply(null, y)]; 似乎每次都返回[cell.x - computerX, cell.y - computer Y],因为xy 数组中只有一个条目
  • 对你有好处吗?如果你真的浏览了我的 jsFiddle,你会注意到上述代码位于 for 循环中。另外,相关部分都在那里。

标签: javascript html canvas artificial-intelligence


【解决方案1】:

对它们进行排序:

food.sort(function(cell1, cell2){
    var a1 = cell1.x - computerX, b1 = cell1.y - computerY,
        a2 = cell2.x - computerX, b2 = cell2.y - computerY,
        cell1Dist = Math.sqrt(a1*a1 + b1*b1),
        cell2Dist = Math.sqrt(a2*a2 + b2*b2);
    return (cell1Dist > cell2Dist)? 1 : ((cell1Dist < cell2Dist)? -1 : 0)
})

这假设 food = [{x: 4, y: 3}, {x: 7, y: 9}...],并且 computerYcomputerX 已设置,如您的问题所示。

编辑:

你不需要sqrt。它是密集的,并且不需要。试试这个:

calcDist = function(cell){
    var a = cell.x - computer.x, b = cell.y - computer.y;
    return a*a + b*b;
}

food.sort(function(cell, cell2){
    return calcDist(cell) - calcDist(cell2);
})

【讨论】:

  • 不过,我已经在这样做了。问题是我不知道如何在我的 for 循环中返回最短距离,因此我可以在为 AI 制作动画时使用它。
  • @Raiden,这对你有用吗?我修复了错误,它确实对单元格进行了正确排序。如果它有效,那么如果你能给我投票以表明这个答案解决了你的问题,向未来的访问者展示你是如何解决这个问题的,那将会很有帮助。
  • 是的,对不起,我试图实现它,但我不太清楚如何返回 dx 和 dy 值,看看如何有 a1、b1、a2 和 b2。
  • 啊 - a1 是与 cell1 的 x 差异,a2 是 cell2,b1 是与 cell1 的 y 差异,b2 是 cell2
  • cell1Dist是到cell1的距离,cell2Dist是到cell2的距离
【解决方案2】:

如何找到离人工智能最近的食物

它通过应用以下距离公式计算 AI(== 本演示中的鼠标)与画布上 100 个测试食物点之间的距离:

var dx = foods[n].x - AI.x;
var dy = foods[n].y - AI.y;
// Performance point: no need to do Math.sqrt -- you can just compare the squares
var distanceSquared = dx*dx+dy*dy;
if(distanceSquared<anyOtherDistanceSquared){
    // this is the nearest food
}

带注释的示例代码和演示:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
  var BB=canvas.getBoundingClientRect();
  offsetX=BB.left;
  offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }

var PI2=Math.PI*2;
var nearest=0;
var radius=3;

// create test foods
var foods=[];
for(var i=0;i<100;i++){
  var x=Math.random()*cw;
  var y=Math.random()*ch;
  foods.push({x:x,y:y});
  ctx.beginPath();
  ctx.arc(x,y,radius,0,PI2);
  ctx.fillStyle='skyblue';
  ctx.fill();
}

$("#canvas").mousemove(function(e){handleMouseMove(e);});

function handleMouseMove(e){
  // tell the browser we're handling this event
  e.preventDefault();
  e.stopPropagation();

  // uncolor the previous nearest
  ctx.beginPath();
  ctx.arc(nearest.x,nearest.y,radius,0,PI2);
  ctx.fillStyle='skyblue';
  ctx.fill();

  // get mouse x,y
  mouseX=parseInt(e.clientX-offsetX);
  mouseY=parseInt(e.clientY-offsetY);

  // find nearest food
  var min=10000000000000;
  for(var i=0;i<foods.length;i++){
    var f=foods[i];
    var dx=f.x-mouseX;
    var dy=f.y-mouseY;
    var testMin=dx*dx+dy*dy;
    if(testMin<min){
      min=testMin;
      nearest=f;
    }
  }

  // color new nearest
  ctx.beginPath();
  ctx.arc(nearest.x,nearest.y,radius,0,PI2);
  ctx.fillStyle='red';
  ctx.fill();
}
#canvas{border:1px solid red; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Move mouse and nearest "food" turns red</h4>
<canvas id="canvas" width=300 height=300></canvas>

【讨论】:

  • @Raiden 非常感谢您的支持!请记住,无需进行任何昂贵的分类——只需扫描食物阵列并找到距离最短的食物。 ;-)
【解决方案3】:

您并没有像现在那样对代码中的点进行排序;您正在对 x 和 y 进行独立排序。线

return [Math.min.apply(null, x), Math.min.apply(null, y)];

不是最近食物的偏移量。最近的食物可能没有最小的 x 位移最小的 y 位移,虽然细胞可能看起来是在寻找很远的食物,但它可能会在一个点之后根本不对应任何食物。这是我的意思的ASCII图。

X---A
| B
|
C

单元格X 的明显正确选择是食物B,但最小x 差为0,最小y 差为0。

将点作为坐标对存储在一个数组中,减少最小距离。

【讨论】:

  • @ 否决了它的人通常会以 原因 发表评论,谢谢。
猜你喜欢
  • 1970-01-01
  • 2023-03-16
  • 1970-01-01
  • 1970-01-01
  • 2021-04-25
  • 2011-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多