Code viewer for Mind:
Mind
const [LEFT, RIGHT, UP, DOWN, SIT] = [0, 1, 2, 3, 4]
const state = {walls: [], visited: [], ctx: null, me: {}}
const drawBox = (x, y, color) => {
const {ctx, S} = state
ctx.fillStyle = color
ctx.fillRect(S * x, S * y, S, S)
}
AB.mind.newRun = function() {
const N = 20
const S = 20 //scale
state.walls = Array(N).fill(0).map(_ => Array(N).fill(0))
state.visited = Array(N).fill(0).map(_ => Array(N).fill(-1))
const $ = id => document.getElementById(id)
const map = document.createElement('canvas')
map.height = map.width = N * S
map.style.background = 'darkgray'
map.style.height = map.style.width = N * S + 'px'
const ctx = map.getContext('2d')
ctx.fillStyle = 'grey'
ctx.fillRect(1 * S, 1 * S, N * S - 2 * S, N * S - 2 * S)
$('ab-runheaderbox').appendChild(map)
for (let i = 0; i < N; i++)
state.walls[i][0] = state.walls[0][i] = state.walls[i][N - 1] = state.walls[N - 1][i] = 1
state.ctx = ctx
state.N = N
state.S = S
}
AB.mind.endRun = function() {}
AB.mind.getAction = function(pos) {
const [meX, meY, enemyX, enemyY] = pos
const {visited, walls, ctx, N, S, me } = state
visited[meY][meX]++
visited[enemyY][enemyX] == -1 && visited[enemyY][enemyX]++
if(!me.hasMoved) {
me.hasMoved = true
me.x = meX
me.y = meY
return me.action = LEFT
}
// threat enemy position as a temporary wall
walls[enemyY][enemyX] = 1
if(me.x == meX && me.y == meY) { // hasn't moved
const y = meY + (me.action == UP ? 1 : (me.action == DOWN ? -1 : 0))
const x = meX + (me.action == LEFT ? -1 : (me.action == RIGHT ? 1 : 0))
walls[y][x] = 1
}
const todo = [
{y: meY, x: meX - 1}, // left
{y: meY, x: meX + 1}, // right
{y: meY + 1, x: meX}, // up
{y: meY - 1, x: meX} // down
]
let action = {type: SIT, visited: Infinity}
for(let i = 0; i < todo.length; i++) {
const move = todo[i]
if(walls[move.y][move.x]) continue;
const visit = visited[move.y][move.x]
if(visit < action.visited) {
action.type = i
action.visited = visit
}
}
me.x = meX
me.y = meY
me.action = action.type
// threat enemy position as a temporary wall
walls[enemyY][enemyX] = 0
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
const MAX_VISITED = Math.max(...visited.map(row => Math.max(...row)))
for(let y = 0; y < N; y++) {
for(let x = 0; x < N; x++) {
walls[y][x] && drawBox(x, y, 'yellow')
visited[y][x] != -1 && drawBox(x, y, `hsl(192, 90%, ${Math.max(56, parseInt(99 - 99 * visited[y][x] / MAX_VISITED))}%)`)
}
}
drawBox(enemyX, enemyY, 'red')
drawBox(meX, meY, 'green')
return me.action
};