[Из песочницы] Учим Искусственный Интеллект играть в игру

ii_r.gif?raw=true

Итак, сканер — прямая. У нас есть координаты одной из её точек (координаты игрока) и угол относительно оси OX, вторую точку мы можем получить, используя тригонометрические функции sin и cos.

Отсюда получаем направляющий вектор прямой, а значит можем построить канонический вид уравнения этой прямой.

Чтобы получить значение на сканер, нужно посмотреть, пересекает ли какой-нибудь шар эту прямую, а значит, нужно представить уравнение прямой в параметрическом виде и подставить всё это в уравнения окружности, последовательно для каждой окружности для поля.

Если привести эту подстановку к общему виду, получится параметрической уравнение относительно a, b и с, где эти переменные — коэффициенты квадратного уравнения, начиная с квадрата соответственно.

Предлагаем читателю более подробно ознакомиться с этим алгоритмом самостоятельно, используя простейшие определения линейной алгебры
Ниже представлен код сканеров

Ball.scaners: {           //сканеры
                
  length: 1000,
                
  i: [],                                        //значения на сканерах
                
  get_data: function(){         //Ball.scaners.get_data / Получение данных со сканеров
                
    var angl = 0;
    var x0 = Ball.x,
    var y0 = Ball.y;
                
    var l = Ball.scaners.length;
                
    for(let k = 0; k < 32; k++){
                        
      x1 = l*Math.cos(angl),
      y1 = l*Math.sin(angl);
                        
      Ball.scaners.i[k] = 0;
                        
      for(i = 0; i < bombs.length; i++){
                                
        if(((k >= 0) && (k <= 8) && (bombs[i].x < x0) && (bombs[i].y < y0)) || ((k >= 8) && (k <= 16) && (bombs[i].x > x0) && (bombs[i].y < y0)) || ((k >= 16) && (k <= 24) && (bombs[i].x > x0) && (bombs[i].y > y0)) || ((k >= 24) && (k <= 32) && (bombs[i].x < x0) && (bombs[i].y > y0))){                  //Проверка областей видимости сканеров
                                
                                
                        
          var x2 = bombs[i].x,
          y2 = bombs[i].y;
                                        
          var p = true;         //проверка на наличие решения
          var pt = true;                //проверка на наличие ДВУХ корней
          var t1, t2;
                                        
                                        
          var a = x1*x1 + y1*y1,
          b = 2*(x1*(x0 - x2) + y1*(y0 - y2)),
          c = (x0 - x2)*(x0 - x2) + (y0 - y2)*(y0 - y2) - bombs[i].r*bombs[i].r;
                                        
                                        
          //------------------------------Проверка восьми возможных случаев
          if((a == 0) && (b != 0)){
            t = -c/b;
            pt = false;
          }
                                        
          if((a == 0) && (b == 0)){
            p = false;
          }
                                        
          if((a != 0) && (b != 0) && (c == 0)){
            t1 = 0;
            t2 = b/a;
          }
                                        
          if((a != 0) && (b == 0) && (c == 0)){
            t1 = 0;
            pt = false;
          }
                                        
          if((a != 0) && (b == 0) && (c != 0)){
            t1 = Math.sqrt(c/a);
            t2 = -Math.sqrt(c/a);
          }
                                        
          if((a != 0) && (b != 0) && (c != 0)){
                                                
            var d = b*b - 4*a*c;
                                                
            if(d > 0){
                                                        
              t1 = (-b + Math.sqrt(d))/(2*a);
              t2 = (-b - Math.sqrt(d))/(2*a);
                                                        
          }
                                                
          if(d == 0){
            t1 = -b/(2*a);
          }
                                                
          if(d < 0){
            p = false;
          }
                                                
        }
                                        
//-----------------------------------
                                        
        if(p == true){
                                        
          if(pt == true){
            let x = t1*x1 + x0;
            let y = t1*y1 + y0;
            let l1 = Math.pow((x - Ball.x), 2)+Math.pow((y - Ball.y), 2);
                                                
            x = t2*x1 + x0;
            y = t2*y1 + y0;
                                                        
            let l2 = Math.pow((x - Ball.x), 2)+Math.pow((y - Ball.y), 2);
                                                        
            if(l1 <= l2){
              Ball.scaners.i[k] += 1 - l1/(l*l);
            }else{
              Ball.scaners.i[k] += 1 - l2/(l*l);
            }
                                                
          }else{
                                                
            let x = t1*x1 + x0;
            let y = t1*y1 + y0;
                                                        
            Ball.scaners.i[k] += 1 - (Math.pow((x - Ball.x), 2)+Math.pow((y - Ball.y), 2))/(l*l);
                                                
          }
                                        
        }else{
                                        
          Ball.scaners.i[k] += 0;
                                                
        }
                                        
      }else{
        continue;
      }
                                
    }
                                
    angl += Math.PI/16;
                                
  }
                
//!---------------Для зелёных
  for(k = 32; k < 64; k++){
                        
    x1 = l*Math.cos(angl),
    y1 = l*Math.sin(angl);
                        
    Ball.scaners.i[k] = 0;
                        
    for(i = 0; i < apples.length; i++){
                                
      if(((k >= 32) && (k <= 40) && (apples[i].x < x0) && (apples[i].y < y0)) || ((k >= 40) && (k <= 48) && (apples[i].x > x0) && (apples[i].y < y0)) || ((k >= 48) && (k <= 56) && (apples[i].x > x0) && (apples[i].y > y0)) || ((k >= 56) && (k <= 64) && (apples[i].x < x0) && (apples[i].y > y0))){
                                
        var x2 = apples[i].x,
        var y2 = apples[i].y;
                                        
        var p = true;           //проверка на наличие решения
        var pt = true;          //проверка на наличие ДВУХ корней
        var t1, t2;
                                        
        var a = x1*x1 + y1*y1,
        b = 2*(x1*(x0 - x2) + y1*(y0 - y2)),
        c = (x0 - x2)*(x0 - x2) + (y0 - y2)*(y0 - y2) - apples[i].r*apples[i].r;
                                        
        //------------------------------Проверка восьми возможных случаев
        if((a == 0) && (b != 0)){
          t = -c/b;
          pt = false;
        }
                                        
        if((a == 0) && (b == 0)){
          p = false;
        }
                                        
        if((a != 0) && (b != 0) && (c == 0)){
          t1 = 0;
          t2 = b/a;
        }
                                        
        if((a != 0) && (b == 0) && (c == 0)){
          t1 = 0;
          pt = false;
        }
                                        
        if((a != 0) && (b == 0) && (c != 0)){
          t1 = Math.sqrt(c/a);
          t2 = -Math.sqrt(c/a);
        }
                                        
        if((a != 0) && (b != 0) && (c != 0)){
                                                
          var d = b*b - 4*a*c;
                                                
          if(d > 0){
                                                        
            t1 = (-b + Math.sqrt(d))/(2*a);
            t2 = (-b - Math.sqrt(d))/(2*a);
                                                        
          }
                                                
          if(d == 0){
            t1 = -b/(2*a);
          }
                                                
          if(d < 0){
            p = false;
          }
                                                
        }
                                        
       //-----------------------------------
                                        
        if(p == true){
                                        
          if(pt == true){
            let x = t1*x1 + x0;
            let y = t1*y1 + y0;
            let l1 = Math.pow((x - Ball.x), 2)+Math.pow((y - Ball.y), 2);
                                                
            x = t2*x1 + x0;
            y = t2*y1 + y0;
                                                        
            let l2 = Math.pow((x - Ball.x), 2)+Math.pow((y - Ball.y), 2);
                                                        
            if(l1 <= l2){
              Ball.scaners.i[k] += 1 - l1/(l*l);
            }else{
              Ball.scaners.i[k] += 1 - l2/(l*l);
            }
                                                
          }else{
                                                
            let x = t1*x1 + x0;
            let y = t1*y1 + y0;
                                                        
            Ball.scaners.i[k] += 1 - (Math.pow((x - Ball.x), 2)+Math.pow((y - Ball.y), 2))/(l*l);
                                                
          }
                                        
        }else{
                                        
          Ball.scaners.i[k] += 0;
                                                
        }
                                        
                                
      }else{
        continue;
      }
                                
    }
                                
      angl += Math.PI/16;
                                
    }
                        
                        
                        
    Ball.scaners.i[64] = (1000 - Ball.x) / 1000;    //левая граница
    Ball.scaners.i[65] = Ball.x / 1000;                 //правая граница
    Ball.scaners.i[66] = (500 - Ball.y) / 500;       //верхняя граница
    Ball.scaners.i[67] = Ball.y / 500;                  //нижняя граница
                
    }
                
}

© Habrahabr.ru