@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
121 lines (88 loc) • 2.97 kB
JavaScript
import { seededRandom } from "../../../../../core/math/random/seededRandom.js";
import { GridCellAction } from "../../GridCellAction.js";
import { assert } from "../../../../../core/assert.js";
import { binarySearchHighIndex } from "../../../../../core/collection/array/binarySearchHighIndex.js";
import { number_compare_ascending } from "../../../../../core/primitives/numbers/number_compare_ascending.js";
/**
*
* @type {number[]}
*/
const evaluatedWeights = [];
export class CellActionSelectWeightedRandom extends GridCellAction {
/**
*
* @type {function}
* @private
*/
__random = seededRandom(0);
/**
*
* @type {WeightedGridCellAction[]}
*/
options = [];
/**
*
* @param {WeightedGridCellAction[]} options
* @returns {CellActionSelectWeightedRandom}
*/
static from(options) {
const r = new CellActionSelectWeightedRandom();
r.addManyOptions(options);
return r;
}
/**
*
* @param {WeightedGridCellAction[]} options
*/
addManyOptions(options) {
const n = options.length;
for (let i = 0; i < n; i++) {
const action = options[i];
this.addOption(action);
}
}
/**
*
* @param {WeightedGridCellAction} option
*/
addOption(option) {
assert.equal(option.isWeightedGridCellAction, true, 'option.isWeightedGridCellAction !== true');
this.options.push(option);
}
initialize(data, seed) {
this.__random.setCurrentSeed(seed);
const actions = this.options;
const n = actions.length;
for (let i = 0; i < n; i++) {
const weightedGridCellAction = actions[i];
weightedGridCellAction.initialize(data, seed);
}
}
execute(data, x, y, rotation) {
const elements = this.options;
const n = elements.length;
let totalWeight = 0;
for (let i = 0; i < n; i++) {
/**
*
* @type {WeightedGridCellAction}
*/
const weightedElement = elements[i];
/**
*
* @type {CellFilter}
*/
const weightFilter = weightedElement.weight;
const weightValue = weightFilter.execute(data, x, y, 0);
if (weightValue > 0) {
//if the weight is negative, we clamp it to 0
totalWeight += weightValue;
}
evaluatedWeights[i] = totalWeight;
}
const targetWeight = this.__random() * totalWeight;
const index = binarySearchHighIndex(evaluatedWeights, targetWeight, number_compare_ascending, 0, n - 1);
const targetElement = elements[index];
targetElement.action.execute(data, x, y, rotation);
}
}