Code viewer for Mind: ~[-_o]~

// Cloned by stephas2 on 18 Nov 2018 from Mind "~[-_o]~" by stephas2 
// Please leave this clone trail here.
 
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
          foundRoad = false,
          roadBlock = {},
          cp = () => m_p.x + '_' + m_p.y,
          ep = () => e_p.x + '_' + e_p.y,
          ctx; //canvas context to draw on

    function check_greens() {
        //check the board if any of the blocks have free surrounding blocks
        for(let key in map) {
            if(map[key] == "Wall") {
                let xy = key.split('_'),
                    x = parseInt(xy[0]),
                    y = parseInt(xy[1]),
                    chain = [],
                    top_left = map[(x-1)+'_'+(y-1)],
                    top_mid = map[(x-0)+'_'+(y-1)],
                    top_right = map[(x+1)+'_'+(y-1)],
                    
                    mid_left = map[(x-1)+'_'+(y+0)],
                    mid_right = map[(x+1)+'_'+(y+0)],
                    
                    bot_left = map[(x-1)+'_'+(y+1)],
                    bot_mid = map[(x+0)+'_'+(y+1)],
                    bot_right = map[(x+1)+'_'+(y+1)],
                    free = true
                    
                    if(!(top_left && top_left != "Wall"))
                        free = false
                    if(!(top_mid && top_mid != "Wall"))
                        free = false
                    if(!(top_right && top_right != "Wall"))
                        free = false
                    if(!(mid_left && mid_left != "Wall"))
                        free = false
                    if(!(mid_right && mid_right != "Wall"))
                        free = false
                    if(!(bot_left && bot_left != "Wall"))
                        free = false
                    if(!(bot_mid && bot_mid != "Wall"))
                        free = false
                    if(!(bot_right && bot_right != "Wall"))
                        free = false

                    if(free) {
                        //found block to run around
                        roadBlock = {x:x, y:y}
                        foundRoad = true
                        ctx.fillStyle = 'green'
                        ctx.fillRect(x*10, y*10, 10, 10)
                    }
            }
        }
        
    }
    
   
    //ACTION callback => newly calculated x, y based on ACTION
    function move(ACTION, cb) {
        if(ACTION == ACTION_LEFT) cb(m_p.x - 1, m_p.y)
        if(ACTION == ACTION_RIGHT) cb(m_p.x + 1, m_p.y)
        if(ACTION == ACTION_UP) cb(m_p.x, m_p.y - 1)
        if(ACTION == ACTION_DOWN) 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 findGreen() {
        return last_action = getRandomInt(4)
    }
   
    let clockWise = true
    function calculate_my_move() {
        if(foundRoad) {
            let x = roadBlock.x,
                y = roadBlock.y,
                    top_left = (x-1)+'_'+(y-1),
                    top_mid = (x-0)+'_'+(y-1),
                    top_right = (x+1)+'_'+(y-1),
                    
                    mid_left = (x-1)+'_'+(y+0),
                    mid_right = (x+1)+'_'+(y+0),
                    
                    bot_left = (x-1)+'_'+(y+1),
                    bot_mid = (x+0)+'_'+(y+1),
                    bot_right = (x+1)+'_'+(y+1)
              
              let free_moves = [top_left, top_mid, top_right, mid_right, bot_right, bot_mid, bot_left, mid_left]
              // I'm not around the green block :(
              if(free_moves.filter(e => e == cp()).length == 0)
                return findGreen()

              //ENEMY ROLE_PLAY
              if(cp() == top_left && ep() == top_mid)
                clockWise = false
              else if(cp() == top_left && ep() == mid_left)
                clockWise = true
              
              else if(cp() == top_mid && ep() == top_right)
                clockWise = false
              else if(cp() == top_mid && ep() == top_left)
                clockWise = true
              
              else if(cp() == top_right && ep() == mid_right)
                clockWise = false
              else if(cp() == top_right && ep() == top_mid)
                clockWise = true
                
              else if(cp() == mid_left && ep() == top_left)
                clockWise = false
              else if(cp() == mid_left && ep() == bot_left)
                clockWise = true
                
              else if(cp() == mid_right && ep() == bot_right)
                clockWise = false
              else if(cp() == mid_right && ep() == top_right)
                clockWise = true
                
              else if(cp() == bot_left && ep() == mid_left)
                clockWise = false
              else if(cp() == bot_left && ep() == bot_mid)
                clockWise = true
                
              else if(cp() == bot_mid && ep() == bot_left)
                clockWise = false
              else if(cp() == bot_mid && ep() == bot_right)
                clockWise = true
                
              else if(cp() == bot_right && ep() == bot_mid)
                clockWise = false
              else if(cp() == bot_right && ep() == mid_right)
                clockWise = true
                
// //AT THIS POINT ENEMY SHOULD NOT BE A THREAT BUT :( NOT MOVING -- SCORE
             else
                return ACTION_STAYSTILL
                
                

              
              //me Moving around
              if(cp() == top_left)
                return clockWise ? ACTION_RIGHT : ACTION_DOWN
              if(cp() == top_mid)
                return clockWise ? ACTION_RIGHT : ACTION_LEFT
              if(cp() == top_right)
                return clockWise ? ACTION_DOWN : ACTION_LEFT
              if(cp() == mid_left)
                return clockWise ? ACTION_UP : ACTION_DOWN
              if(cp() == mid_right)
                return clockWise ? ACTION_DOWN : ACTION_UP
              if(cp() == bot_left)
                return clockWise ? ACTION_UP : ACTION_RIGHT
              if(cp() == bot_mid)
                return clockWise ? ACTION_LEFT : ACTION_RIGHT
              if(cp() == bot_right)
                return clockWise ? ACTION_LEFT : ACTION_UP
            
              
            
             return ACTION_STAYSTILL           
        }
        return last_action = getRandomInt(4)
    }

        //row.push({isUnknown: true, isWall: false, isEnemy: false, isMe: false, isFree: false})
        //
    
    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>"
    };

    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[e_p.x + '_' + e_p.y] = "Me"

        }
        

        move(last_action, function(x, y) {
            if( !map[x+'_'+y] && str(m_p) == str(m_pp) ) {
                ctx.fillStyle = 'yellow'
                ctx.fillRect(x*10, y*10, 10, 10)
                map[x+'_'+y] = "Wall"
            }
        })
        
        
        check_greens()
        
        let my_move
        while(true) {
            my_move = calculate_my_move()
            if( my_move == ACTION_STAYSTILL || map[moving(my_move)] != "Wall" || map[moving(my_move)] != "Enemy")
                break
        }
        
        
        //previous position becomes current position
        e_pp = e_p 
        m_pp = m_p
        
        return my_move
    };
    this.endRun = function() {}
}