Code viewer for Mind: Follow Enemy
function Mind()  { 
    
    let getRandomInt = max=>Math.floor(Math.random() * Math.floor(max)),
        str = JSON.stringify,
          BLOCKPUNISH = 50,
          ACTION_LEFT = 0,
          ACTION_RIGHT = 1,
          ACTION_UP = 3,
          ACTION_DOWN = 2,
          ACTION_STAYSTILL = 4,
          m_p = {}, //my position
          m_pp = {}, //my previous position
          e_p = {}, //enemy position
          e_pp = {}, //enemy previous position
          last_action = ACTION_STAYSTILL,  //my last action
          map = {}, //entire 20x20 map
          cp = () => m_p.x + '_' + m_p.y,
          ep = () => e_p.x + '_' + e_p.y,
          my_move,      // The action I took last
          ctx; //canvas context to draw on
     
     
    function diff (num1, num2) {
      if (num1 > num2) {
        return (num1 - num2);
      } else {
        return (num2 - num1);
      }
    }
    
    function dist (x1, y1, x2, y2) {
      var deltaX = diff(x1, x2);
      var deltaY = diff(y1, y2);
      var dist = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
      return (dist);
    } 
          
    //ACTION callback => newly calculated x, y based on ACTION
    function move(ACTION, cb) {
        if(ACTION == ACTION_LEFT) return cb(m_p.x - 1, m_p.y)
        if(ACTION == ACTION_RIGHT) return cb(m_p.x + 1, m_p.y)
        if(ACTION == ACTION_UP) return cb(m_p.x, m_p.y - 1)
        if(ACTION == ACTION_DOWN) return cb(m_p.x, m_p.y + 1)
        cb(m_p.x, m_p.y)
    }
    
    function moving(ACTION) {
        let mv = ""
        move(ACTION, function(x, y) {
            mv = x + '_' + y
        })
        return mv
    }
    function movexy(ACTION) {
        let mv = {}
        move(ACTION, function(x, y) {
            mv.x = x
            mv.y = y
        })
        return mv
    }
    
    this.newRun = function() {
        let debug_box = document.getElementById('ab-runheaderbox'),
            mini_map = document.createElement('canvas')
            mini_map.width = 200
            mini_map.height = 200
            mini_map.style.background = 'yellow'
            mini_map.style.width = '200px'
            mini_map.style.height = '200px'
            mini_map.setAttribute('id', 'mini_map')
            
            //draw a 20x20 map surrounded by walls
            ctx = mini_map.getContext('2d')
            ctx.fillStyle = 'grey'
            ctx.fillRect(10, 10, 180, 180)
            debug_box.appendChild(mini_map)

            //mark side walls
            for(let i = 0; i < 20; i++)
                map[i + '_0'] = map['0_'+i] = map[i + '_19'] = map['19_'+i] = "Wall"
            
            //fix name
            debug_box.children[4].children[0].innerHTML += "<br>"
            
            //globalize all
            window.map = map
            window.mp = cp
            
    };
    
    function discover_map() {
        let left = map[moving(ACTION_LEFT)],
            right = map[moving(ACTION_RIGHT)],
            up = map[moving(ACTION_UP)],
            down = map[moving(ACTION_DOWN)],
            left_free = false,
            right_free = false, 
            up_free = false,
            down_free = false
        
        // console.log("My TURN ________________________________\nPass 1 <<<<")
        if(!left) return ACTION_LEFT
        if(!right) return ACTION_RIGHT
        if(!up) return ACTION_UP
        if(!down) return ACTION_DOWN
        
        // console.log("Pass 2 <<<<")
        //only move if there is no better move
        
        if(left != "Wall" && left != "Enemy") left_free = true
        if(right != "Wall" && right != "Enemy") right_free = true
        if(up != "Wall" && up != "Enemy") up_free = true
        if(down != "Wall" && down != "Enemy") down_free = true
                
        if(left_free && !right_free && !up_free && !down_free) return ACTION_LEFT
        if(!left_free && right_free && !up_free && !down_free) return ACTION_RIGHT
        if(!left_free && !right_free && up_free && !down_free) return ACTION_UP
        if(!left_free && !right_free && !up_free && down_free) return ACTION_DOWN
        
        // console.log("Pass 3 <<<<")

        //left with 1 other        
        if(left_free && right_free && !up_free && !down_free) 
            return dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) ? ACTION_LEFT : ACTION_RIGHT
        
        if(left_free && !right_free && up_free && !down_free) 
            return dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) ? ACTION_LEFT : ACTION_UP

        if(left_free && !right_free && !up_free && down_free) 
            return dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) ? ACTION_LEFT : ACTION_DOWN
            
        //right with 1 other
        if(!left_free && right_free && up_free && !down_free) 
            return dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) ? ACTION_RIGHT : ACTION_UP
            
        if(!left_free && right_free && !up_free && down_free) 
            return dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) ? ACTION_RIGHT : ACTION_DOWN

        //up with 1 other
        if(!left_free && !right_free && up_free && down_free) 
            return dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) ? ACTION_UP : ACTION_DOWN
        
        // console.log("Pass 4 <<<<")


        //left with 2 others
        if(left_free && !right_free && up_free && down_free) 
            return dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y)
                ? (dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) ? ACTION_LEFT : ACTION_DOWN)
                : (dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) ? ACTION_UP : ACTION_DOWN)
        
        //left with 2 others
        if(left_free && right_free && !up_free && down_free) 
            return dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y)
                ? (dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) ? ACTION_LEFT : ACTION_DOWN)
                : (dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) ? ACTION_RIGHT : ACTION_DOWN)

        //left with 2 others
        if(left_free && right_free && up_free && !down_free) 
            return dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y)
                ? (dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) ? ACTION_LEFT : ACTION_UP)
                : (dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) ? ACTION_RIGHT : ACTION_UP)
                
        
        
        //TODO: right with 2 others
        if(!left_free && right_free && up_free && down_free) 
            return dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y)
                ? (dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) ? ACTION_RIGHT : ACTION_DOWN)
                : (dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) ? ACTION_UP : ACTION_DOWN)

        
        //TODO: up with 2 others
        //TODO: down with 2 others
        
        // console.log("Pass 5 <<<<")

        
        //left smallest
        if(left_free && right_free && up_free && down_free && 
          dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) &&
          dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) &&
          dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y))
            return ACTION_LEFT

        //right smallest
        if(left_free && right_free && up_free && down_free &&
          dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) &&
          dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) &&
          dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y) <= dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y))
            return ACTION_RIGHT

    
        //up smallest
        if(left_free && right_free && up_free && down_free &&
          dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) <= dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) &&
          dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) <= dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) &&
          dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) <= dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y))
            return ACTION_UP
    
    
        //down smallest
        if(left_free && right_free && up_free && down_free &&
          dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) <= dist(movexy(ACTION_LEFT).x, movexy(ACTION_LEFT).x, e_p.x, e_p.y) &&
          dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) <= dist(movexy(ACTION_UP).x, movexy(ACTION_UP).x, e_p.x, e_p.y) &&
          dist(movexy(ACTION_DOWN).x, movexy(ACTION_DOWN).x, e_p.x, e_p.y) <= dist(movexy(ACTION_RIGHT).x, movexy(ACTION_RIGHT).x, e_p.x, e_p.y))
            return ACTION_DOWN
    

        // console.log("Pass 6 <<<<")
        console.log("How can it possibly end up here hahahaha")
        return getRandomInt(4) //ACTION_STAYSTILL
    }

    this.getAction = function (state) {
        e_p = {x: state[2], y: state[3]}  //enemy position
        m_p  = {x: state[0], y: state[1]} //my position
        
        //draw me on map
        ctx.fillStyle = 'blue'
        ctx.fillRect(m_p.x*10, m_p.y*10, 10, 10)

        //draw enemy on map
        ctx.fillStyle = 'red'
        ctx.fillRect(e_p.x*10, e_p.y*10, 10, 10)  

        //check if previous positions are not the same, it's a free block
        if(str(e_p) != str(e_pp)) {
            ctx.fillStyle = 'lightblue'
            ctx.fillRect(e_pp.x*10, e_pp.y*10, 10, 10)
            map[e_pp.x + '_' + e_pp.y] = "Free"
            map[e_p.x + '_' + e_p.y] = "Enemy"
        }
        if(str(m_p) != str(m_pp)) {
            ctx.fillStyle = 'lightblue'
            ctx.fillRect(m_pp.x*10, m_pp.y*10, 10, 10)
            map[m_pp.x + '_' + m_pp.y] = "Free"
            map[m_p.x + '_' + m_p.y] = "Me"

        }
        
        //cp() == moving(my_move) && :((((((
        if(str(m_p) == str(m_pp) ) {       // || str(e_p) == str(e_pp) -> later on maybe 

                let xy = movexy(my_move)
                
                // console.log("new wall Was born, "+ JSON.stringify(xy) + " myPos: "+JSON.stringify(m_p)  )
                
             
                
                ctx.fillStyle = 'yellow'
                ctx.fillRect(xy.x*10, xy.y*10, 10, 10)
                map[xy.x+'_'+xy.y] = "Wall"
        }


        // console.log(cp(), moving(my_move), str(m_p), str(m_pp), my_move )
        // ABRun.controlPause();


        my_move = discover_map()
        //previous position becomes current position
        e_pp = e_p 
        m_pp = m_p
        
        return my_move
    };
    this.endRun = function() {}
}