/**
* Enum for ActionType
* @readonly
* @enum {number}
*/
const ActionType = {
NONE : 0,
MOVE : 1,
HARVEST : 2,
ATTACK : 3,
TRANSFER: 4,
PHEROMONE: 5
};
/**
* Enum for DirectionType
* @readonly
* @enum {number}
*/
const DirectionType = {
FORWARD: 1,
BACKWARD: 2,
NONE: 3
};
/**
* Enum for PheromoneType
* @readonly
* @enum {number}
*/
const PheromoneType = {
NONE : 0,
ATTACK : 1,
DEFEND : 2,
FOOD : 3,
DANGER: 4
};
/**
* Enum for ObjectType
* @readonly
* @enum {number}
*/
const ObjectType = {
NONE : 0,
HIVE : 1,
FOOD : 2,
ANT : 3,
SPIDER : 4,
PHEROMONE : 5
};
const ShapeType = {
CIRCLE : 1,
SQUARE : 2,
RECTANGLE : 3
};
const AntType = {
SIMPLE: 0,
CUSTOM: 1
}
const HiveType = {
DEFAULT : 0,
CUSTOM : 1
}
const _FILL_STYLE_TABLE = ['#000000','#ff0000','#00ff00','#0000ff']; // Ant color per hive
/**
* Returns a random value between min and max.
* @param {number} min - Lower threshold.
* @param {number} max - Upper threshold.
* @return {number} random number.
*/
function rand(min, max){
return Math.random() * (max - min) + min;
}
/**
* Returns a number converted from radians to degree.
* @param {number} degree.
* @return {number} radians.
*/
function degToRad(degrees){
return degrees * Math.PI / 180;
}
/**
* Returns a number converted from degree to radians.
* @param {number} radians.
* @return {number} degree.
*/
function radToDeg(radians){
return radians * 180 / Math.PI;
}
/**
* Gets the distance between to points.
* @param {dict} Point a.
* @param {dict} Point b.
* @return {number} distance.
*/
function getDistance(a, b){
var dx = (a.x-b.x);
var dy = (a.y-b.y);
return Math.sqrt(dx*dx+dy*dy);
}
/**
* Gets the angle in radians between to vectors [-PI,PI].
* @param {dict} Vector a.
* @param {dict} Vector b.
* @return {number} angle in radians.
*/
function angleBetweenVectorsRad(fromVec, toVec){
// reference to math behind this: http://www.euclideanspace.com/maths/algebra/vectors/angleBetween/issues/index.htm
var nFromVec = normalize(fromVec);
var nToVec = normalize(toVec);
var angle = Math.atan2(nToVec.y,nToVec.x) - Math.atan2(nFromVec.y,nFromVec.x);
if (angle >= Math.PI)
angle -= Math.PI*2;
else if (angle <= -Math.PI)
angle += Math.PI*2;
return angle;
}
/**
* Gets the angle in degree between to vectors [-180,180].
* @param {dict} Vector a.
* @param {dict} Vector b.
* @return {number} angle in degree.
*/
function angleBetweenVectorsDeg(fromVec, toVec){
return radToDeg(angleBetweenVectorsRad(fromVec,toVec));
}
/**
* Rotates a vector by given radians.
* @param {dict} Vector.
* @param {number} Rotation given in radians.
* @return {dict} Rotated vector.
*/
function rotateVector(vec, radians)
{
var xNew = vec.x * Math.cos(radians) - vec.y * Math.sin(radians);
var yNew = vec.x * Math.sin(radians) + vec.y * Math.cos(radians);
return { x: xNew, y: yNew };
}
/**
* Gets the normalized vector.
* @param {dict} Vector.
* @return {dict} Normalized vector.
*/
function normalize(vec){
var length = getDistance({x:0,y:0}, vec);
var normalizedVec = {x: vec.x/length, y: vec.y/length};
return normalizedVec;
}
/**
* Gets the position inside a list of the maximum value.
* @param {list} List of numbers.
* @return {number} Position of the maximum value.
*/
function argmax(tlist) {
var max = -9e8;
var maxarg = -1;
for (var i = 0; i < tlist.length; ++i) {
if (tlist[i] > max) {
max = tlist[i];
maxarg = i;
}
}
return maxarg;
}
/**
* Gets the maximum value in a list.
* @param {list} List of numbers.
* @return {number} Maximum value.
*/
function maxElement(tlist) {
var max = -9e8;
for (var i = 0; i < tlist.length; ++i) {
if (tlist[i] > max) {
max = tlist[i];
}
}
return max;
}
function createEditor(elementID, defaultValue){
var antControllerWordCompleter = {
getCompletions: function(editor, session, pos, prefix, callback) {
var wordList = AntController.getAutoCompletionWordList();
callback(null, wordList.map(function(word) {
return {
caption: word,
value: word,
meta: "This ant"
};
}));
}
}
var globalWordCompleter = {
getCompletions: function(editor, session, pos, prefix, callback) {
var wordList = ["this."];
callback(null, wordList.map(function(word) {
return {
caption: word,
value: word,
meta: "global"
};
}));
}
}
ace.require("ace/ext/language_tools");
var customAntEditor = ace.edit(elementID);
customAntEditor.$blockScrolling = Infinity;
customAntEditor.setTheme("ace/theme/chrome");
customAntEditor.session.setMode("ace/mode/javascript");
customAntEditor.setOptions({
enableBasicAutocompletion: true,
enableLiveAutocompletion: true
});
customAntEditor.completers = [globalWordCompleter, antControllerWordCompleter];
customAntEditor.setValue(defaultValue, -1); // -1 set cursor to begin
return customAntEditor;
}