verbs/forage.js
26 lines · in natura-src-1.0.0.zip as natura/verbs/forage.js · a module · its entry in the module reference
// verbs/forage.js -- ONE life ontology verb, one concern: move toward the best LOCAL source of a resource when you
// need it. Pure and RENDER-FREE. Universal -- a butterfly seeks nectar, a monkey a fruiting tree, a bat an insect
// swarm, a snail an algal patch, a grazer fresh grass: the entity supplies WHAT the resource is and HOW it moves;
// this supplies WHICH source, scored richest-over-nearest (a full source right here beats a fuller one far off). UMD.
(function (root, factory) {
if (typeof module !== 'undefined' && module.exports) module.exports = factory();
else (root.NaturaVerbs = root.NaturaVerbs || {}).forage = factory();
})(typeof self !== 'undefined' ? self : this, function () {
'use strict';
// forage(pos, sources, opts) -> { target: bestSource|null, dist, atSource }
// pos = {x,y} ; sources = [{x,y,amount}] ; opts = { reach:0.03 (AT it), min:0.05 (ignore below) }
// null target = nothing worth going to (the caller wanders / rests instead).
function forage(pos, sources, opts) {
opts = opts || {};
const reach = opts.reach != null ? opts.reach : 0.03, min = opts.min != null ? opts.min : 0.05;
let best = null, bestScore = -1, bd = Infinity;
for (let i = 0; i < sources.length; i++) {
const s = sources[i], amt = s.amount || 0; if (amt <= min) continue;
const dx = s.x - pos.x, dy = s.y - pos.y, d = Math.sqrt(dx * dx + dy * dy);
const score = amt / (0.04 + d); // richest AND nearest wins
if (score > bestScore) { bestScore = score; best = s; bd = d; }
}
return { target: best, dist: bd, atSource: best != null && bd <= reach };
}
return { forage };
});