Saltar al contenido
Volver al inicio 100 Días de Código en Python — Día 94: Proyecto de portafolio — Un bot que juega al dinosaurio de Chrome

100 Días de Código en Python — Día 94: Proyecto de portafolio — Un bot que juega al dinosaurio de Chrome

Nivel: Grado décimo Área: Tecnología e Informática Modalidad: Tutorial práctico Fuente: Curso "100 Days of Code: The Complete Python Pro Bootcamp" (Angela Yu, App Brewery). Contenido del Día 94, proyecto de portafolio profesional (categoría GUI Automation).

Este tutorial adapta pedagógicamente el Día 94. La sección 📝 Contenido original del curso proviene del único archivo de la carpeta: dia94-tarea13.md (enunciado y pregunta de reflexión, en inglés; aquí traducido). El curso no ofrece guía ni solución, y este tutorial no entrega el bot terminado. Todo lo que no está en ese archivo (ciclo percibir–decidir–actuar, detección por píxeles verificada, calibración, seguridad de la automatización, uso responsable, retos 🟢🟡🟠🔴, proyecto extra y la etapa 13 de Mi Portafolio Profesional) es creación de esta adaptación.

Nota sobre las verificaciones: el 28 de septiembre de 2026, con Python 3.14, Pillow 12.3.0 y NumPy 2.5.3, se ejecutaron las funciones de detección de la sección 4 sobre imágenes sintéticas que imitan el juego (fondo claro con y sin un "cactus"): detectan el obstáculo correctamente. También se comprobó que en el modo noche (fondo oscuro) la detección simple da un falso positivo, que Image.getdata() está obsoleto en Pillow 12 (se eliminará en Pillow 14) y que la versión con NumPy fue unas 14 veces más rápida en una región de 600 × 150. La parte que controla el teclado y captura la pantalla (pyautogui, ImageGrab) no se ejecutó: requiere una pantalla real con el juego abierto.


Tabla de contenidos

  1. La tarea: automatizar el juego del T-rex
  2. Analizar el problema: percibir, decidir, actuar
  3. 📖 Percibir: capturar la pantalla y encontrar la zona de peligro
  4. 📖 Decidir: ¿hay un obstáculo?
  5. 📖 Actuar con seguridad: pyautogui
  6. 🚀 Proyecto del día: construcción por versiones
  7. 🌟 Proyecto extra: automatizar una tarea repetitiva del computador
  8. 🏗️ Mi Portafolio Profesional — Etapa 13
  9. 🧩 Comprueba lo aprendido
  10. 🤖 Programar con apoyo de IA
  11. 🛠️ Observaciones sobre el material original
  12. 📋 Matriz de trazabilidad
  13. 📦 Evidencias de aprendizaje del Día 94

1. La tarea: automatizar el juego del T-rex

(Fuente: dia94-tarea13.md)

📝 Contenido original del curso

En Chrome, cuando intentas entrar a un sitio y no hay internet, ves un pequeño dinosaurio (aparentemente porque los dinosaurios tienen brazos cortos y "no alcanzan" tu sitio web).

En esa página hay un juego oculto: si pulsas la barra espaciadora, puedes jugar al T-rex run. (El enunciado incluye una imagen del juego.) También puedes acceder directamente en elgoog.im/t-rex.

Tu objetivo hoy es escribir un script de Python que automatice el juego. Tu programa mirará los píxeles de la pantalla para decidir cuándo pulsar la barra espaciadora y jugar automáticamente.

Puedes ver cómo se ve el juego automatizado con un bot en elgoog.im/t-rex/?bot.

Quizá quieras investigar dos paquetes: Pillow y PyAutoGUI.

Pregunta de la tarea — Momento de reflexión: cómo abordaste el proyecto; qué fue difícil y qué fácil; cómo mejorarías; tu mayor aprendizaje; qué harías distinto.

Prerequisitos: Pillow (Día 85); NumPy e imágenes como arreglos (Día 77 y Día 92); automatización con Selenium (Días 48–53), que aquí se reemplaza por control directo de teclado; ciclos while (Día 5).


2. Analizar el problema: percibir, decidir, actuar

(Sección creada para esta adaptación.)

Todos los bots y robots siguen el mismo ciclo:

Texto
      ┌──────────────────────────────────────────────┐
      ▼                                              │
  PERCIBIR                DECIDIR                ACTUAR
  capturar una  ──►  ¿hay píxeles oscuros  ──►  pulsar espacio
  zona de la         delante del dino?          (o no hacer nada)
  pantalla

🔍 Antes de programar

Juega 3 partidas a mano y responde:

Pregunta Tu respuesta
¿Dónde está el dinosaurio en tu pantalla? (coordenadas) …
¿Qué zona hay que "vigilar" para ver venir un cactus? …
¿De qué color son el fondo y los obstáculos? …
¿Hay obstáculos que se esquivan agachándose (pájaros)? …
¿Qué pasa con la velocidad a medida que avanza el juego? …
¿Cambian los colores después de un rato? …

La última pregunta es clave: después de cierta puntuación, el juego pasa a modo noche (colores invertidos). Un bot que no lo sepa fallará.


3. 📖 Percibir: capturar la pantalla y encontrar la zona de peligro

(Sección creada para esta adaptación. No ejecutado: requiere pantalla real.)

Capturar

Python
from PIL import ImageGrab

captura = ImageGrab.grab()                    # toda la pantalla
captura = ImageGrab.grab(bbox=(x1, y1, x2, y2))  # solo una región (más rápido)

ImageGrab funciona en Windows y macOS; en Linux depende del entorno gráfico. pyautogui.screenshot() es una alternativa (usa Pillow por dentro).

Calibrar: encontrar las coordenadas

Las coordenadas dependen de tu pantalla: no copies las de otra persona. Una forma de encontrarlas:

Python
import pyautogui, time

time.sleep(3)                  # tiempo para poner el ratón sobre el dino
print(pyautogui.position())    # Point(x=..., y=...)

Después, guarda una captura y ábrela para comprobar que la zona elegida es la correcta:

Python
ImageGrab.grab(bbox=ZONA).save("zona.png")

⚠️ Escalado de pantalla en Windows: si tu pantalla está al 125 % o 150 %, las coordenadas de pyautogui y las de la captura pueden no coincidir. Síntoma: la zona guardada no es la que esperabas. Comprueba siempre con zona.png y consulta la documentación de pyautogui sobre este tema.


4. 📖 Decidir: ¿hay un obstáculo?

(Sección creada para esta adaptación. Verificado con imágenes sintéticas.)

🎯 Objetivo de aprendizaje

Convertir una región de píxeles en una decisión sí/no con un umbral.

📖 Explicación conceptual

En el modo día, el fondo es casi blanco y los cactus son gris oscuro. Si en la zona delante del dinosaurio aparecen suficientes píxeles oscuros, hay un obstáculo. Dos parámetros:

  • umbral: a partir de qué valor un píxel es "oscuro" (en escala de grises, 0 es negro y 255 blanco).
  • mínimo: cuántos píxeles oscuros hacen falta (para ignorar polvo o ruido).

🔎 Ejemplo explicado

Python
import numpy as np

def hay_obstaculo(captura, zona, umbral=100, minimo=5):
    region = np.array(captura.crop(zona).convert("L"))
    return int((region < umbral).sum()) >= minimo
  • crop(zona) recorta la región (izquierda, arriba, derecha, abajo).
  • convert("L") pasa a escala de grises: un solo número por píxel.
  • region < umbral produce un arreglo de True/False; .sum() cuenta los True (NumPy trata True como 1).
  • Recibe una imagen, no captura la pantalla: por eso se puede probar con imágenes fabricadas.

Prueba verificada (sin pantalla):

Python
from PIL import Image, ImageDraw

pantalla = Image.new("RGB", (600, 150), (247, 247, 247))   # fondo del juego
ZONA = (120, 90, 160, 120)
assert not hay_obstaculo(pantalla, ZONA)

ImageDraw.Draw(pantalla).rectangle((140, 85, 150, 125), fill=(83, 83, 83))  # "cactus"
assert hay_obstaculo(pantalla, ZONA)

Alternativa sin NumPy: recorrer los píxeles con region.getdata(). Funciona, pero getdata está obsoleto en Pillow 12 (verificado: muestra un aviso y se eliminará en Pillow 14), y fue unas 14 veces más lento en la prueba. En un bot, la velocidad importa: cada milisegundo de retraso es un salto tardío.

El modo noche (verificado)

En un fondo oscuro, todos los píxeles son "oscuros": hay_obstaculo devuelve True sin cactus (falso positivo) y el dinosaurio saltaría sin parar. Idea: mirar primero un píxel del fondo (lejos de los obstáculos) y, si es oscuro, invertir la lógica (buscar píxeles claros). Tu turno: escribe fondo_es_oscuro(captura, punto) y adapta la decisión.

⚠️ Errores frecuentes

Error Qué ocurre Solución
Zona demasiado cerca del dino Salta tarde y choca Mueve la zona hacia la derecha
Zona demasiado lejos Salta antes de tiempo y cae sobre el cactus Ajusta con pruebas
El juego se acelera Cada vez salta más tarde Aleja la zona con el tiempo o según la puntuación
Capturar toda la pantalla en cada vuelta El bot es lento Captura solo la región (bbox)
Falsos positivos en modo noche Salta sin parar Detecta el color del fondo
Coordenadas de otra persona No funciona en tu pantalla Calibra en tu equipo

5. 📖 Actuar con seguridad: pyautogui

(Sección creada para esta adaptación. No ejecutado.)

pyautogui controla tu teclado y ratón. Un bot con un error puede pulsar teclas en cualquier ventana (¡incluso escribir en un chat!). Por eso:

Python
import pyautogui

pyautogui.FAILSAFE = True   # activado por defecto: mover el ratón a una esquina detiene el programa
pyautogui.PAUSE = 0         # por defecto hay una pausa tras cada acción; para el juego la quitamos

pyautogui.press("space")    # saltar

Reglas de seguridad para el aula:

  1. Conoce la forma de detenerlo antes de ejecutarlo: esquina de la pantalla (FAILSAFE) o Ctrl + C en la terminal.
  2. Pon un límite de tiempo en el ciclo mientras pruebas (por ejemplo, 30 segundos).
  3. Espera 3 segundos antes de empezar, para que puedas hacer clic en la ventana del juego.
  4. Cierra chats, correos y documentos abiertos mientras pruebas.

Uso responsable

Automatizar un juego sin conexión para aprender está bien. Usar bots en juegos en línea contra otras personas suele violar los términos del juego (y es trampa). Automatizar clics en páginas web puede violar sus términos de uso. Aplica lo aprendido en el Día 93: primero, ¿puedo?, ¿debo?


6. 🚀 Proyecto del día: construcción por versiones

(Desarrolla la tarea dia94-tarea13.md. Las versiones son una propuesta de esta adaptación.)

Problema

Escribir un bot que juegue al T-rex run mirando los píxeles de la pantalla.

Contexto

La clase de tecnología estudia cómo "ven" y "deciden" los robots. El juego del dinosaurio es un laboratorio seguro para experimentar con sensores (píxeles), reglas y actuadores (teclas).

Objetivo

Un bot calibrado que supere, de manera consistente, la puntuación que tú logras jugando a mano.

Requisitos funcionales

  1. Captura la zona de peligro y decide saltar según los píxeles.
  2. Se detiene con seguridad (FAILSAFE y límite de tiempo).
  3. Funciona en modo día y en modo noche.
  4. Muestra en la terminal cuántos saltos hizo.

Restricciones técnicas

  • Detección en una función pura probada con imágenes (sección 4).
  • Coordenadas y umbrales como constantes en un solo lugar (o en un archivo de configuración).
  • Ciclo while con condición de salida.

Planificación

  1. Comprender el juego (juega y observa). 2. Entradas: píxeles. 3. Procesos: capturar → decidir → pulsar. 4. Salidas: teclas. 5. Dividir en percibir/decidir/actuar. 6. Calibrar. 7. Implementar. 8. Probar. 9. Ajustar. 10. Mejorar.

Construcción paso a paso

  • Versión 1 — Calibración: script que imprime la posición del ratón y guarda zona.png.
  • Versión 2 — Decisión offline: hay_obstaculo con las pruebas de la sección 4 y con 2 capturas reales guardadas (una con cactus y otra sin).
  • Versión 3 — Bot básico: ciclo de 30 s que captura y salta.
  • Versión 4 — Ajuste: mide la puntuación de 5 partidas y ajusta zona, umbral y mínimo. Registra los cambios en una tabla.
  • Versión 5 — Modo noche y velocidad: adapta la lógica.
  • Versión final: README.md con un GIF, la tabla de ajustes y el diario.

Pruebas

# Caso Resultado esperado
1 Imagen sintética sin cactus False
2 Imagen sintética con cactus en la zona True
3 Imagen sintética con cactus fuera de la zona False
4 Fondo oscuro sin cactus (modo noche) False en tu versión mejorada
5 Mover el ratón a una esquina El programa se detiene (FailSafeException)
6 Tu captura real con cactus True

🧪 Prueba y depuración

Python
while True:
    pantalla = ImageGrab.grab()
    if pantalla.getpixel((300, 400)) != (255, 255, 255):
        pyautogui.press("space")

Encuentra cuatro problemas: bucle infinito sin salida; captura toda la pantalla (lento); mira un solo píxel y exige blanco exacto (el fondo del juego no es (255, 255, 255) y cualquier variación dispara el salto); y no considera el modo noche.

⭐ Extensión del proyecto

  • 🟢 Reto 1 — Aplicación: agacharse (pyautogui.keyDown("down")) cuando el obstáculo está arriba (pájaros), usando una segunda zona.
  • 🟡 Reto 2 — Ampliación: zona que se desplaza automáticamente según el tiempo transcurrido, para compensar la aceleración.
  • 🟠 Reto 3 — Desafío: medir la velocidad de los obstáculos con dos capturas seguidas (¿cuántos píxeles se movió el borde del cactus?) y calcular el momento ideal del salto.
  • 🔴 Reto 4 — Pensamiento computacional: diseña un experimento para encontrar los mejores parámetros (zona, umbral, mínimo): define qué medir, cuántas partidas por combinación y cómo comparar resultados sin engañarte con la suerte de una sola partida.

7. 🌟 Proyecto extra: automatizar una tarea repetitiva del computador

(Proyecto creado para esta adaptación; no existe en el curso original.)

Situación

En la sala de informática, cada inicio de clase hay que abrir las mismas 3 aplicaciones, ubicarlas en la pantalla y abrir la carpeta del curso. Toma 3 minutos por computador.

Requisitos

  1. Un script con pyautogui (o, mejor, con subprocess y os.startfile donde sea posible) que abra y organice las aplicaciones.
  2. Espera a que cada aplicación aparezca (por ejemplo, buscando una imagen en pantalla con pyautogui.locateOnScreen) en lugar de usar pausas fijas.
  3. Modo "simulación" que solo imprime lo que haría.

Decisiones que debes tomar (y justificar)

  • ¿Qué pasos se pueden hacer sin controlar el ratón (más confiable) y cuáles lo necesitan?
  • ¿Qué hace el script si una aplicación no se abre?

Casos de prueba

  • En modo simulación, no se mueve el ratón.
  • Si una aplicación tarda, el script espera sin fallar (hasta un límite).

🏫 Solo en computadores y con permisos autorizados por el docente o el administrador de la sala.


8. 🏗️ Mi Portafolio Profesional — Etapa 13

(Proyecto integrador creado para esta adaptación; etapas anteriores en los Días 82 a 93.)

Etapa 13 (hoy):

  1. Repositorio con deteccion.py (y pruebas con imágenes sintéticas y reales en pruebas/), bot.py, calibrar.py y config.py.
  2. README.md con GIF, instrucciones de calibración, reglas de seguridad y la tabla de ajustes de la versión 4.
  3. DIARIO.md del Día 94 y ficha en proyectos.json.

9. 🧩 Comprueba lo aprendido

Conceptuales

  1. Describe el ciclo percibir–decidir–actuar con el ejemplo del bot.
  2. ¿Por qué conviene que hay_obstaculo reciba una imagen en lugar de capturar la pantalla?
  3. ¿Qué es un falso positivo? Da un ejemplo en este proyecto.
  4. ¿Para qué sirve pyautogui.FAILSAFE?

Análisis de código

Python
region = np.array(captura.crop((100, 50, 120, 60)).convert("L"))
print(region.shape)

¿Qué forma tiene region? (Cuidado con el orden: filas, columnas.)

Predicción

Con umbral=100 y minimo=5, una zona con 4 píxeles de valor 50 y el resto 247, ¿hay obstáculo?

Depuración

"Mi bot funciona los primeros 30 segundos y luego empieza a chocar con todos los cactus." Da dos causas posibles.

Modificación

Cambia hay_obstaculo para que devuelva también la posición (columna) del primer píxel oscuro de la zona.

Creación

Escribe es_modo_noche(captura, punto) y combínala con hay_obstaculo en una función decidir(captura).


10. 🤖 Programar con apoyo de IA

Ciclo de trabajo: formula el problema → inténtalo tú primero → consulta a la IA sobre un punto concreto → lee y entiende → prueba → compara con la documentación oficial → modifica → explica con tus palabras.

Actividad 1 — API obsoleta. Pide a una IA código para contar píxeles oscuros con Pillow. Si usa getdata(), ejecútalo, lee el aviso de obsolescencia y reescríbelo con NumPy. Compara los tiempos.

Actividad 2 — Seguridad. Pregunta a una IA cómo detener un script de pyautogui que se descontroló. Compruébalo en la documentación oficial de PyAutoGUI (sección Fail-Safes).

Actividad 3 — Ética. Pregunta a una IA si usar bots en videojuegos en línea está permitido. Contrasta con los términos de servicio de un juego real que conozcas.

Declara el uso: sección "Uso de IA" en el README.md.


11. 🛠️ Observaciones sobre el material original

Archivo Observación Tratamiento
dia94-tarea13.md No menciona el modo noche ni la aceleración del juego Secciones 2 y 4, y la versión 5
dia94-tarea13.md No menciona medidas de seguridad al controlar el teclado Sección 5
dia94-tarea13.md Sugiere Pillow; muchos ejemplos en línea usan getdata(), obsoleto en Pillow 12 Se usa NumPy (sección 4)
dia94-tarea13.md Enlaza una copia del juego en elgoog.im (un sitio espejo) Se conserva; el juego original está en Chrome sin conexión (o en chrome://dino)

12. 📋 Matriz de trazabilidad

Contenido original Archivo de origen Concepto desarrollado Ejercicio original Reto adicional Proyecto relacionado
El juego oculto del T-rex en Chrome dia94-tarea13.md Sección 2 — — Sección 6 (contexto)
Script que automatiza el juego dia94-tarea13.md Secciones 2 y 5 Bot T-rex Retos 1 y 2 Secciones 6 y 8
Mirar píxeles para decidir cuándo pulsar espacio dia94-tarea13.md Secciones 3 y 4 Bot T-rex Retos 3 y 4 Sección 6
Paquetes sugeridos: Pillow y PyAutoGUI dia94-tarea13.md Secciones 3 a 5 — — —
Momento de reflexión dia94-tarea13.md Sección 6 (versión final) Pregunta de reflexión — Sección 8
(No existe en el curso original) — Umbrales, falsos positivos, seguridad, ética — Automatizar la sala de informática Sección 7

13. 📦 Evidencias de aprendizaje del Día 94

  • El bot funcionando (GIF o video) y la puntuación comparada con la tuya.
  • Las pruebas de detección con imágenes sintéticas y reales.
  • La tabla de ajustes de parámetros.
  • DIARIO.md del Día 94 y ficha en el portafolio.
  • Cuaderno de errores: zona mal calibrada, escalado de pantalla, falsos positivos en modo noche, captura de pantalla completa (lentitud), getdata() obsoleto, bucle sin salida.