Juego de la vida

De Jose Castillo Aliaga
Ir a la navegación Ir a la búsqueda

A continuación, vamos a estudiar una posible implementación del juego de la vida con scripts de bash y arrays.

El mayor problema para resolver esto en bash es que no podemos hacer directamente arrays bidimensionales. Por eso, debemos recurrir al truco de poner array[y*tamaño+x].

Preparación de la pantalla

La pantalla, al principio, es un array bidimensional de un tamaño determinado que tiene valores aleatorios entre '0' y '1'. Debemos hacer una función que la genere:

generar_pantalla ()
{
  ancho=$1
  for ((i=0;i<$((ancho*ancho));i++))
  do
  pantalla[$i]=$(echo $((RANDOM%2)))
  done
}

Si queremos mostrarla, podemos hacer esto:

echo "${pantalla[@]}" | tr -d ' ' |sed -r "s/.{$ancho}/&\n/g"

De esta manera, el script para generar y mostrar el juego de la vida en bash queda así:

#!/bin/bash

generar_pantalla ()
 {
   ancho=$1
   for ((i=0;i<$((ancho*ancho));i++))
   do
   pantalla[$i]=$(echo $((RANDOM%2)))
   done
 }

ancho=$1 
generar_pantalla $ancho
echo "${pantalla[@]}" | tr -d ' ' |sed -r "s/.{$ancho}/&\n/g"

Dibujar la pantalla cada cierto tiempo

A continuación, hay que buscar la manera de dibujar la pantalla cada cierto tiempo sin que parpadee. Otros lenguajes permiten la utilización del llamado doble buffer. Pero en Bash hay que buscarse la vida.

Intenta hacer esto en el script:

while [ 1 ]
do
clear
echo "${pantalla[@]}" | tr -d ' ' |sed -r "s/.{$ancho}/&\n/g"
done

Si hacemos un clear antes de dibujarla, el tiempo que tarde en volver a mostrarla parecerá un parpadeo. La idea es evitar esto no haciendo el clear, sino sobrescribiendola.

Esto se consigue con los caracteres especiales del echo.

echo -en "\e[s\e[0;0H\n$(echo ${pantalla[@]} | tr -d ' ' |sed -r "s/.{$ancho}/&\n/g")"

Si lo analizamos, lo que hace es añadir \e[s\e[0;0H para situar el cursor al principio de la pantalla y empezar a dibujar desde ahí. De esta manera, no parece que parpadee porque no se borra nada.

#!/bin/bash

generar_pantalla ()
 {
   ancho=$1
   for ((i=0;i<$((ancho*ancho));i++))
   do
   pantalla[$i]=$(echo $((RANDOM%2)))
   done
 }

ancho=$1 
generar_pantalla $ancho
#echo "${pantalla[@]}" | tr -d ' ' |sed -r "s/.{$ancho}/&\n/g" | tr '01' ' '
clear
while [ 1 ]
do
echo -en "\e[s\e[0;0H$(echo ${pantalla[@]} | tr -d ' ' |sed -r "s/.{$ancho}/&\n/g" | tr '01' ' *')"
done


Generaciones

El juego de la vida tiene las siguientes reglas:

Las transiciones dependen del número de células vecinas vivas:

  • Una célula muerta con exactamente 3 células vecinas vivas "nace" (al turno siguiente estará viva).
  • Una célula viva con 2 ó 3 células vecinas vivas sigue viva, en otro caso muere o permanece muerta (por "soledad" o "superpoblación").

Para conseguir esto hay que mantener dos matrices de células: la actual y la que vamos generando. Al final, se debe sustituir la actual por la generada.