En la entrada anterior les compartí el camino que seguí para programar el Juego de la Vida de Conway desde cero, primero con cuadernos interactivos y después con una versión para la terminal.
Esta vez quería dar un paso más: ver las células evolucionar en una ventana, poder pausar la simulación y probar algunos patrones conocidos sin tener que cambiar el código cada vez. Así nació esta versión gráfica hecha con Python y Pygame.
"Pygame es un conjunto de módulos del lenguaje Python que permiten la creación de videojuegos en dos dimensiones de una manera sencilla..." Fuente: Wikipedia
La idea no fue cambiar las reglas del juego, sino reutilizar la lógica de la versión anterior y sumarle una interfaz que permita explorarla en tiempo real.
Un repaso rápido: ¿qué es el Juego de la Vida?
El Juego de la Vida es un autómata celular creado por el matemático británico John Horton Conway. No hay jugadores ni decisiones durante la partida: se define un estado inicial y, a partir de ahí, el tablero evoluciona generación tras generación.
Cada célula puede estar viva o muerta y observa a sus ocho vecinas, incluidas las diagonales. Las reglas son simples:
- Una célula viva sobrevive si tiene dos o tres vecinas vivas.
- Una célula muerta nace si tiene exactamente tres vecinas vivas.
- En cualquier otro caso, la célula muere o permanece muerta.
Con solo esas reglas aparecen estructuras que se desplazan, oscilan o cambian durante muchas generaciones. Si querés conocer con más detalle cómo representé la matriz y calculé los vecinos, podés leer la primera parte del proyecto.
De la consola a Pygame
En la versión anterior podía ver la evolución del tablero en la terminal, pero quería una forma más agradable de observar los patrones y controlar la simulación mientras estaba corriendo. Además de que tenía ganas de ver algo básico de Pygame.
Esta librería se ocupa de abrir la ventana, dibujar cada célula y recibir las teclas. La lógica del autómata sigue trabajando con una matriz de listas de Python: cada posición vale 1 si la célula está viva y 0 si está muerta. Para esta versión no necesité incorporar NumPy ni cambiar esa representación.
La aplicación arranca con un tablero aleatorio. En la parte superior de la ventana se muestra un pequeño HUD con la generación actual, el estado de la simulación, el patrón seleccionado y la velocidad.
Controles
Mientras la ventana está activa, podés usar estas teclas:
| Tecla | Acción |
|---|---|
Espacio |
Pausar o reanudar la simulación |
↑ |
Aumentar la velocidad en 1 FPS, hasta 60 FPS |
↓ |
Reducir la velocidad en 1 FPS, hasta 1 FPS |
R |
Generar un tablero aleatorio nuevo |
1–9, 0 |
Cargar un patrón predefinido |
Esc |
Cerrar la aplicación |
Cada vez que elegís un patrón o generás un tablero aleatorio, el contador vuelve a cero. Los patrones se colocan centrados en el tablero.
Patrones incluidos
Además del estado aleatorio, se pueden probar diez patrones conocidos:
| Tecla | Patrón | Tipo |
|---|---|---|
1 |
Gosper Glider Gun | Cañón de planeadores |
2 |
Glider | Nave espacial |
3 |
Lightweight Spaceship (LWSS) | Nave espacial |
4 |
Pulsar | Oscilador |
5 |
Kok's Galaxy | Oscilador |
6 |
Pentadecathlon | Oscilador |
7 |
Tumbler | Oscilador |
8 |
Diehard | Matusalén |
9 |
R-pentomino | Matusalén |
0 |
Acorn | Matusalén |
Cómo está organizado el proyecto
Intenté mantener separadas las responsabilidades para que la lógica del juego no dependa de cómo se dibuja la ventana:
logica.pycrea los tableros, cuenta vecinos y calcula la generación siguiente. También coloca los patrones en el centro.display.pydibuja las células y el HUD con Pygame.main.pycrea la ventana, procesa los controles y coordina el ciclo de la simulación.patrones.pycontiene las matrices de los patrones disponibles.config.pylee los valores deconfig.toml.
El ciclo principal procesa los eventos de teclado, dibuja el tablero y, si la simulación no está pausada, calcula la generación siguiente. Para calcularla se parte de una copia de la matriz actual: así cada célula se actualiza usando el mismo estado de partida y no uno que ya haya sido modificado durante el recorrido.
Configurar el tablero y los colores
Algunos valores se pueden cambiar antes de iniciar el programa desde src/conway_pygame/config.toml. Ahí se definen la cantidad de filas y columnas, los FPS iniciales y los colores de la interfaz.
Por ejemplo, este fragmento configura un tablero de 50 por 50 células y comienza a 10 FPS:
[simulacion]
filas = 50
columnas = 50
fps = 10
[colores]
fondo = [15, 18, 25]
celda_muerta = [24, 29, 41]
celda_viva = [0, 229, 180]
Los colores se expresan como valores RGB, con tres números entre 0 y 255. Los cambios en el archivo se aplican cuando se vuelve a iniciar la aplicación; la velocidad sí se puede ajustar durante la ejecución con las flechas.
Surge la pregunta: ¿cuál es la necesidad de tener un archivo toml con esta configuración?. Estrictamente hablando, ninguna, me topé varias veces con archivos toml y quería incorporarlos en el proyecto a modo de prueba para entender un poco la forma en que se utilizan.
TOML es un formato de archivo de configuración que es fácil de leer debido a la semántica obvia que pretende ser "mínima". TOML está diseñado para mapear inequívocamente un diccionario [...] "TOML", el nombre, es un acrónimo de "Tom's Obvious, Minimal Language" que hace referencia a su creador: Tom Preston-Werner. Fuente: Wikipedia
¿Cómo probarlo en tu PC?
El proyecto usa Python 3.13 o superior y Pygame. Si ya tenés instalado uv, podés clonar el repositorio y sincronizar el entorno así:
git clone https://github.com/mcattani/conway_pygame.git
cd conway_pygame
uv sync
Después, iniciá el juego con:
uv run conway-pygame
También podés ejecutarlo como módulo:
uv run python -m conway_pygame
Pygame está declarado como dependencia del proyecto, así que uv sync se ocupa de instalarlo junto con el resto del entorno.
Como siempre, les dejo el código completo en GitHub: https://github.com/mcattani/conway_pygame
Si lo probás, me gustaría saber qué te pareció o qué otro patrón sumarías. Todos los comentarios son bienvenidos.
Saludos!
Y si este proyecto te resultó interesante y querés apoyar el blog, podés invitarme un cafecito:









