Recogida de datos competitivo League of Legends

Objetivo

El objetivo de este proyecto será el de conseguir un dataset explotable sobre el desempeño de un usuario cualquiera en el conocido videojuego LeagueofLegends.

Desarrollo

Para el desarrollo de este proyecto se hará uso de la API de riot games https://developer.riotgames.com/. Para hacer uso de la misma habrá que tener una cuenta en Rito Games y solicitar un token. En este sentido hay 3 tipos de tokens disponibles:

  1. Token de desarrollo: Se desactiva una vez transcurridas 24 horas y está pensada para hacer pequeños desarrollos con la API y realizar prototipos.
  2. Token personal: Pensado para pequeños trabajos personales que no requiere de una validación previa, aunque sí que habrá que proporcionar una descripción del fin de la misma. No caduca, pero tiene ciertas limitaciones.
  3. Token de producción: Permite realizar más consultas que los anteriores casos y está pensada para productos que se ofertarán a grandes comunidades y tendrán un gran tráfico.

En el marco de este proyecto se hará uso del caso 1, el token de desarrollo.

Resumen de los pasos:

  • Paso 1: Conectarse a la API
  • Paso 2: Conseguir el id de un jugador y sus principales datos
  • Paso 3: Recuperar la lista de ultimas partidas jugadas y tabular
  • Paso 4: Conseguir información de detallada de cada una de las partidas y tabular

Paso 1: Conectarse a la API

Para conectarse a la API de Riot con Python bastará con usar la librería riotwacher. En este sentido se cargarán LolWatcher y ApiError que servirán para realizar la conexión y el control de errores respectivamente. De manera adicional, se cargarán las librerías que usaremos a lo largo del proyecto.

from riotwatcher import LolWatcher, ApiError
import pandas as pd

Una vez hecho esto bastará con utilizar el siguiente comando para conectarnos a la API:

lol_watcher = LolWatcher(token)

Introduciendo el token solicitado en la variable token.

Paso 2: Conseguir el id de un jugador y sus principales datos

Una vez conectados a la API, el primer paso a realizar será el de conseguir la información básica del usuario del que queremos conseguir datos. En nuestro caso, recogeremos información del ganador del torneo de la comunidad, Endika.

Para ello tendremos que seleccionar la región en la que está jugando actualmente y realizar la siguiente consulta:

region = 'euw1'
usuario = lol_watcher.summoner.by_name(region, 'eendriuus9')
print(usuario)

Obteniendo así los distintos identificadores internos que usa Riot para este usuario:

Con estos identificadores se puede conseguir, por ejemplo, información sobre el nivel clasificatorio de los jugadores:

ranked = lol_watcher.league.by_summoner(region, usuario['id'])
print(ranked)

En este ejemplo podemos ver que Endika está en la división de plata en las dos colas clasificatorias actuales (soloQ y flexQ).

Paso 3: Recuperar la lista de ultimas partidas jugadas y tabular

Con los identificadores de usuario disponibles se puede solicitar a la API que de la informacion de las últimas partidas jugadas por dicho jugador:

Match_list = lol_watcher.match.matchlist_by_account(region,usuario["accountId"])

Una vez hecho esto, se puede crear un diccionario en el que se irán guardando los datos de las distintas partidas del historial guardadas en Match_list. Para ello iremos iterando partida a partida:

partidas = {"id_partida":[], "Champion":[],"queue":[],"season":[],"timestamp":[],"role":[],"lane":[]} 
for i in Match_list["matches"]:
    partidas["id_partida"].append(i["gameId"])
    partidas["Champion"].append(i["champion"])
    partidas["queue"].append(i["queue"])
    partidas["season"].append(i["season"])
    partidas["timestamp"].append(i["timestamp"])
    partidas["role"].append(i["role"])
    partidas["lane"].append(i["lane"])

Convirtiendo el diccionario resultante en DataFrame se obtendría lo siguiente:

df_partidas = pd.DataFrame(partidas)
df_partidas.head()

Paso 4: Conseguir información de detallada de cada una de las partidas y tabular

Para acabar, una vez conseguido el historial de partidas se puede recopilar los datos de cada una de esas partidas. Para ello, teniendo en cuenta que en cada partida participan 10 jugadores antes que nada hay que identificar que jugador de los devueltos por la llamada a la API es el objetivo del análisis. Con ese fin, bastará con comprobar que jugador utiliza el campeón correspondiente al usuario objetivo, información ya recogida en el paso anterior.

En este punto matizar que este ejemplo se centrará únicamente en las partidas clasificatorias disputadas por nuestro usuario objetivo y que habría que adaptar el diccionario en caso de querer recoger datos de las demás tipologías de partidas:

partida =  {"id_partida" : [], "fecha":[], "duracion":[],"version":[],"spell1Id":[],
"spell2Id":[],"Ganada":[],"item0":[],"item1":[],
"item2":[],"item3":[],"item4":[],"item5":[],"item6":[],
"kills":[],"assists":[],"deaths":[],"largestKillingSpree":[],
"largestMultiKill":[],"totalDamageDealt":[],"physicalDamageDealt":[],
"trueDamageDealt":[],"magicDamageDealt":[],"totalHeal":[],"totalDamageTaken":[],
"timeCCingOthers":[],"visionScore":[],"goldEarned":[],"goldSpent":[],
"totalMinionsKilled":[],"neutralMinionsKilled":[],"neutralMinionsKilledTeamJungle":[],
"neutralMinionsKilledEnemyJungle":[],"totalTimeCrowdControlDealt":[],
"wardsPlaced":[],"wardsKilled":[],"visionWardsBoughtInGame":[],"sightWardsBoughtInGame":[],
"role":[],"lane":[]}
for index, i in df_partidas.iterrows():
    part = str(i[0])
    camp = i[1]
    game = lol_watcher.match.by_id(region,part)
    tipo = game["queueId"]
    if tipo in [440,420]:
        partida["id_partida"].append(part)
        partida["fecha"].append(game["gameCreation"])
        partida["duracion"].append(game["gameDuration"])
        partida["version"].append(game["gameVersion"])

        pos = 0
        for j in game["participants"]:
            if j["championId"] == camp:
                break
            else:
                pos += 1
        resumen = game["participants"][pos]


        partida["spell1Id"].append(resumen["spell1Id"])
        partida["spell2Id"].append(resumen["spell2Id"])

        stats = resumen["stats"]
        partida["Ganada"].append(stats["win"])
        partida["item0"].append(stats["item0"])
        partida["item1"].append(stats["item1"])
        partida["item2"].append(stats["item2"])
        partida["item3"].append(stats["item3"])
        partida["item4"].append(stats["item4"])
        partida["item5"].append(stats["item5"])
        partida["item6"].append(stats["item6"])
        partida["kills"].append(stats["kills"])
        partida["deaths"].append(stats["deaths"])
        partida["assists"].append(stats["assists"])
        partida["largestKillingSpree"].append(stats["largestKillingSpree"])
        partida["largestMultiKill"].append(stats["largestMultiKill"])
        partida["totalDamageDealt"].append(stats["totalDamageDealt"])
        partida["physicalDamageDealt"].append(stats["physicalDamageDealt"])
        partida["trueDamageDealt"].append(stats["trueDamageDealt"])
        partida["magicDamageDealt"].append(stats["magicDamageDealt"])
        partida["totalHeal"].append(stats["totalHeal"])
        partida["totalDamageTaken"].append(stats["totalDamageTaken"])
        partida["timeCCingOthers"].append(stats["timeCCingOthers"])
        partida["visionScore"].append(stats["visionScore"])
        partida["goldEarned"].append(stats["goldEarned"])
        partida["goldSpent"].append(stats["goldSpent"])
        partida["totalMinionsKilled"].append(stats["totalMinionsKilled"])
        partida["neutralMinionsKilled"].append(stats["neutralMinionsKilled"])
        partida["neutralMinionsKilledTeamJungle"].append(stats["neutralMinionsKilledTeamJungle"])
        partida["neutralMinionsKilledEnemyJungle"].append(stats["neutralMinionsKilledEnemyJungle"])
        partida["totalTimeCrowdControlDealt"].append(stats["totalTimeCrowdControlDealt"])
        partida["wardsPlaced"].append(stats["wardsPlaced"])
        partida["wardsKilled"].append(stats["wardsKilled"])
        partida["visionWardsBoughtInGame"].append(stats["visionWardsBoughtInGame"])
        partida["sightWardsBoughtInGame"].append(stats["sightWardsBoughtInGame"])

        timeline = resumen["timeline"]
        partida["role"].append(timeline["role"])
        partida["lane"].append(timeline["lane"])

Convirtiendo el resultado en DataFrame obtendriamos:

Bonus

Como elemento adicional presentamos un simple gráfico realizado con la librería matplotlib del estado de forma actual del jugador analizado. En el mismo podemos ver el +/- de las ultimas partidas competitivas jugadas por el mismo.

Podemos decir que, a pesar de que parece estar remontando, no se encuentra en un momento positivo de forma.

Líneas futuras

Con esta base se podría:

  • Analizar «estado de forma» del jugador, perfilarlo e identificar puntos de mejora
  • Analizar las estadísticas base de los campeones utilizados por el jugador y detectar campeones adicionales para enriquecer su champion pool
  • Comparar los datos del jugador con jugadores de su categoría
top