Code viewer for Mind: Cloned Complex Mind (clone...

// Cloned by David Jusev on 1 Dec 2022 from Mind "Cloned Complex Mind" by Joe Ninety One 
// Please leave this clone trail here.
 


// 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.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.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()

		console.log("JSON CMP UP : ", JSON.stringify(this.cellDecision(current_pos, ACTION_UP, 0, true)), JSON.stringify(enemy_pos))
		console.log("JSON CMP DOWN : ", JSON.stringify(this.cellDecision(current_pos, ACTION_DOWN, 0, true)), JSON.stringify(enemy_pos))
		console.log("JSON CMP RIGHT : ", JSON.stringify(this.cellDecision(current_pos, ACTION_RIGHT, 0, true)), JSON.stringify(enemy_pos))
		console.log("JSON CMP LEFT : ", JSON.stringify(this.cellDecision(current_pos, ACTION_LEFT, 0, true)), JSON.stringify(enemy_pos))

		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];
	}

}