Source: utils.js

/**
 * @fileOverview Implementation of various helper functions which do not
 *               fit anywhere else.
 */

/**
 * @summary Emits data on the system console/on-screen warnings.
 * @param output {Object} An object to be shown to the developer.
 *                        Is automatically converted to JSON-like
 *                        notation.
 * @see API3.DebugEnabled
 * @return undefined
 */
API3.debug = function(output)
{
	if (API3.DebugEnabled)
	{
		if (typeof output === "string")
			warn(output);
		else
			warn(uneval(output));
	}
};

/**
 * @summary Emits a warning message to the console.
 * @description While the basic JavaScript <code>warn</code> function
 *              could be used to emit warnings, for a bot it is
 *              preferrable to use this function as it provides
 *              additional information on which component/player
 *              is having a problem.
 * @param output {Object} An object to be shown to the developer.
 *                        Is automatically converted to JSON-like
 *                        notation.
 * @return undefined
 */
API3.warn = function(output)
{
	if (typeof output === "string")
		warn("PlayerID " + PlayerID + " |   " + output);
	else
		warn("PlayerID " + PlayerID + " |   " + uneval(output));
};

/**
 * @summary Computes the euclidian distance of two points.
 * @param a {Array.<Number>} The first point.
 * @param b {Array.<Number>} The second point.
 * @return The euclidian distance between a and b, when treating the
 *         first two elements of the arrays as a two-dimensional
 *         position.
 * @see API3.SquareVectorDistance A faster alternative
 */
API3.VectorDistance = function(a, b)
{
	var dx = a[0] - b[0];
	var dz = a[1] - b[1];
	return Math.sqrt(dx*dx + dz*dz);
};

/**
 * @summary Computes the square of the euclidian distance of two
 *          points.
 * @description In many applications, such as sorting objects by
 *              distance to a common anchor point, it is not necessary
 *              to have the exact distance value as long as the
 *              results are compatible with the less-than/equal
 *              relation regarding the "real" distance. Since
 *              computation of square roots is expensive, this
 *              function may be used as a cheaper alternative to
 *              [VectorDistance]{@link API.VectorDistance}.
 * @param a {Array.<Number>} The first point.
 * @param b {Array.<Number>} The second point.
 * @return The square of the euclidian distance between a and b, when
 *         treating the first two elements of the arrays as a
 *         two-dimensional position.
 */
API3.SquareVectorDistance = function(a, b)
{
	var dx = a[0] - b[0];
	var dz = a[1] - b[1];
	return (dx*dx + dz*dz);
};

var API3 = function(m)
{

// A is the reference, B must be in "range" of A
// this supposes the range is already squared
m.inRange = function(a, b, range)// checks for X distance
{
	// will avoid unnecessary checking for position in some rare cases... I'm lazy
	if (a === undefined || b === undefined || range === undefined)
		return undefined;
	
	var dx = a[0] - b[0];
	var dz = a[1] - b[1];
	return ((dx*dx + dz*dz ) < range);
}
// slower than SquareVectorDistance, faster than VectorDistance but not exactly accurate.
m.ManhattanDistance = function(a, b)
{
	var dx = a[0] - b[0];
	var dz = a[1] - b[1];
	return Math.abs(dx) + Math.abs(dz);
}

m.AssocArraytoArray = function(assocArray) {
	var endArray = [];
	for (var i in assocArray)
		endArray.push(assocArray[i]);
	return endArray;
};

m.ShallowClone = function(obj)
{
	var ret = {};
	for (var k in obj)
		ret[k] = obj[k];
	return ret;
}

// Picks a random element from an array
m.PickRandom = function(list)
{
	if (list.length === 0)
		return undefined;
	else
		return list[Math.floor(Math.random()*list.length)];
};


// Utility functions for conversions of maps of different sizes
// It expects that cell size of map 1 is a multiple of cell size of map 2

// return the index of map2 with max content from indices contained inside the cell i of map1 
m.getMaxMapIndex = function(i, map1, map2)
{
	var ratio = map1.cellSize / map2.cellSize;
	var ix = (i % map1.width) * ratio;
	var iy = Math.floor(i / map1.width) * ratio;
	var index = undefined;
	for (var kx = 0; kx < ratio; ++kx)
		for (var ky = 0; ky < ratio; ++ky)
			if (!index || map2.map[ix+kx+(iy+ky)*map2.width] > map2.map[index])
				index = ix+kx+(iy+ky)*map2.width;
	return index;
};

// return the list of indices of map2 contained inside the cell i of map1 
// map1.cellSize must be a multiple of map2.cellSize
m.getMapIndices = function(i, map1, map2)
{
	var ratio = map1.cellSize / map2.cellSize;	// TODO check that this is integer >= 1 ?
	var ix = (i % map1.width) * ratio;
	var iy = Math.floor(i / map1.width) * ratio;
	var ret = [];
	for (var kx = 0; kx < ratio; ++kx)
		for (var ky = 0; ky < ratio; ++ky)
			ret.push(ix+kx+(iy+ky)*map2.width);
	return ret;
};

// return the list of points of map2 contained inside the cell i of map1 
// map1.cellSize must be a multiple of map2.cellSize
m.getMapPoints = function(i, map1, map2)
{
	var ratio = map1.cellSize / map2.cellSize;	// TODO check that this is integer >= 1 ?
	var ix = (i % map1.width) * ratio;
	var iy = Math.floor(i / map1.width) * ratio;
	var ret = [];
	for (var kx = 0; kx < ratio; ++kx)
		for (var ky = 0; ky < ratio; ++ky)
			ret.push([ix+kx, iy+ky]);
	return ret;
};

return m;

}(API3);

// -------------------------------------------------------------------
//  End of file
// -------------------------------------------------------------------