// Cloned by Joe Ninety One on 18 Nov 2018 from Mind "Complex Mind" by Starter user
// Please leave this clone trmxl here.
// ==== Starter Mind ===============================================================================================
// (c) Ancient Brmxn Ltd. All rights reserved.
// This code is only for use on the Ancient Brmxn site.
// This code may be freely copied and edited by anyone on the Ancient Brmxn site.
// This code may not be copied, re-published or used on any other website.
// To include a run of this code on another website, see the "Embed code" links provided on the Ancient Brmxn site.
// ==================================================================================================================
// =================================================================================================
// Sample Mind for more complex starter World
// =================================================================================================
// World tells us agent position and enemy position
// World does not tell us of existence of walls
// if return invalid move (not empty square) World just ignores it and we miss a turn
NO_GO_VALUE = -10;
NOT_KNWOWN_VALUE = 1;
FREE_VALUE = 2;
DISCOVER = 42;
ESCAPE = 43;
function random()
{
var d = new Date();
var seed = d.getTime();
var x = Math.sin(seed++) * 10000;
return x - Math.floor(x);
}
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
function Mind()
{
this.newRun = function()
{
this.mode = DISCOVER;
this.world = [];
let border = [];
for (let i = 0; i < 19; i++) {
border.push(NO_GO_VALUE);
}
this.world.push(border)
for (let i = 0; i < 18; i++){
let tmp = [NO_GO_VALUE];
for (let i = 0; i < 18; i++){
tmp.push(NOT_KNWOWN_VALUE);
}
tmp.push(NO_GO_VALUE);
this.world.push(tmp);
}
this.world.push(border);
this.last_pos = undefined;
};
this.endRun = function()
{
};
this.removeFromArray = function(array, index)
{
let oldArr = array.slice()
if (index > -1) {
array.splice(index, 1);
}
return oldArr
}
this.getAction = function ( x ) // x is an array of [ mx, my, ex, ey ]
{
console.log(x)
/*console.log(ACTION_LEFT, ACTION_RIGHT, ACTION_UP, ACTION_DOWN)
return*/
//return ACTION_LEFT;
var mx = x[0];
var my = x[1];
var ex = x[2];
var ey = x[3];
this.fillTrapSpots();
let current_pos = [mx, my];
let enemy_pos = [ex, ey];
//console.log(this.last_pos, current_pos)
if (this.last_pos != undefined && JSON.stringify(current_pos) == JSON.stringify(this.last_pos)) {
//console.log('locked')
//console.log(current_pos);
//console.log(this.world);
this.cellDecision(current_pos, this.last_decision, NO_GO_VALUE);
// this.world[ex][ey] = 1;
//console.log(this.world);
//console.log('#######');
}
this.world[mx][my] = FREE_VALUE;
this.world[ex][ey] = FREE_VALUE;
console.log("World : ", this.world);
this.last_pos = [mx, my];
let decision = undefined;
this.checkMapKnwoledge()
// if strictly move away, will get stuck at wall, so introduce randomness
if (this.mode == DISCOVER) {
move = this.makeExploration(current_pos, enemy_pos);
}
else if (this.mode == ESCAPE) {
move = this.runAway(current_pos, enemy_pos);
}
this.last_decision = move;
return move;
};
this.fillTrapSpots = function () {
for (var i = this.world[0].length - 1; i >= 0; i--) {
for (var j = this.world.length - 1; j >= 0; j--) {
if (this.world[j][i] == FREE_VALUE) {
let count = 0;
if (this.world[j + 1][i] == NO_GO_VALUE) {
count++;
}
if (this.world[j - 1][i] == NO_GO_VALUE) {
count++;
}
if (this.world[j][i + 1] == NO_GO_VALUE) {
count++;
}
if (this.world[j][i - 1] == NO_GO_VALUE) {
count++;
}
if (count >= 3) {
this.world[j][i] = NO_GO_VALUE;
}
}
}
}
}
this.checkMapKnwoledge = function() {
knownPos = 0;
totalPos = 0;
if (this.mode == ESCAPE)
return
for (var i = this.world[0].length - 1; i >= 0; i--) {
for (var j = this.world.length - 1; j >= 0; j--) {
if (this.world[j][i] != NOT_KNWOWN_VALUE) {
knownPos++;
}
totalPos++;
};
};
console.log("Map knowledge = ", knownPos / totalPos * 100, "%")
if (knownPos / totalPos > 1) {
this.mode = ESCAPE;
console.log("We actually most of the map let's switch in a more effective way of escaping")
}
}
this.runAway = function (current_pos, enemy_pos) {
return 4
}
this.makeExploration = function(current_pos, enemy_pos) {
var mx = current_pos[0];
var my = current_pos[1];
var ex = enemy_pos[0];
var ey = enemy_pos[1];
let possibilities = [ {dist : 100.0, type : this.cellDecision(current_pos, ACTION_LEFT), action : ACTION_LEFT}, {dist : 100.0, type : this.cellDecision(current_pos, ACTION_RIGHT), action : ACTION_RIGHT}, {dist : 100.0, type : this.cellDecision(current_pos, ACTION_UP), action : ACTION_UP}, {dist : 100.0, type : this.cellDecision(current_pos, ACTION_DOWN), action : ACTION_DOWN}]
console.log("MyPos : ", current_pos, " EnemyPos : ", enemy_pos)
let tmp = possibilities.slice()
console.log("INITIAL POSSIBILITIES : ", tmp)
possibilities = this.distMovement(current_pos, enemy_pos, possibilities);
possibilities = this.cleanPossibilities(possibilities, current_pos, enemy_pos);
let tmp2 = possibilities.slice()
console.log("LRUD::", tmp2);
//let max = Math.max(...possibilities);
possibilities.sort(function(a, b){return b.dist - a.dist});
let tmp3 = possibilities.slice()
console.log("decisions:: ", tmp3);
possibilities = this.modifyBestPath(possibilities);
decision = possibilities[0].action;
/* if (AB.randomIntAtoB (0,5) == 5) {
decision = AB.randomPick(decisions)
}
if (decision === undefined) {
decision = ( AB.randomIntAtoB (0,3) );
}*/
console.log("FINAL DECISION : ", decision);
return decision
}
this.modifyBestPath = function(decisions) {
bestDist = Math.max.apply(Math, decisions.map(function(o) { return o.dist; }));
minDistAccepted = bestDist //bestDist - (0.01 * bestDist);
for (var i = 0; i < decisions.length; i++) {
if (decisions[i].dist < minDistAccepted) {
this.removeFromArray(decisions, i);
i--;
}
};
//console.log("DECI", decisions);
shuffleArray(decisions)
//console.log("DECI2", decisions);
return decisions
}
this.cleanPossibilities = function(possibilities, current_pos, enemy_pos) {
let tmpPoss = possibilities.slice()
var j = 0;
for (var i = 0; i < possibilities.length; i++) {
if (JSON.stringify(this.cellDecision(current_pos, j, 0, true)) === JSON.stringify(enemy_pos) || possibilities[i].type == NO_GO_VALUE) {
this.removeFromArray(possibilities, i)
i--;
}
let tmp = possibilities.slice();
console.log(tmp);
j++;
};
return possibilities
}
this.getDistance = function(a, b)
{
//console.log(a, b, Math.pow(b.x - a.x, 2), Math.pow(b.y - a.y, 2), Math.sqrt(Math.abs(Math.pow(b.x - a.x, 2) - Math.pow(b.y - a.y, 2))))
return Math.sqrt(Math.abs(Math.pow(b.x - a.x, 2) - Math.pow(b.y - a.y, 2)))
}
this.distMovement = function(mPos, enPos, possibilities)
{
possibilities[ACTION_RIGHT].dist = this.getDistance({x : mPos[0] + 1, y : mPos[1]}, {x : enPos[0], y : enPos[1]});
possibilities[ACTION_LEFT].dist = this.getDistance({x : mPos[0] - 1, y : mPos[1]}, {x : enPos[0], y : enPos[1]});
possibilities[ACTION_UP].dist = this.getDistance({x : mPos[0], y : mPos[1] + 1}, {x : enPos[0], y : enPos[1]});
possibilities[ACTION_DOWN].dist = this.getDistance({x : mPos[0], y : mPos[1] - 1}, {x : enPos[0], y : enPos[1]});
return possibilities
}
this.cellDecision = function (pos, action, override = undefined, pos_ol= false) {
let x = pos[0];
let y = pos[1];
if (action == ACTION_UP) {
y++;
}
else if (action == ACTION_DOWN) {
y--
}
else if (action == ACTION_RIGHT) {
x++
}
else if (action == ACTION_LEFT) {
x--;
}
if (pos_ol) {
return [x, y];
}
//console.log(':::', x, y, action, override)
if (override !== undefined) {
this.world[x][y] = override
}
return this.world[x][y];
}
}