首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么AI在互相追逐/奔跑时振动?

为什么AI在互相追逐/奔跑时振动?
EN

Stack Overflow用户
提问于 2021-05-26 15:20:56
回答 1查看 50关注 0票数 0
代码语言:javascript
复制
    //let meow=meowmeow
     let cell = []    
     let Xgrid = 200;
     let Ygrid = 150;
     let cpu = [];
     let CPUteam = 2;
     let AIdist = [];
     let Cpudist = [];
     let Cpudist2 = [];
     let lost = false;
     function setup() {
       smooth();
       frameRate(999)
       createCanvas(600, 450);
     }
    
     function draw() {
       Newcelltimer++;
       let cellDist = [];
       let cpuDist = [];
       if (lost) {
         background(0)
       } else {
         background(220);
    
         translate(200,150)
         scale(0.9)
         if (Newcelltimer == 1 ) {
           cpu.push(ceil(random(-Xgrid, 2 * Xgrid)), ceil(random(-Ygrid, 2 * Ygrid)), 20, CPUteam)
           OffSetX.push(ceil(random(0, 1000000)))
           OffSetY.push(ceil(random(1000000, 2000000)))
    
           cell.push(ceil(random(0 - Xgrid, 2 * Xgrid)),
             ceil(random(0 - Ygrid, 2 * Ygrid)))
           CPUteam++;
         }
           if (Newcelltimer == 0) {
           cpu.push(ceil(random(-Xgrid, 2 * Xgrid)), ceil(random(-Ygrid, 2 * Ygrid)), 20, CPUteam)
           OffSetX.push(ceil(random(0, 1000000)))
           OffSetY.push(ceil(random(1000000, 2000000)))
    
           cell.push(ceil(random(0 - Xgrid, 2 * Xgrid)),
             ceil(random(0 - Ygrid, 2 * Ygrid)))
           CPUteam++;
         }   
         
        
        for (let j = 0; j < (cpu.length / 4); j++) {
    
           if (cpu[j*4+2]>200) {
             lost = true;
           }
           
           let cpuDist = [];
    //Constrains the AI in the Canvas
--------------------------------------------
           if (cpu[j * 4] > (2 * Xgrid) - (cpu[j * 4 + 2] / 2)) {
             cpu[j * 4] = (2 * Xgrid) - (cpu[j * 4 + 2] / 2)
           }
    
           if (cpu[j * 4] < (-Xgrid) + (cpu[j * 4 + 2] / 2)) {
             cpu[j * 4] = (-Xgrid) + (cpu[j * 4 + 2] / 2);
           }
    
           if (cpu[j * 4 + 1] > (2 * Ygrid) - (cpu[j * 4 + 2] / 2)) {
             cpu[j * 4 + 1] = (2 * Ygrid) - (cpu[j * 4 + 2] / 2);
           }
    
           if (cpu[j * 4 + 1] < (-Ygrid) + (cpu[j * 4 + 2] / 2)) {
             cpu[j * 4 + 1] = (-Ygrid) + (cpu[j * 4 + 2] / 2)
           }
---------------------------------------------------------------------
           for (let m = 0; m < cpu.length / 4; m++) {
             if (m != j) {
               if (cpu[j * 4 + 3] % 2 != cpu[m * 4 + 3] % 2) {
                 distant = dist(cpu[m * 4], cpu[m * 4 + 1], cpu[j * 4], cpu[j * 4 + 1])
                 let higher = (cpu[m * 4 + 2] > cpu[j * 4 + 2]) ? cpu[m * 4 + 2] : cpu[j * 4 + 2];
    
                 if (higher/2 >= distant) {
                   if (cpu[m * 4 + 2] > cpu[j * 4 + 2]) {
                     cpu[m * 4 + 2] += cpu[j * 4 + 2]
                     cpu.splice(j * 4, 4)
                   } else if(cpu[j*4+2]>cpu[m*4+2]) {
                     cpu[j * 4 + 2] += cpu[m * 4 + 2]
                     cpu.splice(m * 4, 4)
                   } //Else
                 } //If
                 else {
                   cpuDist.push(distant);
                 } //Else
               } //If
             } //If
           } //For
           //Finds the Closest CPU's index value
    -------------------------------------------------
           let ClosestCpu = round(min(cpuDist));
           let ClosestCpupos;
    
           for (var q = 0; q < cpu.length / 4; q++) {
             if (ClosestCpu == round(int(dist(cpu[q * 4], cpu[q * 4 + 1], cpu[j * 4], cpu[j * 4 + 1])))) {
               ClosestCpupos = q;
               break;
             }
           }
   ---------------------------------------------------

    //Checks if AI ate a cell
    --------------------------------------------------
           for (let n = 0; n < cell.length / 2; n++) {
             let dis = int(dist(cell[n * 2], cell[n * 2 + 1], cpu[j * 4], cpu[j * 4 + 1]))
             if (dis <= cpu[j * 4 + 2] / 2) {
               cpu[j * 4 + 2] += 5;
               cell.splice(n * 2, 2)
             } else {
    //If cell is NOT eaten, pushes the distance between AI and cell into an array
               cellDist.push(dis)
             }
           }
        --------------------------------------------------

    //Find the closest Cell's index value
    -------------------------------------
           let ClosestCell = min(cellDist);
           let ClosestCellpos;
           for (let r = 0; r < cell.length / 2; r++) {
             if (ClosestCell == int(dist(cell[r * 2], cell[r * 2 + 1], cpu[j * 4], cpu[j * 4 + 1]))) {
               ClosestCellpos = r;
               break;
             }
           }
        --------------------------------------
           
Checks if the closest AI is close enough to either chase or run away from it.
    -------------------------------------

      if (Cpudist[j]) {
      Cpudist[j] = dist(cpu[ClosestCpupos * 4], cpu[ClosestCpupos * 4 + 1], cpu[j*4], cpu[j*4+1]) < 250 &&  cpu[ClosestCpupos*4+2] < cpu[j * 4 + 2];
    } else {
      Cpudist[j] = dist(cpu[j * 4], cpu[j * 4 + 1], cpu[ClosestCpupos*4],cpu[ClosestCpupos*4+1]) < 200 && cpu[ClosestCpupos*4+2] < cpu[j * 4 + 2];
    }     
             if (Cpudist2[j]) {
      Cpudist2[j] = dist(cpu[ClosestCpupos * 4], cpu[ClosestCpupos * 4 + 1], cpu[j*4], cpu[j*4+1]) < 250 &&  cpu[ClosestCpupos*4+2] > cpu[j * 4 + 2];
    } else {
      Cpudist2[j] = dist(cpu[j * 4], cpu[j * 4 + 1], cpu[ClosestCpupos*4],cpu[ClosestCpupos*4+1]) < 200 && cpu[ClosestCpupos*4+2] > cpu[j * 4 + 2];
    }  
    -------------------------------------

  let amp = round((cpu[j * 4 + 2] / Math.pow(cpu[j * 4 + 2], 1.44)) * 20000) / 2000;                        
  

//Moves the AI in the following way: If the closest AI is less than an arbitrary 250 then you run, if not, check if the closest cell is less than another arbitrary 250, then you chase the cell. Otherways, you use noise values to move (I deleted that because it was quite repetitive) 
     if (Cpudist2[j]) {
       //Run        
       
          let distXpos = cpu[ClosestCpupos * 4] - cpu[j * 4];
          let distYpos = cpu[ClosestCpupos * 4 + 1] - cpu[j * 4 + 1];
    
             let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
             
             let MultVal = 250/abs(higherVal);
             
             distXpos*=MultVal;
             distYpos*=MultVal;
             
             distXpos = map(distXpos, -250, 250, -1, 1);
             distYpos = map(distYpos, -250, 250, -1, 1);
             cpu[j * 4] -= distXpos * amp;
             cpu[j * 4 + 1] -= distYpos * amp;
           } else if (dist(cpu[ClosestCpupos*4],cpu[ClosestCpupos*4+1],cpu[j*4],cpu[j*4+1])<250&&cpu[ClosestCpupos*4+2]<cpu[j*4+2]) {
             //Chase
             let distXpos = cpu[ClosestCpupos * 4] - cpu[j * 4];
             let distYpos = cpu[ClosestCpupos * 4 + 1] - cpu[j * 4 + 1];
    
             let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
             
             let MultVal = 250/abs(higherVal);
             
             distXpos*=MultVal;
             distYpos*=MultVal;
             
             distXpos = map(distXpos, -250, 250, -1, 1);
             distYpos = map(distYpos, -250, 250, -1, 1);
             cpu[j * 4] += distXpos * amp;
             cpu[j * 4 + 1] += distYpos * amp;
           } else if (dist(cell[ClosestCellpos * 2], cell[ClosestCellpos * 2 + 1], cpu[j * 4], cpu[j * 4 + 1]) < 250) {
             
             let distXpos = cell[ClosestCellpos * 2] - cpu[j * 4];
             let distYpos = cell[ClosestCellpos * 2 + 1] - cpu[j * 4 + 1];
    
             let higherVal = (abs(distXpos) > abs(distYpos)) ? distXpos : distYpos;
             
             let MultVal = 250/abs(higherVal);
             
             distXpos*=MultVal;
             distYpos*=MultVal;
    
             distXpos = map(distXpos, -250, 250, -1, 1);
             distYpos = map(distYpos, -250, 250, -1, 1);
             cpu[j * 4] += distXpos * amp;
             cpu[j * 4 + 1] += distYpos * amp;
           }
           if (cpu[j * 4 + 3] % 2 == 0) {
             fill(0, 0, 255)
             circle(cpu[j * 4], cpu[j * 4 + 1], cpu[j * 4 + 2]);
           } else {
             fill(255, 0, 0)
             circle(cpu[j * 4], cpu[j * 4 + 1], cpu[j * 4 + 2])
           }
         }
       }
Displays the cells on the canvas
       for (let k = 0; k < cell.length / 2; k++) {
    
         fill(0, 255, 255, 100)
         circle(cell[k * 2], cell[k * 2 + 1], 7)
       }
     }

我只想提一下,这是为了调试AI的目的,因为我的另一个程序和我的另一个程序是基于agar.io的。

  • https://editor.p5js.org/Meowmeow/sketches/bJiOlWTkd完整的程序,不删除任何内容
  • 当AI追逐AI时,它才会振动,但它会追逐它。
  • 问题可能在CPU for循环中。
  • 数组是混乱的,可能应该是2d数组,但是为了解释它:一维数组在4的“组”中,第一个数字是X pos,第二个数字是2Y pos,第三个是大小,第四个是团队蓝色或红色(如果第4个值%2是0,它是蓝色的,否则是1)。所以一个CPU数组看起来像[100,150,25,3,250,600,15,4],然后你做一个for循环,从0开始,到长度/4,然后你画AI的,首先AI是100,150,大小25,蓝色团队。第二个AI是200,600,大小为26,红队
  • cpuDist检查你是否追逐AI,cpuDist2检查你是否使用振荡逃离人工智能。CPU位于播放机200以内,然后将其设置为false,当它到达250时。这样,它就不会振荡,因为它需要移动50个像素才能改变行为。我认为问题就在这个逻辑上。
EN

回答 1

Stack Overflow用户

发布于 2021-05-26 18:31:26

你应该真正地使用对象。两个cpus的示例数组如下所示:

代码语言:javascript
复制
cpu = [
  {
    x: 100,
    y: 150,
    size: 25,
    team: 3
  },
  {
    x: 250,
    y: 600,
    size: 15,
    team: 4
  }
]

然后,您可以简单地按cpu循环,并访问每个cpu的属性如下所示:

代码语言:javascript
复制
for (let ai of cpu) {
  circle(ai.x, ai.y, ai.size)
}

这将不会太难实现,只需使用查找和替换。

对于您的实际问题,我不能像julien.giband在他们的评论中所说的那样运行您的代码。然而,我认为问题在于,您只是逃离了最接近的CPU。类似于你之前的问题,振动是行为变化过快的结果。

为了说明这一点,假设在一维中有3个CPU。将其位置设置为0、49和100。让中间的有10大小,外层的有20大小。我只想假设小的移动每帧3像素,大的移动每帧1像素。以下是它们的进展情况:

  1. (0,49,100)
    • 49离开左边,51离开右边,向右移动

  2. (1,52,99)
    • 51离开左边,47离开右边,向左移动

  3. (2,49,98)
    • 47向左,49向右,向右移动

  4. (3,52,97)
    • 49离开左边,45离开右边,向左移动

  5. (4,49,96)
    • 45离开左边,47离开右边,向右移动

  6. (5,52,95)
    • 以此类推,你就知道了

你看到中间的震动了吗?这就是你的代码中发生的事情。如果您想解决这个问题,可以执行julien.giband建议的建议之一。

如果您想逃离多个CPU,我建议为每个CPU提供一个追逐CPU的CPU列表。我不打算使用数组格式来解决这个问题,但是下面是CPU作为对象的样子:

代码语言:javascript
复制
single_cpu = {
  x: 100,
  y: 150,
  size: 25,
  team: 3,
  chased_by: [1, 2]
}

您可以动态地更改chased_by列表,类似于在当前版本中更改Cpudist[j]的方式。它可能看起来像这样(在j循环中):

代码语言:javascript
复制
for (let i; i < cpu.length; i++) {
  chase_index = cpu[j].chased_by.indexOf(i);
  if (chase_index == -1) { // if i is not in the list of cpus currently chasing j
    if (dist(cpu[i].x, cpu[i].y, cpu[j].x, cpu[j].y) < 200 &&
        cpu[i].team %2 != cpu[j].team %2 &&
        cpu[i].size > cpu[j].size) { // if i is bigger, on the other team, and within 200 of j
      cpu[j].chased_by.push(i); // add i to the list of cpus currently chasing j
    }
  } else { // if i is in the list
    if (dist(cpu[i].x, cpu[i].y, cpu[j].x, cpu[j].y) > 250 || 
        cpu[i].size < cpu[j].size) { // if i is smaller than or more than 250 away from j
      cpu[j].chased_by.splice(chase_index, 1); // remove i from the list
    }
  }
}

然后,当你在计算如何逃跑的时候,你就会逃离所有CPU的平均位置。为了同时逃离播放器和多个CPU,你必须做一些额外的事情。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67707933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档