Code viewer for Mind: Walter's Mind
const GRID_SIZE = 20;

var stateHistory = [];
var moveHistory = [];
var mapLayout = [];

var currentState = null;
var prevState = null;

function getMoves(state) {
  var ax = state[0];
  var ay = state[1];

  // 0: left, 1: right, 2: up, 3: down, 4: still
  return [{ x: ax-1, y: ay }, { x: ax+1, y: ay }, { x: ax, y: ay+1 }, { x: ax, y: ay-1 }, { x: ax, y: ay }];
}

function getAgentPosition(state) {
  var ax = state[0];
  var ay = state[1];
  return {
    x: ax,
    y: ay
  };
}

function getEnemyPosition(state) {
  var ex = state[2];
  var ey = state[3];
  return {
    x: ex,
    y: ey
  };
}


function updateMap() { // check if we were able to move
  if (moveHistory.length < 1) return;

  var lastMove = moveHistory[moveHistory.length - 1];
  var currentPos = getAgentPosition(currentState);
  var prevPos = getAgentPosition(prevState);
  var moveBlocked = currentPos.x === prevPos.x && currentPos.y === prevPos.y && lastMove !== ACTION_STAYSTILL;
  if (!moveBlocked) return;

  enemyPos = getEnemyPosition(prevState);
  if (lastMove === ACTION_UP) { // ensure we moved up
    if (enemyPos.y === (currentPos.y + 1) && enemyPos.x === currentPos.x) return;
    // enemy not blocking square, should update map
    mapLayout[currentPos.y + 1][currentPos.x] = 1;
  } else if (lastMove === ACTION_DOWN) { // ensure we moved down
    if (enemyPos.y === currentPos.y - 1 && enemyPos.x === currentPos.x) return;
    // enemy not blocking square, should update map
    mapLayout[currentPos.y - 1][currentPos.x] = 1;
  } else if (lastMove === ACTION_LEFT) { // ensure we moved left
    if (enemyPos.y === currentPos.y && enemyPos.x === currentPos.x - 1) return;
    // enemy not blocking square, should update map
    mapLayout[currentPos.y][currentPos.x - 1] = 1;
  } else if (lastMove === ACTION_RIGHT) { // ensure we moved up
    if (enemyPos.y === currentPos.y && enemyPos.x === currentPos.x + 1) return;
    // enemy not blocking square, should update map
    mapLayout[currentPos.y][currentPos.x + 1] = 1;
  }
}

function simpleGetMove(state) {
  var ax = state[0];
  var ay = state[1];
  var ex = state[2];
  var ey = state[3];

  if (ex < ax) return (AB.randomPick(ACTION_UP, AB.randomPick(ACTION_RIGHT, ACTION_LEFT)));
  if (ex > ax) return (AB.randomPick(ACTION_DOWN, AB.randomPick(ACTION_RIGHT, ACTION_LEFT)));

  if (ey < ay) return (AB.randomPick(ACTION_RIGHT, AB.randomPick(ACTION_UP, ACTION_DOWN)));
  if (ey > ay) return (AB.randomPick(ACTION_LEFT, AB.randomPick(ACTION_UP, ACTION_DOWN)));
}

function getDistance(pointA, pointB) {
  if (pointA === null || pointB === null) return -1;
  return Math.sqrt(Math.pow(pointB.x - pointA.x, 2) + Math.pow(pointB.y - pointA.y, 2));
}

function getManhattanDistance(pointA, pointB) {
  if (pointA === null || pointB === null) return -1;
  return Math.abs(pointA.x - pointB.x) + Math.abs(pointA.y - pointB.y);
}

function getMove(state) {
  var potentialMoves = getMoves(state);
  potentialMoves = potentialMoves.map(function checkIfMoveBlocked(move) {
    if (mapLayout[move.y][move.x] === 1) return null;
    return move;
  })
  var enemyPos = getEnemyPosition(state);

  // [{ x: ax-1, y: ay }, { x: ax+1, y: ay }, { x: ax, y: ay+1 }, { x: ax, y: ay-1 }, { x: ax, y: ay }];
  // [12.5, 9.3, 10.7, 11.9, 9]
  var distances = potentialMoves.map(function (pos) {
    return getManhattanDistance(pos, enemyPos);
  });

  console.log('moves', potentialMoves, distances);

  var bestMove = 4;
  var largestDistance = 0;
  for (var i = 0; i <= 3; i++) {
    var distance = distances[i];
    if (distance > largestDistance) {
      largestDistance = distance;
      bestMove = i;
    }
  }

  return bestMove;
}

function Mind() {

  this.newRun = function () {
    // init mapLayout
    // 0 for free square, 1 for blocked
    for (i = 0; i < GRID_SIZE; i++) {
      mapLayout.push([]);
      for (j = 0; j < GRID_SIZE; j++) {
        if (i === 0 || i === 19 || j === 0 || j === 19) mapLayout[i].push(1); // wall
        else mapLayout[i].push(0);
      }
    }
  };

  this.getAction = function (state) { // state: [ax, ay, ex, ey]
    prevState = currentState;
    currentState = state;
    stateHistory.push(state);

    updateMap();

    var move = getMove(state);
    // console.log(move, mapLayout);
    moveHistory.push(move);
    return (move);
  };


  this.endRun = function () {};

}