Categorías
Informática Universitario Videojuego

Ejercicios

Estos son algunos ejercicios que pueden realizarse para practicar lo aprendido en el tema de Introducción, sobre programación en Python y conceptos fundamentales del Aprendizaje Automático y la Minería de Datos.

⚠️Salvo que se indique lo contrario, estos ejercicios pueden resolverse en condiciones de prueba final, esto es, examen individual en el laboratorio, sin acceso a Internet y sin usar IA generativa. Tan sólo hace falta la plantilla o el contexto que proporcione el profesor junto al enunciado, y un servidor de lenguaje como Pylance que viene por defecto en la extensión oficial de Python para Visual Studio Code y que permite explorar la documentación del API.

  1. Escribe un programa que cree un archivo telemetria_partidas.csv con encabezados (jugador_id, tiempo_jugado_min, kills, resultado). Genera al menos 5 filas de datos ficticios. A continuación, lee el archivo línea a línea procesándolo manualmente con cadenas de texto para calcular la proporción global de partidas ganadas vs. perdidas (el llamado Win Rate).
# Ej. de fila: P01,15,3,victoria

# Generación del archivo 'telemetria_partidas.csv' línea a línea
with open("telemetria_partidas.csv", "w", encoding="utf-8") as f:
    f.writelines(datos_iniciales)

# Lectura del archivo 'telemetria_partidas.csv' línea a línea
with open("telemetria_partidas.csv", "r", encoding="utf-8") as f:
    lineas = f.readlines()

# Limpieza de saltos de línea (\n), retornos de carro (\r) y espacios sobrantes
linea_limpia = linea.strip()

# Separación de campos usando la coma como delimitador
campos = linea_limpia.split(",")
  1. La API de un servidor devuelve una cadena en formato JSON con el equipamiento (loadout) de un personaje (armas, durabilidad y tipo de daño). Usa la biblioteca nativa json para procesar la cadena (crea un fichero ficticio para hacer pruebas), modifica la durabilidad de un objeto tras -supuestamente- usarlo en combate y vuelve a exportar el perfil del personaje a JSON estructurado.
# Ej. de cadena JSON: '{"personaje": "Guerrero", "loadout": [{"arma": "Espada", "durabilidad": 100, "tipo_daño": "físico"}]}'

import json

# Lectura/conversión de datos desde cadena JSON a diccionario de Python (o carga de archivo con json.load)
# datos = json.loads(cadena_json)

# Modificación de un campo interno (ej. reducir la durabilidad tras un combate)
# datos["loadout"][0]["durabilidad"] -= 15

# Exportación y formateo de nuevo a formato JSON estructurado (usar indent=4 para legibilidad)
# json_resultado = json.dumps(datos, indent=4, ensure_ascii=False)
  1. Tienes una lista de mensajes del chat de una partida con datos corruptos o inconclusos (ej: [» GG WP «, «100», «0.8»], [«AFK», «DESCONECTADO», «ERROR»], [» hacker «, «12», «0.99»]). Crea una función que limpie los espacios, filtre los mensajes nulos, erróneos o desconectados y convierta las puntuaciones de probabilidad de spam/toxicidad a números decimales válidos.
# Ej. de lista de entrada: [["  GG WP  ", "100", "0.8"], ["AFK", "DESCONECTADO", "ERROR"], [" hacker ", "12", "0.99"]]

# Filtrado de elementos no válidos y conversión de tipos
def limpiar_y_filtrar_mensajes(chat_log):
    mensajes_limpios = []
    
    for mensaje in chat_log:
        # Extracción y limpieza de espacios en cada campo
        # texto = mensaje[0].strip()
        # prob_str = mensaje[2].strip()
        
        # Comprobación de condiciones de descarte/error (ej. palabra clave o conversión fallida)
        # try:
        #     probabilidad = float(prob_str)
        #     mensajes_limpios.append((texto, probabilidad))
        # except ValueError:
        #     continue

    return mensajes_limpios
  1. Dada una lista con el daño infligido por un hechizo en 20 combates, tenemos este script en Python que calcula el daño medio, la mediana de daño y la varianza.
    Al observar los resultados devueltos por el programa, se aprecia una discrepancia notable entre el valor de la media y el de la mediana, ¿a qué se debe esto?
    Si como diseñador tuvieras que decidir si aplicar un buff o un nerf a la habilidad basándote en el comportamiento habitual de la mayoría de combates, ¿qué métrica resulta más fiable en este caso concreto y por qué?
datos_daño = [120, 115, 118, 122, 125, 119, 500, 121, 117, 123]

media = sum(datos_daño) / len(datos_daño)
datos_ord = sorted(datos_daño)
mediana = datos_ord[len(datos_ord)//2]
varianza = sum((x - media)**2 for x in datos_daño) / len(datos_daño)

print(f"Media: {media:.1f} | Mediana: {mediana:.1f} | Varianza: {varianza:.1f}")
  1. Representa las coordenadas (x, y, z) de 3 enemigos como una matriz de 3 x 3 usando listas anidadas. Escribe una función que aplique un vector de traslación (ej. mover a todos los enemigos 2 unidades en X y -1 en Z) y otra función que calcule el producto escalar para medir la alineación del personaje con la mirada de un guardia.
# Ej. de matriz 3x3 de enemigos (x, y, z): 
# posiciones = [[1.0, 0.0, 3.0], [-2.0, 1.0, 5.0], [4.0, 0.0, 1.0]]

# Traslación de coordenadas aplicando offset (dx, dy, dz)
def trasladar_posiciones(matriz_pos, vector_traslacion):
    # Recorrer cada enemigo (fila) y sumar elemento a elemento (dx, dy, dz)
    # nueva_matriz = [[coord + offset for coord, offset in zip(enemigo, vector_traslacion)] for enemigo in matriz_pos]
    pass

# Producto escalar entre dos vectores tridimensionales (v1 · v2 = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2])
def producto_escalar(v1, v2):
    # resultado = sum(a * b for a, b in zip(v1, v2))
    pass
  1. Durante una partida, el motor del juego registra en una lista cada acción destacada que realiza el jugador (ej. [«baja», «baja», «curacion», «baja», «headshot», «curacion»]). Escribe un programa en Python puro que:
    – Recorra la lista y use un diccionario de Python para contar cuántas veces ha ocurrido cada tipo de acción.
    – Calcule el porcentaje que representa cada acción sobre el total de eventos de la partida.
    – Muestre el resultado en texto (ej: {«baja»: 3, «curacion»: 2, «headshot»: 1}).
# Ej. de lista de acciones: acciones = ["baja", "baja", "curacion", "baja", "headshot", "curacion"]

# Conteo y frecuencias relativas mediante diccionarios
frecuencias = {}

# 1. Recorrido para acumular apariciones
# for accion in acciones:
#     frecuencias[accion] = frecuencias.get(accion, 0) + 1

# 2. Cálculo del porcentaje sobre el total
# total_eventos = len(acciones)
# porcentajes = {accion: (conteo / total_eventos) * 100 for accion, conteo in frecuencias.items()}
  1. Tenemos una lista de 100 partidas grabadas (replays) para entrenar una IA. Dado este programa que prepara la lista para que la IA aprenda a jugar, identifica los dos problemas metodológicos que tiene y resuélvelos para que todas las ejecuciones sean iguales y las particiones de datos sean correctas.
import random

replays = [f"replay_{i}.dat" for i in range(100)]
random.shuffle(replays)   

train_set = replays[:80]
test_set  = replays[70:]   

Esta página está licenciada bajo CC BY-NC-SA 4.0 por Laboratorios Narratech.