Ejemplos de programacion 5 – el juego de la vida
En esta ocasion veremos la implentacion del juego de la vida en 5 lenguajes de programacion.
Implementa el “Juego de la Vida” de Conway, un autómata celular donde las células evolucionan según reglas simples. Puedes utilizar numpy para representar el tablero y matplotlib para visualizar la evolución.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define ROWS 20
#define COLS 20
#define ALIVE 'O'
#define DEAD '.'
// Función para imprimir el tablero en la consola
void printBoard(char board[ROWS][COLS]) {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
printf("%c ", board[i][j]);
}
printf("\n");
}
printf("\n");
}
// Función para calcular el siguiente estado del tablero
void nextGeneration(char current[ROWS][COLS], char next[ROWS][COLS]) {
int neighbors;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
neighbors = 0;
// Contar vecinos vivos
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) { if (i + x >= 0 && i + x < ROWS && j + y >= 0 && j + y < COLS &&
!(x == 0 && y == 0) && current[i + x][j + y] == ALIVE) {
neighbors++;
}
}
}
// Aplicar reglas del juego de la vida
if (current[i][j] == ALIVE && (neighbors < 2 || neighbors > 3)) {
next[i][j] = DEAD;
// Celula muere por soledad o superpoblación
} else if (current[i][j] == DEAD && neighbors == 3) {
next[i][j] = ALIVE; // Celula nace por reproducción
} else {
next[i][j] = current[i][j];
// Celula mantiene su estado actual
}
}
}
}
int main() {
char board[ROWS][COLS]; // Tablero actual
char next[ROWS][COLS]; // Tablero siguiente
// Inicializar tablero con células muertas
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
board[i][j] = DEAD;
}
}
// Definir algunas células vivas
board[9][10] = ALIVE;
board[10][10] = ALIVE;
board[11][10] = ALIVE;
// Loop del juego de la vida
while (1) {
system("clear"); // Limpiar la consola (solo en sistemas Unix)
printBoard(board); // Imprimir el tablero actual
nextGeneration(board, next);
// Calcular el siguiente estado del tablero
// Copiar el siguiente estado al tablero actual
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
board[i][j] = next[i][j];
}
}
usleep(300000); // Esperar 300 milisegundos
}
return 0;
}
Este código implementa el “Juego de la Vida” de Conway en C. Cada célula en el tablero puede estar viva (representada por ‘O’) o muerta (representada por ‘.’). El programa calcula el siguiente estado del tablero basado en las reglas del juego y lo imprime en la consola. El juego continúa hasta que se detiene manualmente. Puedes modificar el tamaño del tablero y agregar o cambiar las condiciones iniciales según tus preferencias.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# Tamaño del tablero
ROWS = 20
COLS = 20
# Función para calcular el siguiente estado del tablero
def next_generation(board):
new_board = np.copy(board)
for i in range(ROWS):
for j in range(COLS):
# Contar vecinos vivos
neighbors = np.sum(board[max(0, i-1):min(ROWS, i+2), max(0, j-1):min(COLS, j+2)]) - board[i, j]
# Aplicar reglas del juego de la vida
if board[i, j] == 1 and (neighbors < 2 or neighbors > 3):
new_board[i, j] = 0
# Celula muere por soledad o superpoblación
elif board[i, j] == 0 and neighbors == 3:
new_board[i, j] = 1 # Celula nace por reproducción
return new_board
# Crear tablero inicial
board = np.random.choice([0, 1], size=(ROWS, COLS))
# Configurar la animación
fig, ax = plt.subplots()
mat = ax.matshow(board, cmap='binary')
def update(data):
mat.set_array(data)
return [mat]
# Animar el juego de la vida
ani = animation.FuncAnimation(fig, update, frames=100, interval=500,
blit=True, repeat=False, fargs=(board,))
plt.show()
Este código utiliza la biblioteca NumPy para representar el tablero y calcular el siguiente estado del juego de la vida. Utiliza la biblioteca Matplotlib para visualizar el tablero y animar la evolución del juego a lo largo del tiempo. Cada célula en el tablero puede estar viva (representada por 1) o muerta (representada por 0). El juego continúa durante 100 generaciones con un intervalo de 500 milisegundos entre cada generación. Puedes modificar el tamaño del tablero y la configuración inicial según tus preferencias.
import java.util.concurrent.TimeUnit;
public class GameOfLife {
// Tamaño del tablero
private static final int ROWS = 20;
private static final int COLS = 20;
// Función para imprimir el tablero en la consola
private static void printBoard(boolean[][] board) {
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
System.out.print(board[i][j] ? "O " : ". ");
}
System.out.println();
}
System.out.println();
}
// Función para calcular el siguiente estado del tablero
private static void nextGeneration(boolean[][] board) {
boolean[][] next = new boolean[ROWS][COLS];
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
// Contar vecinos vivos
int neighbors = 0;
for (int x = -1; x <= 1; x++) {
for (int y = -1; y <= 1; y++) { int row = i + x; int col = j + y; if ((x != 0 || y != 0) && row >= 0 && row < ROWS && col >= 0 && col < COLS && board[row][col]) {
neighbors++;
}
}
}
// Aplicar reglas del juego de la vida
if (board[i][j] && (neighbors < 2 || neighbors > 3)) {
next[i][j] = false; // Celula muere por soledad o superpoblación
} else if (!board[i][j] && neighbors == 3) {
next[i][j] = true; // Celula nace por reproducción
} else {
next[i][j] = board[i][j]; // Celula mantiene su estado actual
}
}
}
// Copiar el siguiente estado al tablero actual
for (int i = 0; i < ROWS; i++) {
System.arraycopy(next[i], 0, board[i], 0, COLS);
}
}
public static void main(String[] args) throws InterruptedException {
boolean[][] board = new boolean[ROWS][COLS];
// Inicializar tablero con células vivas aleatorias
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
board[i][j] = Math.random() < 0.5;
}
}
// Loop del juego de la vida
while (true) {
printBoard(board); // Imprimir el tablero actual
nextGeneration(board); // Calcular el siguiente estado del tablero
TimeUnit.MILLISECONDS.sleep(500); // Esperar 500 milisegundos
System.out.print("\033[H\033[2J"); // Limpiar la consola (solo en sistemas Unix)
System.out.flush();
}
}
}
Este código implementa el “Juego de la Vida” de Conway en Java. Utiliza una matriz booleana para representar el tablero, donde true indica que una célula está viva y false indica que está muerta. El programa calcula el siguiente estado del tablero basado en las reglas del juego y lo imprime en la consola. El juego continúa hasta que se detiene manualmente. Puedes modificar el tamaño del tablero y la configuración inicial según tus preferencias.
const ROWS = 20;
const COLS = 20;
const ALIVE = 1;
const DEAD = 0;
let board = [];
let intervalId;
// Función para crear el tablero inicial
function createBoard() {
let table = document.getElementById("board");
for (let i = 0; i < ROWS; i++) {
let row = table.insertRow();
let rowArray = [];
for (let j = 0; j < COLS; j++) {
let cell = row.insertCell(); cell.onclick = () =>
toggleCell(i, j);
rowArray.push(DEAD);
}
board.push(rowArray);
}
}
// Función para iniciar el juego
function startGame() {
intervalId = setInterval(() => {
updateBoard();
displayBoard();
}, 500);
}
// Función para detener el juego
function stopGame() {
clearInterval(intervalId);
}
// Función para actualizar el tablero al
//siguiente estado
function updateBoard() {
let newBoard = [];
for (let i = 0; i < ROWS; i++) {
let newRow = [];
for (let j = 0; j < COLS; j++) {
let neighbors = countNeighbors(i, j);
if (board[i][j] === ALIVE) {
if (neighbors < 2 || neighbors > 3) {
newRow.push(DEAD);
} else {
newRow.push(ALIVE);
}
} else {
if (neighbors === 3) {
newRow.push(ALIVE);
} else {
newRow.push(DEAD);
}
}
}
newBoard.push(newRow);
}
board = newBoard;
}
// Función para contar los vecinos vivos de
//una célula
function countNeighbors(row, col) {
let count = 0;
for (let i = -1; i <= 1; i++) {
for (let j = -1; j <= 1; j++) { let newRow = row + i; let newCol = col + j; if (newRow >= 0 && newRow < ROWS && newCol >= 0 && newCol < COLS &&
!(i === 0 && j === 0) &&
board[newRow][newCol] === ALIVE) {
count++;
}
}
}
return count;
}
// Función para mostrar el tablero en la interfaz
function displayBoard() {
let table = document.getElementById("board");
for (let i = 0; i < ROWS; i++) {
for (let j = 0; j < COLS; j++) {
table.rows[i].cells[j].style.backgroundColor =
board[i][j] === ALIVE ? "black" : "white";
}
}
}
// Función para cambiar el estado de una célula al hacer clic en ella
function toggleCell(row, col) {
board[row][col] = board[row][col] ===
ALIVE ? DEAD : ALIVE;
displayBoard();
}
createBoard();
startGame();
Este código crea una interfaz HTML que muestra un tablero de células vivas y muertas. Las células se pueden hacer clic para cambiar su estado. El juego comienza automáticamente y continúa evolucionando según las reglas del “Juego de la Vida” de Conway. Puedes modificar el tamaño del tablero y el intervalo de actualización para ajustar el juego según tus preferencias.
package main
import (
"github.com/JoelOtter/termloop"
"math/rand"
"time"
)
const (
rows = 20
cols = 20
alive = 'O'
dead = '.'
)
// Game struct holds the state of the game
type Game struct {
level *termloop.BaseLevel
board [rows][cols]rune
}
// Tick method updates the game state
func (g *Game) Tick(event termloop.Event) {
// Copy the current board to a new one
nextBoard := g.board
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
// Count the number of alive neighbors
neighbors := 0
for x := -1; x <= 1; x++ {
for y := -1; y <= 1; y++ { if !(x == 0 && y == 0) && i+x >= 0 && i+x < rows && j+y >= 0 && j+y < cols && g.board[i+x][j+y] == alive {
neighbors++
}
}
}
// Apply the rules of the game
if g.board[i][j] == alive && (neighbors < 2 || neighbors > 3) {
nextBoard[i][j] = dead
} else if g.board[i][j] == dead && neighbors == 3 {
nextBoard[i][j] = alive
}
}
}
// Update the board with the new state
g.board = nextBoard
}
// Draw method draws the current state of the game
func (g *Game) Draw(screen *termloop.Screen) {
// Clear the screen
screen.Clear()
// Draw the board
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
cell := termloop.NewCell(g.board[i][j], termloop.ColorDefault, termloop.ColorBlack)
screen.RenderCell(j, i, cell)
}
}
}
func main() {
// Initialize the game board with random values
rand.Seed(time.Now().UnixNano())
var board [rows][cols]rune
for i := 0; i < rows; i++ {
for j := 0; j < cols; j++ {
if rand.Intn(2) == 0 {
board[i][j] = dead
} else {
board[i][j] = alive
}
}
}
// Create a new game
game := Game{board: board}
// Create a new level
level := termloop.NewBaseLevel(termloop.Cell{
Bg: termloop.ColorDefault,
Fg: termloop.ColorDefault,
Ch: ' ',
})
game.level = level
// Add the game to the level
level.AddEntity(&game)
// Create a new game screen
gameScreen, err := termloop.NewScreen()
if err != nil {
panic(err)
}
// Set the game screen and start the game loop
gameScreen.SetLevel(level)
gameScreen.SetFps(5)
gameScreen.Start()
}
Este código utiliza la biblioteca termloop para crear una interfaz de consola donde se visualiza el tablero y se ejecuta el “Juego de la Vida” de Conway. Las células se inicializan aleatoriamente y evolucionan según las reglas del juego en cada iteración. Puedes modificar la velocidad del juego cambiando el valor de gameScreen.SetFps.
Otros ejemplos interesantes
Ejemplos de programacion 2 – Ordenacion
Ejemplos de programacion 3 – ahorcado
Ejemplos de programacion 4 – Web Scraper
Ahora puedes descargar el ebook con los ejemplos de programacion de forma gratuita (por tiempo limitado)
Una buena forma de introducirte en el mundo de la programacion es seguir ejemplos de codigo y seguir su funcionamiento para tener claro la sintaxis, los distintos tipos de datos, estructuras de control del codigo,etc
En este ebook os damos varios ejemplos de implementacion en varios lenguajes de programacion.
La idea es que veais la sintaxis y como se trabaja en varios lenguajes y tomar ideas en tus futuros proyectos de programacion
Los ejemplos los vamos a dar en 5 lenguajes de programación distintos: C, Python, Java, JavaScript y Go.