UNPKG

step-sequence-generator

Version:

A step sequence generator for figure skating programs

70 lines (69 loc) 3.61 kB
"use strict"; 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;