Змейка JS. Искуственный интелект

Хочу сделать змейку на js вместе с ИИ.

const canvas = document.querySelector("canvas");
   const ctx = canvas.getContext("2d");
  
   const game = Array.apply(null, {length:40}).map(el=>Array.apply(null,{length:40}).map(el=>0))   

   let snake = [{x:1,y:1}]
   let snakeDirection = {Ox:1,Oy:0}
   const grid = 20;
   let apple = {x:0, y:0};
   let color = "white";

   class Neuron{
       constructor(value){
          this._value=value;
          this._weight = random(10,0,false);
       }
      get value(){return this._value*this._weight }
   
      set weight(value){this._weight-=value}
   } 

   class Brain{
      constructor (length){
        this._neurons = Array.apply(null,{length}).map(el=>new Neuron(0));
      }
  
      set neuron({id, value}) {
          this._neurons[id]=value;
          
      }
      get neurons (){return this._neurons}    

   }

  const snakeAi = new Brain(13);

   function log(text){
     const p = document.querySelector("p");
     p.innerHTML=text;
   }
   
   function random(max,min, floor = true){
       let value = Math.random()*(max-min+1)+min;
      if(floor){
           return Math.floor(value)
      }
      return value 
   } 

   document.addEventListener("keydown",(e)=>{
      const key = e.code;
      switch(key){
         case "KeyW":
             if(snakeDirection.Oy===0){snakeDirection.Oy=-1;snakeDirection.Ox=0;}
         break;
         case "KeyS":
             if(snakeDirection.Oy===0){snakeDirection.Oy=1;snakeDirection.Ox=0;}
         break;
         case "KeyD":
             if(snakeDirection.Ox===0){snakeDirection.Ox=1;snakeDirection.Oy=0;}
         break;
         case "KeyA":
             if(snakeDirection.Ox===0){snakeDirection.Ox=-1;snakeDirection.Oy=0;}
         break;
         case "KeyE":
             tik = 4;
         break;
         case "KeyQ":
             tik = 0;
         break;
      }
   })   

   for(let i = 0; i <10; i++){
    snake.push({x:0,y:0})
   }

   let befforeSnake = snake;
   let tik = 0;




   function collision(){
            if(snake[0].x===apple.x && snake[0].y===apple.y ){
                snake.push({x:snake[snake.length-1].x,y:snake[snake.length-1].y})
                apple.x=random(game[0].length-1,0);
                apple.y=random(game.length-1,0);

            }
           for(let i = 1; i < snake.length; i++){
            if(snake[i].x===snake[0].x && snake[i].y===snake[0].y){
                        return true
               }
           }
          if(snake[0].x+snakeDirection.Ox === game.length || snake[0].x+snakeDirection.Ox < 0 || snake[0].y+snakeDirection.Oy == game.length || snake[0].y+snakeDirection.Oy < 0 )    return true
   } 
   
   function move(){
        for(let i = 0, befforeEl={}; i<snake.length;i++){
            if(i===0){
               [befforeEl.x,befforeEl.y]=[snake[i].x,snake[i].y];
               snake[i].x+=snakeDirection.Ox;
               snake[i].y+=snakeDirection.Oy;
               game[snake[i].x][snake[i].y]="h";
            }else if(i===snake.length-1){
                 game[snake[i].x][snake[i].y]=0;
                 let el = snake[i];
                 snake[i] = befforeEl;
                 befforeEl = el;
            }else{
               let el = snake[i];
               snake[i] = befforeEl;
               befforeEl = el;
               game[snake[i].x][snake[i].y]=1;
           }
        }
   }


let [w,h]=[canvas.width,canvas.height]=[800,800];
apple.x=random(game[0].length-1,0);
apple.y=random(game.length-1,0);

let fps = 0;


function render(){
   if(tik++===2){
        [w,h]=[canvas.width,canvas.height]=[window.innerWidth,window.innerHeight];
        
        game[apple.x][apple.y]=2;
         
        if(!collision()) tik=0;
        move();

        ctx.fillStyle = "black";
        ctx.fillRect(0,0,w,h);
        ctx.strokeStyle="#fffefe";
        ctx.fillStyle = "white";

        for(let i = 0; i<game.length; i++){
           const row = game[i];
           for(let j = 0; j<row.length;j++){
                  if(row[j]===1){
                      ctx.fillRect(50+i*20,50+j*20,20,20);
                  }else if(row[j]==="h"){
                      ctx.fillStyle = "yellow";
                      ctx.fillRect(50+i*20,50+j*20,20,20);
                      ctx.fillStyle = "white";
                   }else if(row[j]===2){
                      ctx.fillStyle = "green";
                      ctx.fillRect(50+i*20,50+j*20,20,20);
                      ctx.fillStyle = "white";
                   }
           }
        }
     ctx.beginPath();
     ctx.rect(50,50,game.length*20,game[0].length*20)
     ctx.stroke();

 


   }
      fps++;
      requestAnimationFrame(render);
}


requestAnimationFrame(render);

setInterval(()=>{log(fps);fps=0;},1000)
   body{
   margin:0;
}
p{
  color:white;
  position:absolute;
  top: 20px;
  left:20px;

}
<p></p>
<canvas></canvas>

Использовал массив в виде карты, предполагалось что так будет менее затратной операция поиска области которую сможет видеть змейка.

Вопрос - как указать змейке область начиная из головы, область обзора должна быть 3 на 5

   ооо  
   гоо     - где г- голова, о - область которую видит змейка.  
   ооо

Желательно, область должна отображаться на игровом поле


Ответы (0 шт):