X-Git-Url: https://git.xangelo.ca/?p=sketchy-heroes.git;a=blobdiff_plain;f=src%2Flib%2Fweighted.ts;fp=src%2Flib%2Fweighted.ts;h=dc713b61356a8767ccbaf19746f6469b1cd8e557;hp=0000000000000000000000000000000000000000;hb=b5d3cc37fddebff8dcdf1ef0cdd3a626811f14d3;hpb=20dc560a75cfd6ddc8a66956315a30001779ec24 diff --git a/src/lib/weighted.ts b/src/lib/weighted.ts new file mode 100644 index 0000000..dc713b6 --- /dev/null +++ b/src/lib/weighted.ts @@ -0,0 +1,41 @@ +// given an array, will grab a weighted version of it +import { random } from 'lodash'; +import { logger } from './logger'; + +export type Weighted = { + weight: number; +} + +export function weighted(options: T[], getWeight: (item: T) => number, weightPrecision: number = 100, defaultReturn?: T): T | undefined { + let maxWeight = 0; + let segments: {start: number, end: number, item: T}[] = []; + + options.forEach(option => { + const start = maxWeight; + maxWeight += (getWeight(option) * weightPrecision) + const end = maxWeight; + segments.push({ + start: start, + end: end, + item: option + }); + }); + + const selection = random(0, 100); + + logger.info({ + random: selection, + maxWeight: maxWeight + }, 'random weighted selection for item'); + + if(selection >= maxWeight) { + // there's a chance that the player actually gest nothing! + return undefined; + } + + const found = segments.find(segment => { + return segment.start <= selection && segment.end >= selection; + }); + + return found ? found.item : defaultReturn; +}