step-sequence-generator
Version:
A step sequence generator for figure skating programs
70 lines (69 loc) • 3.61 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MovementChanceRatioMapGenerator = void 0;
const movement_enums_1 = require("../../shared/enums/movement-enums");
const is_extended_movement_character_1 = require("../../utils/is-extended-movement-character");
const round2_1 = require("../../utils/round2");
class MovementChanceRatioMapGenerator {
/**
* getChanceRatioMap
* @param args
* @param {Movement[]} args.movements массив движений
* @param {MovementChanceRatioMapType} args.rbPercentage базовый список шансов на выпадение элемента в процентах
*/
getChanceRatioMap(args) {
const { rbPercentage, movements } = args;
const groupMovementCounted = this.groupAndCountMovements(movements);
return this.calcChanceRatio(Array.from(groupMovementCounted.keys()), rbPercentage);
}
groupAndCountMovements(selection) {
const map = new Map();
for (let item of selection) {
const key = item.isDifficult
? movement_enums_1.ExtendedMovementCharacter.DIFFICULT
: (0, is_extended_movement_character_1.transformToExtendedMovementCharacterType)(item.type);
const value = map.get(key) || 0;
map.set(key, value + 1);
}
return map;
}
calcChanceRatio(movementCharacterInUse, chanceRatioMap) {
const actualChanceRatioMap = this.getActualChanceRatioMap(movementCharacterInUse, chanceRatioMap);
const percentSeparated = this.separatePercentByType(actualChanceRatioMap);
return this.redistributeChanceRatio(percentSeparated, actualChanceRatioMap);
}
getActualChanceRatioMap(charactersInUse, chanceRatioMap) {
const map = new Map();
for (const [key, percent] of chanceRatioMap.entries()) {
if (charactersInUse.includes(key)) {
map.set(key, percent);
}
}
return map;
}
separatePercentByType(actualChanceRatioMap) {
const HUNDRED_PERCENTAGE = 100;
// todo усовершенствовать для случаев, когда несколько элементов равны max
const values = Array.from(actualChanceRatioMap.values());
const max = Math.max(...values);
const total = values.reduce((sum, value) => sum + value, 0);
const used = max === total ? total : total - max;
const unused = HUNDRED_PERCENTAGE - total;
return { unusedPercent: unused, usedPercent: used };
}
redistributeChanceRatio(percentSeparated, actualChanceRatioMap) {
const map = new Map();
const { unusedPercent, usedPercent } = percentSeparated;
const maxPercent = Math.max(...actualChanceRatioMap.values());
// todo усовершенствовать для случаев, когда несколько элементов равны max
const redistributionFactor = usedPercent === 0 ? 0 : (0, round2_1.round2)(unusedPercent / usedPercent);
for (const [key, percent] of actualChanceRatioMap.entries()) {
const typedKey = (0, is_extended_movement_character_1.transformToExtendedMovementCharacterType)(key);
const shouldAdjust = usedPercent === maxPercent || percent < maxPercent;
const adjusted = shouldAdjust ? percent + percent * redistributionFactor : percent;
map.set(typedKey, adjusted);
}
return map;
}
}
exports.MovementChanceRatioMapGenerator = MovementChanceRatioMapGenerator;