Tengo una aplicación que premia al usuario según la cantidad de entradas realizadas.
Luego repite el ciclo para siempre, siempre en múltiplos de 10.
1-9 debería mostrarse en progreso para cada nivel, y cada décima entrada comienza el siguiente nivel. 1 es 10 %, 9 es 90 % y, en lugar de mostrar 100 %, vaya directamente al siguiente nivel.
Muestro una barra de progreso para el nivel actual, un porcentaje de completado para el nivel actual, el ícono del nivel al que se dirige el usuario. Todos los que actualmente se muestran correctamente.
El problema al que me enfrento es que también muestro un recuento para cada nivel, que solo es correcto hasta 44 entradas inclusive. El 45 es donde las cosas empiezan a ir mal.
Consulte lo siguiente o en jsfiddle y siéntase libre de editar.
const DENOMINATOR = 10; const clamp = (value: number, min: number, max: number): number => { return Math.min(Math.max(value, min), max); } const calculateAwardsByEntryCount = (count: number) => { const maxLevels = 3 * DENOMINATOR; const modulus = count % maxLevels; const currentLevel = Math.max(0, Math.floor(modulus / DENOMINATOR) - 1); const nextLevel = Math.min(3, currentLevel + 1); const prestige = Math.ceil((count + 1) / maxLevels); const progress = ((modulus - DENOMINATOR * nextLevel) / DENOMINATOR) * 100; let bronze = 0; let silver = 0; let gold = 0; if (count >= DENOMINATOR) { bronze = count <= maxLevels ? 1 : Math.floor(modulus / (DENOMINATOR - 1)) * prestige; } if (count >= DENOMINATOR * 2 && bronze > 0) { silver = count <= maxLevels ? 1 : clamp(Math.ceil(modulus / (DENOMINATOR * 2 - 1)) * prestige, 0, bronze + 1); } if (count >= DENOMINATOR * 3 && silver > 0) { gold = count <= maxLevels ? 1 : clamp(Math.ceil((modulus / (DENOMINATOR * 3 - 1)) * prestige), 0, silver + 1); } return { achieved: {bronze, silver, gold}, currentLevel, nextLevel, progress, } } console.log(calculateAwardsByEntryCount(45));No es exactamente la solución más eficiente, pero al menos es 100% precisa para cualquier número de entradas.
const DENOMINATOR = 10; const calculateAwardsByEntryCount = (count: number) => { let remainingProgress = count; let currentLevel = null; let bronze = 0; let silver = 0; let gold = 0; for (remainingProgress; remainingProgress >= DENOMINATOR; remainingProgress -= DENOMINATOR) { switch (currentLevel) { case 1: currentLevel = 2; gold += 1; break; case 0: currentLevel = 1; silver += 1; break; default: currentLevel = 0; bronze += 1; break; } } if (currentLevel === null) { currentLevel = -1 } const progress = (remainingProgress / DENOMINATOR) * 100; const nextLevel = currentLevel === 2 ? 0 : currentLevel + 1; return { achieved: { bronze, silver, gold }, nextLevel, progress, }; } console.log(calculateAwardsByEntryCount(9)); console.log(calculateAwardsByEntryCount(10)); console.log(calculateAwardsByEntryCount(20)); console.log(calculateAwardsByEntryCount(30)); console.log(calculateAwardsByEntryCount(35)); console.log(calculateAwardsByEntryCount(45)); console.log(calculateAwardsByEntryCount(55)); console.log(calculateAwardsByEntryCount(65)); console.log(calculateAwardsByEntryCount(75));