我前段时间问了一个问题,关于如何让人工智能在我的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尝试吃最近的食物,而不仅仅是任何细胞?
答案 0 :(得分:2)
对它们进行排序:
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)
})
这假设食物= [{x: 4, y: 3}, {x: 7, y: 9}...]
,computerY
和computerX
已设置,如您的问题所示。
修改强>
你不需要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);
})
答案 1 :(得分:1)
以下是如何找到离AI最近的食物
通过应用此距离公式计算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();
}
&#13;
#canvas{border:1px solid red; }
&#13;
<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>
&#13;
答案 2 :(得分:-1)
您现在没有在代码中对点进行排序;你是独立排序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.
将点作为坐标对存储在一个数组中,减少最小距离。