Categorías: Programación

Ejemplos de programacion 5 – el juego de la vida

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.

Enunciado

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.

C

 

#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.

 

Python

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.

 

Java

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.

Javascript

 

        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.

GO

 

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

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)

Ejemplos de programacion

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.

Compartir