dc713b61356a8767ccbaf19746f6469b1cd8e557
[sketchy-heroes.git] / src / lib / weighted.ts
1 // given an array, will grab a weighted version of it
2 import { random } from 'lodash';
3 import { logger } from './logger';
4
5 export type Weighted = {
6   weight: number;
7 }
8
9 export function weighted<T>(options: T[], getWeight: (item: T) => number, weightPrecision: number = 100, defaultReturn?: T): T | undefined {
10   let maxWeight = 0;
11   let segments: {start: number, end: number, item: T}[] = [];
12
13   options.forEach(option => {
14     const start = maxWeight;
15     maxWeight += (getWeight(option) * weightPrecision)
16     const end = maxWeight;
17     segments.push({
18       start: start,
19       end: end,
20       item: option
21     });
22   });
23
24   const selection = random(0, 100);
25
26   logger.info({
27     random: selection,
28     maxWeight: maxWeight
29   }, 'random weighted selection for item');
30
31   if(selection >= maxWeight) {
32     // there's a chance that the player actually gest nothing!
33     return undefined;
34   }
35
36   const found = segments.find(segment => {
37     return segment.start <= selection && segment.end >= selection;
38   });
39
40   return found ? found.item : defaultReturn;
41 }