En Java y en Python + Tkinter
Es un autómata celular y fué inventado por el matemático John Conway en 1970.
Este tipo de autómatas son inventados para simular sistemas en el mundo real.
Contiene las siguientes reglas:
Para una casilla habitada
Cada celda con 1 o 0 vecinos muere. (Soledad)
Cada celda con 4 o más vecinos muere. (Sobrepoblación)
Cada celda con 2 o 3 vecinos sobrevive.
Para una casilla no habitada
Cada celda con 3 vecinos se convierte en habitada.
El juego de la vida en Python
El siguiente código se puede descargar desde aquí:
https://dl.dropboxusercontent.com/u/41478854/TheGameOfLife.py
import random
from Tkinter import *
#Medidas de la matrix
largo = 55
ancho = 55
#Matrix
matrix = [[0 for i in xrange(ancho)] for i in xrange(largo)] #matrix principal contenedora
bufferx = [[0 for i in xrange(ancho)] for i in xrange(largo)] #matrix de intercambio
#Campos
separacion = 6 #Separacion entre coordenadas del ovalo a dibujar como punto
constante = 10 #Constante de separacion entre los puntos
probabilidad = 6 #valor de probabilidad para la generacion random
def dibujarRandom():
for i in range(4,ancho-4):
for j in range(4,ancho-4):
r = random.randint(1,10)
if r <= probabilidad : #Si el num random <= probabilidad, la casilla se rellena
matrix[i][j] = 1
def linea(): #dibuja una linea en la matrix
matrix[4][2] = 1
matrix[4][3]=1
matrix[4][4]=1
matrix[4][5]=1
def recorrerMatrix():
for i in range(largo):
for j in range(ancho):
identificarVecinos(i,j)
def identificarVecinos(fila,col):
contador=0
if fila==0 or col==0 or fila==ancho-1 or col == largo-1:
return
for i in range(fila-1,fila+2):
for j in range(col-1,col+2):
if (i != fila or j != col) and matrix[i][j] == 1: #Si los hay algun vecino de los 8 posibles
contador += 1 #contador++
aplicarRegla(contador,fila,col, matrix[fila][col])
def aplicarRegla(vecinos,x,y,celda):
if celda==1 and (vecinos == 2 or vecinos == 3):
bufferx[x][y] = 1
if celda == 1 and vecinos > 3:
bufferx[x][y] = 0
if celda == 1 and (vecinos == 1 or vecinos == 0):
bufferx[x][y]=0
if celda == 0 and vecinos==3:
bufferx[x][y] = 1
def actualizarMatrix():
global matrix,bufferx
matrix = bufferx
bufferx = [[0 for i in xrange(ancho)] for i in xrange(largo)]
def dibujarPuntos(w):
for i in range(largo):
margen = (i+1)*constante #Margen superior que tendra el punto eje Y
for j in range(ancho):
referencia = (j+1)*constante #Punto de referencia para iniciar el punto X
#Dibujo ovalos de color azul o blanco para cada punto de la matriz
if matrix[i][j] == 1:
w.create_oval(referencia,margen,referencia+separacion,margen+separacion,fill="blue",outline="blue")
else:
w.create_oval(referencia,margen,referencia+separacion,margen+separacion,fill="white",outline="white")
w.update_idletasks()#Actualiza los puntos en la matriz
def cerrarVentana():
master.destroy()
def TheGameOfLife():
dibujarRandom()
#linea()
while 1:
dibujarPuntos(w)
recorrerMatrix()
actualizarMatrix()
master = Tk() #Variable de ventana TK
w = Canvas(master, width=600, height=600) #Para dibujar cosas
def main():
master.wm_title("The Game Of Life")
master.geometry("563x563+450+100")#Dimensiones + margenes
master.protocol("WM_DELETE_WINDOW", cerrarVentana)#Listener para cerrar ventana
w.pack()
TheGameOfLife()
mainloop()#Mantener la ventana abierta
main()#Ejecutar la funcion Main
Por cuestiones de comodidad y falta de tiempo, NO realicé muchas validaciones e inclusive tengo un enorme BUG como el listener para cerrar la ventana debido a que pusé en un ciclo infinito el juego de la vida, también decidí establecer con valores fijos los tamaños de la matriz para no tener que redimensionar constantemente. Otra cosa que no tuve más tiempo para solucionar fué que el programa se vuelve muy lento despues de un X número de iteraciones al momento de re-dibujar en el Canvas. Es la primera vez que utilizo Tkinter y nunca había hecho la gran cosa en Python anteriormente.
Por otra parte, en lugar de enfocarme en la interacción con el usuario me enfoqué en la lógica del algoritmo y en cómo utilizar Tkinter en python para dibujar.
Básicamente lo que hice fué lo siguitente:
1) Crear la matriz principal y una matriz buffer
2) Crear un dibujo random en la matriz principal
3) Se dibujan los puntos en el Canvas según la matriz principal
4) Recorrer cada celda de la matriz principal en busca de vecinos
5) Aplicar las reglas del juego para cada celda en la matriz principal
6) La nueva matriz crearla en el buffer a medida que aplicamos la regla
7) El buffer se convierte en la matriz principal
8) Se actualiza el dibujo en el Canvas según la matriz principal
¿Cómo saber si funciona o no?
Primero lo que hice fue poner una función para dibujar una línea pequeña:
def linea(): #dibuja una linea en la matrix
matrix[4][2] = 1
matrix[4][3]=1
matrix[4][4]=1
matrix[4][5]=1
1era iteración 2da iteración
3era iteración
4ta iteración
Dibujando una matriz random podemos ver algo similar a esto:
def dibujarRandom():
for i in range(4,ancho-4):
for j in range(4,ancho-4):
r = random.randint(1,10)
if r <= probabilidad : #Si el num random <= probabilidad, la casilla se rellena
matrix[i][j] = 1
El juego de la vida en Java
Con respecto a Java utilizé como salida de información la línea de comandos.
Descargar aquí:
Código
import java.util.Random;
public class GameOfLife{
private int largo;
private int ancho;
private char[][] cadena;//matriz original
private char[][] buffer;//matriz buffer
GameOfLife(){
largo = 10;
ancho = 10;
inicializar(largo,ancho);
}
GameOfLife(int x, int y){
largo = y;
ancho = x;
inicializar(largo,ancho);
}
public void inicializar(int largo, int ancho){
cadena = new char[largo][ancho];
limpiar();
buffer = new char[largo][ancho];
limpiarBuffer();
}
public void imprimir(){
for(int i=0; i < largo;i++){
for(int j=0; j < ancho; j++){
System.out.print(cadena[i][j]);
}
System.out.println();
}
}
public void imprimirBuffer(){
for(int i=0; i < largo;i++){
for(int j=0; j < ancho; j++){
System.out.print(buffer[i][j]);
}
System.out.println();
}
}
public void limpiar(){
for(int i=0;i<largo; i++){
for(int j=0;j<ancho;j++){
cadena[i][j]='-';
}
}
}//end of clean
public void limpiarBuffer(){
for(int i=0;i<largo; i++){
for(int j=0;j<ancho;j++){
buffer[i][j]='-';
}
}
}//end of clean
public void poblacionRandom(){
Random numR = new Random();
for(int i=4; i < largo-3; i++){
for(int j=4;j<ancho-3;j++){
if( numR.nextInt(10) < 6 ){
cadena[i][j]='X';
}
}
}
}
public void recorrerMatriz(){
for(int i=0;i<largo;i++){
for(int j=0; j<ancho;j++){
identificarVecinos(i,j);
}
}
}
public void identificarVecinos(int fila, int col){
int contador=0;
if(fila==0 || col==0 || fila==ancho-1 || col == largo-1){
return;
}
if(cadena[fila-1][col-1]=='X') contador++;
if(cadena[fila-1][col]=='X') contador++;
if(cadena[fila-1][col+1]=='X') contador++;
if(cadena[fila][col-1]=='X') contador++;
if(cadena[fila][col+1]=='X') contador++;
if(cadena[fila+1][col-1]=='X') contador++;
if(cadena[fila+1][col]=='X') contador++;
if(cadena[fila+1][col+1]=='X') contador++;
aplicarRegla(contador,fila,col, cadena[fila][col]);
}
public void aplicarRegla(int vecinos, int x, int y, char caracter){
if(caracter=='X' && (vecinos == 2 || vecinos == 3) ){
buffer[x][y] = 'X';
}
if(caracter != 'X' && vecinos==3){
buffer[x][y] = 'X';
}
if(vecinos > = 4){
buffer[x][y] = '-';
}
if(vecinos<=1){
buffer[x][y]='-';
}
}
public void copiarA(){
for(int i=0; i <largo;i++){
for(int j=0; j <ancho;j++){
cadena[i][j]=buffer[i][j];
}
}
}
public static void main(String args[]){
int lolargo = Integer.parseInt(args[0]);
int loancho = Integer.parseInt(args[1]);
GameOfLife game = new GameOfLife(lolargo, loancho);
game.poblacionRandom();
while(true){
game.imprimir();
System.out.printf("\n\n");
game.recorrerMatriz();
game.limpiar();
game.copiarA();
}
}//end of main
}//end of class
Necesita 2 argumentos desde la línea de comandos.
Por lo pronto la preparé para que sea una matriz cuadrada.
Para poder apreciar la salida del programa podemos mandarla a un archivo de texto:Abriendo el archivo de texto salida.txt podremos ver las iteraciones realizadas:
1era iteración
2da iteración
3era iteración
Enésima iteración
Referencias:
http://www.bitstorm.org/gameoflife/
http://www.math.com/students/wonders/life/life.html











Revisado. Se ven bastante bien el código y las capturas de pantalla. Faltaron las conclusiones del ejercicio. También recuerda que las referencias electrónicas llevan un cierto formato; checa, por ejemplo, el de APA http://owl.english.purdue.edu/owl/resource/560/10/
ResponderBorrar