// Cloned by AC on 5 Nov 2020 from Mind "Complex Mind" by Starter user
// Please leave this clone trail here.
// =================================================================================================
// 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
var a_mode = 1;
var max_mode = 2;
var gridmax = 0;
var lastMove = [-1,-1];
var last2Moves =[[-1,-1],[-1,-1]];
var lastELocation = []
var move_advantage = 0;
var distance_advantage = 0;
var distance = 0;
var a_moves = 0;
var e_moves = 0;
var blocked = [];
var deadEnd = [];
AB.mind.getAction = function ( x ) // x is an array of [ ai, aj, ei, ej ]
{
var ai = x[0];
var aj = x[1];
var ei = x[2];
var ej = x[3];
console.log("x ->" + x)
if (a_mode == 1)
{
// if strictly move away, will get stuck at wall, so introduce randomness
if ( ej < aj ) return ( AB.randomPick ( ACTION_UP, AB.randomPick(ACTION_RIGHT,ACTION_LEFT) ));
if ( ej > aj ) return ( AB.randomPick ( ACTION_DOWN, AB.randomPick(ACTION_RIGHT,ACTION_LEFT) ));
if ( ei < ai ) return ( AB.randomPick ( ACTION_RIGHT, AB.randomPick(ACTION_UP,ACTION_DOWN) ));
if ( ei > ai ) return ( AB.randomPick ( ACTION_LEFT, AB.randomPick(ACTION_UP,ACTION_DOWN) ));
return ( AB.randomIntAtoB (0,3) );
}
else if (a_mode == 2)
{
//first we assume the location is not encrypted. So if we are at 0,0 we know we are against the wall.
//from here, with no information about the walls, there is no possible tracking of obstacles.
if ((last2Moves[1][0] != ai) || (last2Moves[1][1] != aj))
{
// agent didn't move to last intended location. the intended location much be occupied or blocked.
if (!blocked.includes(last2Moves[1].toString()))
blocked.push(last2Moves[1].toString());
console.log("didn't move : " + blocked.includes(last2Moves[1].toString()) + "," + last2Moves)
}
if ((lastELocation[0] != ei) || (lastELocation[1] != ej))
{
e_moves += 1;
}
var tempMax = Math.max(ai, aj, ei, ej, gridmax);
if(tempMax > gridmax)
{
gridmax = tempMax
console.log("gridmax increased to :" + gridmax )
}
var availableMoves = [];
var checked = 0;
if (ai == 1)
{
if(!blocked.includes([ai-1,aj].toString()))
{
blocked.push([ai-1,aj].toString());
console.log("added walls");
}
}
if(aj == 1)
{
if(!blocked.includes([ai,aj-1].toString()))
{
blocked.push([ai,aj-1].toString());
console.log("added walls");
}
}
if (!blocked.includes([ai-1,aj].toString()) && ai > 1)
{
checked += 1;
if((ai-1 != ei) || (aj != ej))
availableMoves.push([ai-1,aj, ACTION_LEFT]);
}
if (!blocked.includes([ai+1,aj].toString()))
{
checked += 1;
if ((ai+1 != ei) || (aj != ej))
availableMoves.push([ai+1,aj, ACTION_RIGHT]);
}
if (!blocked.includes([ai,aj-1].toString()) && aj > 1)
{
checked += 1;
if ((ai != ei) || (aj-1 != ej))
availableMoves.push([ai,aj-1, ACTION_DOWN]);
}
if (!blocked.includes([ai,aj+1].toString()))
{
checked += 1;
if((ai != ei) || (aj+1 != ej))
availableMoves.push([ai,aj+1, ACTION_UP]);
}
if(checked < 2)
{
//add current location as blocked and don't come back. This location is a hole.
//blocked.push([ai,aj].toString());
if (!deadEnd.includes([ai,aj].toString()))
deadEnd.push([ai,aj].toString());
}
if (availableMoves !== [])
{
var rIndex;
var max_h = 0;
var temp_Max;
var location_i, location_j;
console.log("possible moves:" + availableMoves.length);
for (var k = 0; k < availableMoves.length; k++)
{
temp_Max = 0;
location_i = availableMoves[k][0]
location_j = availableMoves[k][1]
if(!isDeadEnd([location_i, location_j]))
{
temp_Max += gridmax * gridmax; // penalize if it is a deadend
}
if(!wasThere([location_i, location_j]))
{
temp_Max += gridmax; // penalize if the move has been visited before.
}
temp_Max += Math.sqrt(((location_i-ei) * (location_i-ei)) + ((location_j-ej)*(location_j-ej)));
console.log("location: " + temp_Max + "," + location_i+"," + location_j);
if (max_h < temp_Max)
{
selectedMoves = [];
selectedMoves.push(k);
console.log("index changed: " + max_h + "," + temp_Max + "," + selectedMoves.length);
max_h = temp_Max
}
else if(max_h == temp_Max)
{
selectedMoves.push(k);
console.log("added to selected");
}
}
rIndex = selectedMoves[AB.randomIntAtoB(0, selectedMoves.length-1)];
console.log(rIndex);
}
else
{
//check if one of the direction is deadend. take this last step
if(!deadEnd.includes([ai-1,aj].toString()))
availableMoves.push([ai-1,aj, ACTION_LEFT]);
else if (!deadEnd.includes([ai+1,aj].toString()))
availableMoves.push([ai+1,aj, ACTION_RIGHT]);
else if(!deadEnd.includes([ai,aj-1].toString()))
availableMoves.push([ai,aj-1, ACTION_DOWN]);
else if(!deadEnd.includes([ai,aj+1].toString()))
availableMoves.push([ai,aj+1, ACTION_UP]);
}
var nextMove =[]
nextMove[0] = availableMoves[rIndex][0];
nextMove[1] = availableMoves[rIndex][1];
lastELocation[0] = ei;
lastELocation[1] = ej;
last2Moves.shift()
last2Moves.push(nextMove);
a_moves =+ 1;
console.log("next direction :" + availableMoves[rIndex][2] + "->" + last2Moves);
return (availableMoves[rIndex][2]);
}
else
{
}
};
function isDeadEnd(location)
{
var count = 0;
var left = [location[0]-1, location[1]];
var right = [location[0]+1, location[1]];
var top = [location[0], location[1]-1];
var down = [location[0], location[1]+1];
if (!blocked.includes(left.toString())) count += 1;
if (!blocked.includes(right.toString())) count += 1;
if (!blocked.includes(top.toString())) count += 1;
if (!blocked.includes(down.toString())) count += 1;
return count < 2; //if only one entry, this is a deadend.
}
function wasThere(location)
{
return ((last2Moves[0][0] == location[0]) && (last2Moves[0][1] == location[1])) ||
((last2Moves[1][0] == location[0]) && (last2Moves[1][1] == location[1]));
}
function changeAgentMode(mode=0)
{
if ((mode == 0) || (mode < 0) || (mode > max_mode))
a_mode = (a_mode % max_mode) + 1
else
a_mode = mode
return a_mode;
}