LatamQChallenge: Ordenando por división y nivel

Muestro una solución para ordenar por tier, rank, league points y winrate

hace 2 años   •   3 min de lectura

Por Andrés Tuñón
Hangover meme

Por si no recuerdan o no están enterados, estoy armando un proyecto llamado LatamQChallenge donde  desarrollo múltiples funcionalidades, puedes ver todo mi progreso el siguiente enlace:

LatamQChallenge
Este es un sitio en el cual puedes ver las estadísticas de los streamers que competirán en el evento LatamQChallenge.

Esta ocasión mostraré el análisis de la funcionalidad de Ranking para que los espectadores puedan saber quién va ganando el evento.

Funcionalidad

La funcionalidad consiste en mostrar una tabla de Ranking ordenado por división y winrate; es decir, que siga el orden que conocen todos los jugadores de LOL:

Divisiones de LOL
Divisiones de LOL

Cada división tiene 4 niveles y para subir de nivel debes ganar 99 LPS, excepto para las 3 últimas divisiones.

Problema

Ya tengo programada la parte donde consulto las estadísticas y las guardo en la base de datos, bastante sencillo.

Estadísticas del jugador
Estadísticas del jugador

El problema surge cuando tenga que desplegar los participantes en la tabla por orden; ya que, no es numérico y por lo tanto no tiene un orden, debo buscar la forma de como ordenarlo.

Solución

Primero me percaté que si juntamos la división y el nivel son contiguos, logrando un orden lógico:

TIER RANK value
NORANK 0
IRON IV 1
IRON III 2
IRON II 3
IRON I 4
BRONZE IV 5
BRONZE III 6
BRONZE II 7
BRONZE I 8
SILVER IV 9
... ... ...

¿Notaste algún patrón? ¡Sí lo hay!

Si me fijo solo en el salto entre divisiones (tier), los niveles (rank) siempre son 4, por lo tanto puedo simplificarlo del siguiente modo:

TIER value
NORANK 0
IRON 1
BRONZE 5
SILVER 9

y si omito NORANK siempre es una diferencia de 4, pero luego explicaré porque no lo simplifiqué hasta ese punto. Este seria el tierOffset.

Si resuelvo el valor de cada rank en este contexto, seria restar el valor de las tablas anteriores.

Por ejemplo, si quiero saber cuanto debe ser rank para encontrar BRONZE II, la ecuación seria:

III = BRONZE III - BRONZE
III = 6 - 5
III = 1

Igual lo podrías ver navegando por la tabla, este sería el rankOffset

Hay un detalle adicional, hay unas 3 divisiones finales que se manejan distinto:

TIER RANK value
... ... ...
MASTER I 25
GRANDMASTER I 25
CHALLENGER I 25

Realmente el salto entre estas divisiones es por LPS y no se reinicia por lo que toma mayor relevancia; es decir:

DIAMOND I a MASTER I con 0 LPS
MASTER I a GRANDMASTER I con 350 LPS
GRANDMASTER I a CHALLENGER I con 500 LPS

(son ejemplos)

Sin contar que debo buscar la forma de que un DIAMOND II con 97 LPS sea mayor a un DIAMOND II con 46 LPS sin dañar la ecuación previa. Para esto me apoyaré de los decimales.

La ecuación resultante fue esta:

(tierOffset + rankOffset + lps/1000)

Divido entre 1000 para evitar que entre las divisiones comunes, la parte entera sea afectada.

Ya si un CHALLENGER llega a 1000 LPS me da igual que se afecte el entero porque no hay ninguna otra división, además de que seria raro en LAN la verdad.

Pruebas

Realicé pruebas exhaustivas; ya que es muy importate que se el valor se calcule correctamente y parece funcionar todo bien:

pruebas en jest
pruebas en jest

Puntos Finales

Cabe destacar que estoy usando una librería que evita el problema del 0.1 + 0.2 != 0.3 para un cálculo preciso en js.

La parte del winrate la utilizaré para decidir en caso de empate, debo especificarlo en las reglas y la ecuación es la de promedio:

wins / (wins + loses)

Corre la voz

Sigue leyendo