Code viewer for Mind: Dungeon Floodfill Mind

See raw JS.


//Mind for dungeon world that uses floodfill to decide a path each turn
//and take 1 step along it.
//Mind has visibility of entire grid through getGrid function, probably not realistic.
//Mind avoids pathing through the enemy or walls.
//Mind paths pretty directly to the goal on most maps.
//Main limitation is the mind getting confused if the path is longer that 2*gridsize,
//this was deliberate as the alternative is skirting javascript's recursion limit 
//and taking longer than a second per move.
//Another limitation is that it'll just sit there if the enemy can trap
//the agent in a room with only one exit, but it's kinda an edge case, 
// i've enabled the random move in case that helps.
//gets about 6 bad steps on an average run before it makes it to the goal.

function Mind() { 


//--- public functions / interface / API ----------------------------------------------------------

    
	this.newRun = function()
	{
	};

	this.endRun = function()
	{
	};



	this.getAction = function ( x )		// x is an array of [ ai, aj, ei, ej, getGrid()->[GRID_BLANK, GRID_WALL, GRID_MAZE, GRID_GOAL, GRID] ]
	{ 
		var ai = x[0];
		var aj = x[1];
		var ei = x[2];
		var ej = x[3];
		var gi = x[4];
		var gj = x[5];
		var gridInfo = x[6]()
		var GRID_BLANK = gridInfo[0]
		var GRID_WALL = gridInfo[1];
		var GRID_MAZE = gridInfo[2]
		var GRID_GOAL = gridInfo[3]
		var GRID = gridInfo[4]
		var gridsize = GRID.length;
		
		//initialize array to hold square priority map.
		var goal_map = new Array(gridsize)
		for (var i = 0; i<gridsize; i++){
		    goal_map[i] = new Array(gridsize);
		    for(var j = 0; j<gridsize; j++){
		        goal_map[i][j]==undefined;
		    }
		};
		
		var v = function filltoGoal( priority, i, j){
		   //turns goal map into an array of distances to the goal;
		   if (goal_map===undefined) return console.log('great');
		   if(priority<=0 || i<=0 || j<=0 || i>=gridsize || j>=gridsize ||GRID[i]==undefined || GRID[i][j]===undefined) {
		        return;//probably shouldn't recurse too deep or off the map.
		   }
		   
		   if ( GRID[i][j]===GRID_MAZE || GRID[i][j]===GRID_WALL || (i===ei&&j===ej) ){
		       goal_map[i][j] = 0; //don't wanna go here, ever, no thanks.
		       return;
		   }
		   
		   if(goal_map[i][j]>=priority ){
		       return; //already mapped.
		   }
		   
		    
		   //set this gridsquare's priority.
		   goal_map[i][j] = priority;
		    
		   //recursively floodfill to neighbouring squares
		   filltoGoal(priority-1, i+1, j);
		   filltoGoal(priority-1, i, j+1);
		   filltoGoal(priority-1, i-1, j);
		   filltoGoal(priority-1, i, j-1);
		
		   return;//done
		}(gridsize*2, gi, gj);
		
		//figure out out direct neighbour squares, zero rate them if they aren't mapped.
		var neighbours = [ 
		    goal_map[ai+1][aj] || 0,
		    goal_map[ai-1][aj] || 0,
		    goal_map[ai][aj+1] || 0,
		    goal_map[ai][aj-1] || 0,
		 ]
		 
		 console.log(neighbours)
		 
		 //find best neighbour
		 var goto = Math.max.apply(null, neighbours);
         if (goto!==undefined && goto!==0) 
         {//go there if we can
            if ( neighbours[0]===goto ) 	return ( ACTION_RIGHT ); 
		    if ( neighbours[1]===goto ) 	return ( ACTION_LEFT ); 
		    if ( neighbours[2]===goto ) 	return ( ACTION_UP ); 
		    if ( neighbours[3]===goto ) 	return ( ACTION_DOWN );
         }

         //return ACTION_STAYSTILL; 
         //otherwise jitter around until the way opens up on it's own, this bot is a believer.
 		 return  ( randomintAtoB (0,3) );
	};



}