Code viewer for Mind: Final Mind Submission

// Cloned by Mohamed Hafez on 24 Nov 2020 from Mind "Complex Mind mine" by Mohamed Hafez 
// Please leave this clone trail here.
 


// Cloned by Mohamed Hafez on 13 Nov 2020 from Mind "Complex Mind (clone by Mohamed Hafez)" by Mohamed Hafez 
// Please leave this clone trail here.
 


// Cloned by Mohamed Hafez on 8 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 


 

	AB.mind.getAction = function ( x)		// x is an array of inputs from world
	{ 
		var ai = x[0];
		var aj = x[1];
		var ei = x[2];
		var ej = x[3];
		var agentalgorithm2= x[4]; //[MH] to decide which algorithm to run
		var m1 = x[5];  // [MH] value of lower spot
		var m2=  x[6]; // [MH] value of right spot
		var m3=  x[7]; //[MH] value of left spot
		var m4=  x[8]; //[MH] value of upper spot
		var gridsize =x[9]; //[MH] Gridsize
        
        //[MH] Parameters for Mind A* Algorithm
        var openSet2 = [];
        var closedSet2 = [];
        var start2;
        var end2;
        var GRIDMIND=x[10];
        var si;
        var sj;

        //[MH] Parameter for other mind algorithm
        var max2=[];
        

        //[MH] Function to calculate heuristic for A*
        function heuristic(a, b) 
        {

        return ( Math.sqrt(Math.pow((a.i - b.i),2) + Math.pow((a.j - b.j),2)) );
    
        }

        function removeFromArray(arr, elt) 
        {
    // Could use indexOf here instead to be more efficient
  for (var i = arr.length - 1; i >= 0; i--) 
    if (arr[i] == elt) 
      arr.splice(i, 1);
      
      function occupied ( i, j )		// is this square occupied
{
 if ( ( ei == i ) && ( ej == j ) ) return true;		// variable objects 
 if ( ( ai == i ) && ( aj == j ) ) return true;

 if ( GRIDMIND[i][j].value == 1 ) return true;		// fixed objects //[MH] Adding .value since we are dealing with object now	 
 if ( GRIDMIND[i][j].value == 2 ) return true;		//[MH] Adding .value since we are dealing with object now
	 
 return false;
}
      
}
        
        
        //[MH] Default algorithm
        if (agentalgorithm2==1)
        {
		// Random Algorithm

        
		 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) );
 		
        }
 		
 		//[MH] Agent algorithm to escape from Enemy by going far and avoid being stucked by the wall
 		if (agentalgorithm2==3)
 		{

    //[MH] Distance between neigbors spots and enemy to choose hte one which is far from enemy
 		var bfsm=[];
 	
    bfsm[0]=Math.sqrt(Math.pow(ai-ei,2 )  + Math.pow(aj+1-ej,2)) ;
    bfsm[1]=Math.sqrt(Math.pow(ai+1-ei,2 )  + Math.pow(aj-ej,2)) ;
    bfsm[2]=Math.sqrt(Math.pow(ai-ei,2 )  + Math.pow(aj-1-ej,2)) ;
    bfsm[3]=Math.sqrt(Math.pow(ai-1-ei,2 )  + Math.pow(aj-ej,2)) ;
    
    //[MH] ignore neigbors who are wall or maze
    if(m1>0) bfsm[2]=0;
    if(m2>0) bfsm[1]=0;
    if(m3>0) bfsm[3]=0;
    if(m4>0) bfsm[0]=0;
    
    //[MH] Choose neighors with highest distance from Enemy
    var max = Math.max.apply(null, bfsm);
        for (var f = 0; f < bfsm.length; f++ )
        {
        if (bfsm[f]==max)
        {
        max2.push(f);
        }
        }
 		
    return AB.randomElementOfArray ( max2 );
 		}
 		
 		
 		//[MH] A* Alogrithm for Mind
 		if (agentalgorithm2==2)
 		{
 	openSet2=[];
    closedSet2=[];
    start2 = GRIDMIND[ai][aj]; //[MH] Start point is mind location

  //[MH] Grid is divided in 9 Qs and purpose of function to know enemy and agent are in which Q
  function quarter(i,j)
  {
  if ( (i>=0) && (i<=gridsize/3) && (j>=0) && (j<=gridsize/3 )) return 1; 
  if ( (i>=gridsize/3) && (i<=2*gridsize/3) && (j>=0) && (j<gridsize/3 )) return 2;
  if ( (i>=2*gridsize/3) && (i<=gridsize) && (j>=0) && (j<=gridsize/3 )) return 3;
  if ( (i>=0) && (i<gridsize/3) && (j>=gridsize/3) && (j<=2*gridsize/3 )) return 4;
  if ( (i>=gridsize/3) && (i<=2*gridsize/3) && (j>=gridsize/3) && (j<=2*gridsize/3 )) return 5;
  if ( (i>2*gridsize/3) && (i<=gridsize) && (j>=gridsize/3) && (j<=2*gridsize/3 )) return 6;
  if ( (i>=0) && (i<=gridsize/3) && (j>=2*gridsize/3) && (j<=gridsize)) return 7;
  if ( (i>=gridsize/3) && (i<=2*gridsize/3) && (j>2*gridsize/3) && (j<=gridsize)) return 8;
  if ( (i>=2*gridsize/3) && (i<=gridsize) && (j>=2*gridsize/3) && (j<=gridsize)) return 9;
  }
  
 //[MH] Parameters to give range of i,j for each Q of the 9Qs
var Q1=[0,gridsize/3,0,gridsize/3];
var Q2=[gridsize/3,2*gridsize/3,0,gridsize/3];
var Q3=[2*gridsize/3,gridsize,0,gridsize/3];
var Q4=[0,gridsize/3,gridsize/3,2*gridsize/3];
var Q5=[gridsize/3,2*gridsize/3,gridsize/3,2*gridsize/3];
var Q6=[2*gridsize/3,gridsize,gridsize/3,2*gridsize/3];
var Q7=[0,gridsize/3,2*gridsize/3,gridsize];
var Q8=[gridsize/3,2*gridsize/3,2*gridsize/3,gridsize];
var Q9=[2*gridsize/3,gridsize,2*gridsize/3,gridsize];

//[MH] Get a random location in each of the Qs

while (1<2)
{
var Q11=AB.randomIntAtoB (Q1[0],Q1[1] );
var Q12=AB.randomIntAtoB (Q1[2],Q1[3] );
if (!occupied(Q11,Q12)) break; 
}

while (1<2)
{
var Q21=AB.randomIntAtoB (Q2[0],Q2[1] );
var Q22=AB.randomIntAtoB (Q2[2],Q2[3] );
if (!occupied(Q21,Q22)) break; 
}

while(1<2)
{
var Q31=AB.randomIntAtoB (Q3[0],Q3[1] );
var Q32=AB.randomIntAtoB (Q3[2],Q3[3] );
if (!occupied(Q31,Q32)) break; 
}

while(1<2)
{
var Q41=AB.randomIntAtoB (Q4[0],Q4[1] );
var Q42=AB.randomIntAtoB (Q4[2],Q4[3] );
if (!occupied(Q41,Q42)) break; 
}

while(1<2)
{
var Q51=AB.randomIntAtoB (Q5[0],Q5[1] );
var Q52=AB.randomIntAtoB (Q5[2],Q5[3] );
if (!occupied(Q51,Q52)) break; 
}

while(1<2)
{
var Q61=AB.randomIntAtoB (Q6[0],Q6[1] );
var Q62=AB.randomIntAtoB (Q6[2],Q6[3] );
if (!occupied(Q61,Q62)) break; 
}

while(1<2)
{
var Q71=AB.randomIntAtoB (Q7[0],Q7[1] );
var Q72=AB.randomIntAtoB (Q7[2],Q7[3] );
if (!occupied(Q71,Q72)) break; 
}

while(1<2)
{
var Q81=AB.randomIntAtoB (Q8[0],Q8[1] );
var Q82=AB.randomIntAtoB (Q8[2],Q8[3] );
if (!occupied(Q81,Q82)) break; 
}

while(1<2)
{
var Q91=AB.randomIntAtoB (Q9[0],Q9[1] );
var Q92=AB.randomIntAtoB (Q9[2],Q9[3] );
if (!occupied(Q91,Q92)) break; 
}


//[MH] Decision the End target for the mind A* Based on enemy and agent location on the gird
if (quarter(ei,ej)==1) end2=GRIDMIND[Q91][Q92];
if (quarter(ei,ej)==3) end2=GRIDMIND[Q71][Q72];
if (quarter(ei,ej)==7) end2=GRIDMIND[Q31][Q32];
if (quarter(ei,ej)==9) end2=GRIDMIND[Q11][Q12];

if (quarter(ei,ej)==2)
{
   if (quarter(ai,aj)==1 || quarter(ai,aj)==4 || quarter(ai,aj)==7) end2=GRIDMIND[Q71][Q72]; 
   if (quarter(ai,aj)==3 || quarter(ai,aj)==6 || quarter(ai,aj)==9) end2=GRIDMIND[Q91][Q92];
   if (quarter(ai,aj)==2 || quarter(ai,aj)==5 || quarter(ai,aj)==8) end2=GRIDMIND[Q71][Q72]; 
}
    
if (quarter(ei,ej)==4)
{
   if (quarter(ai,aj)==1 || quarter(ai,aj)==2 || quarter(ai,aj)==3) end2=GRIDMIND[Q31][Q32];
   if (quarter(ai,aj)==7 || quarter(ai,aj)==8 || quarter(ai,aj)==9) end2=GRIDMIND[Q91][Q92];
   if (quarter(ai,aj)==4 || quarter(ai,aj)==5 || quarter(ai,aj)==6) end2=GRIDMIND[Q31][Q32];

}
 
 
if (quarter(ei,ej)==6)
{
   if (quarter(ai,aj)==1 || quarter(ai,aj)==2 || quarter(ai,aj)==3) end2=GRIDMIND[Q11][Q12];
   if (quarter(ai,aj)==7 || quarter(ai,aj)==8 || quarter(ai,aj)==9) end2=GRIDMIND[Q71][Q72]; 
   if (quarter(ai,aj)==4 || quarter(ai,aj)==5 || quarter(ai,aj)==6) end2=GRIDMIND[Q11][Q12];

} 



if (quarter(ei,ej)==8)
{
   if (quarter(ai,aj)==1 || quarter(ai,aj)==4 || quarter(ai,aj)==7) end2=GRIDMIND[Q11][Q12];
   if (quarter(ai,aj)==3 || quarter(ai,aj)==6 || quarter(ai,aj)==9) end2=GRIDMIND[Q31][Q32];
   if (quarter(ai,aj)==2 || quarter(ai,aj)==5 || quarter(ai,aj)==8) end2=GRIDMIND[Q11][Q12];

}
    
if (quarter(ei,ej)==5)
{
    
    //[MH] if enemy is in center of grid , go around the grid from Q2 to Q3 to Q6 to Q7 to Q9 to Q8 to Q9 to Q6
    
      if (quarter(ai,aj)==1) end2=GRIDMIND[Q21][Q22];
      if (quarter(ai,aj)==2) end2=GRIDMIND[Q31][Q32];
      if (quarter(ai,aj)==3) end2=GRIDMIND[Q61][Q62];
      if (quarter(ai,aj)==4) end2=GRIDMIND[Q71][Q72];
      if (quarter(ai,aj)==6) end2=GRIDMIND[Q91][Q92];
      if (quarter(ai,aj)==7) end2=GRIDMIND[Q81][Q82];
      if (quarter(ai,aj)==8) end2=GRIDMIND[Q91][Q92];
      if (quarter(ai,aj)==9) end2=GRIDMIND[Q61][Q62];
      if (quarter(ai,aj)==5) 
      {
      
      //[MH] if both enemy and agent are in center of grid , choose next Q to start with based on location of enemy and agent
      if (ai<ei && aj<ej) end2= GRIDMIND[Q11][Q12];
      if (ai<ei && aj>ej) end2= GRIDMIND[Q71][Q72];
      if (ai>ei && aj>ej) end2= GRIDMIND[Q91][Q92];
      if (ai>ei && aj<ej) end2= GRIDMIND[Q31][Q32];
      if (ai<ei) end2= GRIDMIND[Q41][Q42];
      if (ai>ei) end2= GRIDMIND[Q61][Q62];
      if (aj<ej) end2= GRIDMIND[Q21][Q22];
      if (aj>ej) end2= GRIDMIND[Q81][Q82];
    
      }
}

//[MH] Start A* with agent location
    openSet2.push(start2);

// [MH] Clear values of A*
for ( var i = 0; i < gridsize ; i++ )
{
    for ( var j = 0; j < gridsize ; j++ )
    {
      GRIDMIND[i][j].g=0;
	  GRIDMIND[i][j].f=0;
	  GRIDMIND[i][j].h=0;
	  GRIDMIND[i][j].previou=undefined;
    }
}	  

//[MH] Define enemy spot on grid with value 3
GRIDMIND[ei][ej].value=3;

//[MH] A* Algorithm start
while (openSet2.length > 0) 
  {
     
    // Best next option
    var winner2 = 0;
    
   for (var i = 0; i < openSet2.length; i++) 
      if (openSet2[i].f < openSet2[winner2].f) 
        winner2 = i;
        
    var current2 = openSet2[winner2];
    // Did I finish?
    if (current2 === end2) 
    {
    console.log("success - found path2");
    break;
    }

    // Best option moves from openSet to closedSet
    removeFromArray(openSet2, current2);
    closedSet2.push(current2);
    // Check all the neighbors
    var neighbors2 = current2.neighbors;

    //--- start of for loop -----------
    for (var i = 0; i < neighbors2.length; i++) 
    {
      var neighbor2 = neighbors2[i];
      // Valid next spot?
        if (!closedSet2.includes(neighbor2) && (neighbor2.value)!==2 && (neighbor2.value)!==1 && (neighbor2.value)!==3)   // [MH] Discard walls and mazes and enemy 
        {
        var tempG2 = current2.g + heuristic(neighbor2, current2);
        // Is this a better path than before?
        var newPath2 = false;
        if (openSet2.includes(neighbor2)) 
        {
          if (tempG2 < neighbor2.g) 
          {
            neighbor2.g = tempG2;
            newPath2 = true;
          }
        }
        else 
        {
          neighbor2.g = tempG2;
          newPath2 = true;
          openSet2.push(neighbor2);
        }
        // Yes, it's a better path
        if (newPath2 == true) 
        {
          neighbor2.h = heuristic(neighbor2, end2);
          neighbor2.f = neighbor2.g + neighbor2.h;
          neighbor2.previou = current2;
        }
        }
    }
  }
 
 //[MH] Get Path from Agent to Grid random location (end2)
  var path2 = [];
  var temp2 = current2;
  path2.push(temp2);
  while (temp2.previou) 
  {
    path2.push(temp2.previou);
    temp2 = temp2.previou;
  }
  si=path2[path2.length-2].i;   //[MH] new location for agent , Lenght-2 to discard myself otherwise will not move
  sj=path2[path2.length-2].j;   //[MH] new location for agent , Lenght-2 to discard myself otherwise will not move
  if (si<ai) return 0;
  if (si>ai) return 1;
  if (sj<aj) return 3;
  if (sj>aj) return 2;
  else return AB.randomIntAtoB (0,3);
 
 	}
 		
 		
 		
	};