Razón Artificial

La ciencia y el arte de crear videojuegos

El juego de la vida en Python

Escrito por adrigm el 17 de enero de 2010 en Inteligencia Artificial, Programación | 6 Comentarios.

Aquí traigo una versión del juego de la vida en Python utilizando GASP, se trata de una aplicación gráfica en el que se pueden elegir dos tipos de configuraciones:

  1. Aleatoria. Donde se debe introducir el numero de filas y columnas del mapa y se rellenan de forma aleatoria.
  2. Cargar Mapa. Donde se debe indicar la ruta de un mapa en formato txt con la configuración inicial, se incluye un ejemplo de mapa con el juego.

El juego es muy mejorable y se recomienda no usar mapas de más de 900 casillas (30×30), porque la API gráfica no es la mejor y va un poco mal. La configuración del juego se hace a través de consola, pero este se ejecuta en una ventana gráfica. Por defecto esta es de 640×480, pero se puede cambiar muy facilmente en el programa.

El programa necesita el paquete python-gasp que podéis encontrar en las repositorios de la distribuciones basadas en Debian, para otros sistemas consultar la página oficial. El código después del salto.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# ---------------------------------------------------------------------
# Programa: EL juego de la vida.
# Autor: Adrián Guerra Marrero (adrigm).
# Web: www.razonartificial.com
# Licencia: GNU/GPL
# ---------------------------------------------------------------------

# Módulos
from gasp import *
import time, os, random

# CONSTANTES
width = 640
height = 480

# Clases
# ---------------------------------------------------------------------

class Juego:
	def __init__(self, opcion=1, archivo="mapa.txt", fil=10, col=10):
		if opcion == 2:
			self.mapa = leerMapa(archivo)
		else:
			self.mapa = range(fil)
			for i in range(fil):
				self.mapa[i] = range(col)

			for f in range(fil):
				for c in range(col):
					self.mapa[f]1 = random.randint(0, 1)

		self.filas = len(self.mapa)
		self.columnas = len(self.mapa[0])

	def __str__(self):
		mapa = ""
		for f in range(self.filas):
			for c in range(self.columnas):
				if self.mapa[f]1 == 0:
					mapa += ". "
				if self.mapa[f]1 == 1:
					mapa += "* "
			mapa += "\n"
		return mapa

	def analizarVecinos(self, fil, col):
		vecinos = 0
		if fil-1 >= 0 and col-1 >= 0:
			if self.mapa[fil-1][col-1] == 1:
				vecinos += 1
		if fil-1 >= 0:
			if self.mapa[fil-1][col] == 1:
				vecinos += 1
		if fil-1 >= 0 and col+1 <= self.columnas-1:
			if self.mapa[fil-1][col+1] == 1:
				vecinos += 1
		if col-1 >= 0:
			if self.mapa[fil][col-1] == 1:
				vecinos += 1
		if col+1 <= self.columnas-1:
			if self.mapa[fil][col+1] == 1:
				vecinos += 1
		if fil+1 <= self.filas-1 and col-1 >= 0:
			if self.mapa[fil+1][col-1] == 1:
				vecinos += 1
		if fil+1 <= self.filas-1:
			if self.mapa[fil+1][col] == 1:
				vecinos += 1
		if fil+1 <= self.filas-1 and col+1 <= self.columnas-1:
			if self.mapa[fil+1][col+1] == 1:
				vecinos += 1
		return vecinos

	def ciclo(self):
		nueva_conf = []
		for f in range(self.filas):
			columna = []
			for c in range(self.columnas):
				vecinos = self.analizarVecinos(f, c)
				if self.mapa[f]1 == 0:
					if vecinos == 3:
						columna.append(1)
					else:
						columna.append(0)
				if self.mapa[f]1 == 1:
					if vecinos == 2 or vecinos == 3:
						columna.append(1)
					else:
						columna.append(0)
			nueva_conf.append(columna)

		self.mapa = nueva_conf

	def dibujar(self):
		dist_lv = width/self.columnas
		dist_lh = height/self.filas
		for i in range(self.columnas):
			Line((dist_lv*i, 0), (dist_lv*i, height))
		for n in range(self.filas):
			Line((0, dist_lh*n), (width, dist_lh*n))

		for f in range(self.filas):
			y = height-dist_lh - ((dist_lh)*f)+(dist_lh/2)
			for c in range(self.columnas):
				x = ((dist_lv)*c)+(dist_lv/2)
				if self.mapa[f]1 == 1:
					Circle((x, y), ((dist_lh/2)-((dist_lh/2)*0.2)))

# ---------------------------------------------------------------------

# Funciones
# ---------------------------------------------------------------------

# Quita el ultimo caracter de una lista.
def quitarUltimo(lista):
	for i in range(len(lista)):
		lista[i] = lista[i][:-1]
	return lista

# Covierte una cadena en una lista.
def listarCadena(cadena):
	lista = []
	for i in range(len(cadena)):
		if cadena[i] == ".":
			lista.append(0)
		if cadena[i] == "*":
			lista.append(1)
	return lista

# Lee un archivo de texto y lo convierte en una lista.
def leerMapa(archivo):
	mapa = open(archivo, "r")
	mapa = mapa.readlines()
	mapa = quitarUltimo(mapa)
	for i in range(len(mapa)):
		mapa[i] = listarCadena(mapa[i])
	return mapa

# ---------------------------------------------------------------------

def main():
	print "Indica si quieres cargar una configuración o utilizar una aleatoria."
	print "1. Aleatoria"
	print "2. Cargar configuración"
	opcion = input("Introduce el número de la opción elegida: ")
	if opcion == 1:
		filas = input("Introduce el número de filas: ")
		columnas = input("Introduce el número de columnas: ")
		archivo = ""
	if opcion == 2:
		archivo = raw_input("Intruduce la ruta del archivo: ")
		filas = 0
		columnas = 0

	begin_graphics(width=width, height=height, title="Juego de la Vida")
	juego = Juego(opcion=opcion, archivo=archivo, fil=filas, col=columnas)
	while True:
		juego.dibujar()
		juego.ciclo()
		time.sleep(0.35)
		clear_screen()
		update_when('next_tick')
	end_graphics()
	return 0

if __name__ == '__main__':
	main()

6 Comentarios en "El juego de la vida en Python"

  1. Edariel dice:

    Hola, cada vez que ejecuto el programa vida.py me sale la primera pantalla y luego cuando debe refrescar la pantalla, la ventana queda completamente en blanco, así que tengo que finalizarla. Utilizo Linux.

  2. admin dice:

    Tienes instalado el módulo python-gasp? es necesario para que funcione.

  3. mago re3d dice:

    …al ejecutar el programa…aparce error…
    ..como soluvciono esto…
    ..el error sale en las primeras lineas….

  4. adrigm dice:

    tienes que tener instalado el módulo python-gasp para que funcione.

    Si no me dices que error te da, no puedo decirte más.

  5. Kurai dice:

    Hola adrigm, me tome la libertad de modificar algunas lineas para que el codigo funcione con pygame como objetivo, espero que no haya ningun problema.

    Link del fondo: http://www.mediafire.com/?p9j0hjvz1w0e1ni

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    # ---------------------------------------------------------------------
    # Programa: EL juego de la vida.
    # Autor: Adrián Guerra Marrero (adrigm).
    # Web: www.razonartificial.com
    # Licencia: GNU/GPL
    
    # Implementado con Pygame por: Edinson Padrón (Kurai)
    # ---------------------------------------------------------------------
     
    # Módulos
    import time, os, random, pygame
    from pygame.locals import *
     
    # CONSTANTES
    width = 640
    height = 480
     
    # Clases
    # ---------------------------------------------------------------------
     
    class Juego:
        def __init__(self, opcion=1, archivo="mapa.txt", fil=10, col=10):
            if opcion == 2:
                self.mapa = leerMapa(archivo)
            else:
                self.mapa = range(fil)
                for i in range(fil):
                    self.mapa[i] = range(col)
     
                for f in range(fil):
                    for c in range(col):
                        self.mapa[f]1 = random.randint(0, 1)
     
            self.filas = len(self.mapa)
            self.columnas = len(self.mapa[0])
     
        def __str__(self):
            mapa = ""
            for f in range(self.filas):
                for c in range(self.columnas):
                    if self.mapa[f]1 == 0:
                        mapa += ". "
                    if self.mapa[f]1 == 1:
                        mapa += "* "
                mapa += "\n"
            return mapa
     
        def analizarVecinos(self, fil, col):
            vecinos = 0
            if fil-1 >= 0 and col-1 >= 0:
                if self.mapa[fil-1][col-1] == 1:
                    vecinos += 1
            if fil-1 >= 0:
                if self.mapa[fil-1][col] == 1:
                    vecinos += 1
            if fil-1 >= 0 and col+1 <= self.columnas-1:
                if self.mapa[fil-1][col+1] == 1:
                    vecinos += 1
            if col-1 >= 0:
                if self.mapa[fil][col-1] == 1:
                    vecinos += 1
            if col+1 <= self.columnas-1:
                if self.mapa[fil][col+1] == 1:
                    vecinos += 1
            if fil+1 <= self.filas-1 and col-1 >= 0:
                if self.mapa[fil+1][col-1] == 1:
                    vecinos += 1
            if fil+1 <= self.filas-1:
                if self.mapa[fil+1][col] == 1:
                    vecinos += 1
            if fil+1 <= self.filas-1 and col+1 <= self.columnas-1:
                if self.mapa[fil+1][col+1] == 1:
                    vecinos += 1
            return vecinos
     
        def ciclo(self):
            nueva_conf = []
            for f in range(self.filas):
                columna = []
                for c in range(self.columnas):
                    vecinos = self.analizarVecinos(f, c)
                    if self.mapa[f]1 == 0:
                        if vecinos == 3:
                            columna.append(1)
                        else:
                            columna.append(0)
                    if self.mapa[f]1 == 1:
                        if vecinos == 2 or vecinos == 3:
                            columna.append(1)
                        else:
                            columna.append(0)
                nueva_conf.append(columna)
     
            self.mapa = nueva_conf
     
        def dibujar(self, surface):
            dist_lv = width/self.columnas
            dist_lh = height/self.filas
            color = (0, 0, 0)
            
            for i in range(self.columnas):
                pygame.draw.line(surface, color, (dist_lv*i, 0), (dist_lv*i, height))
            for n in range(self.filas):
                pygame.draw.line(surface, color, (0, dist_lh*n), (width, dist_lh*n))
     
            for f in range(self.filas):
                y = height-dist_lh - ((dist_lh)*f)+(dist_lh/2)
                for c in range(self.columnas):
                    x = ((dist_lv)*c)+(dist_lv/2)
                    if self.mapa[f]1 == 1:
                        pygame.draw.circle(surface, color, (x, y), 
                                           int((dist_lh/2)-((dist_lh/2)*0.2)))
     
    # ---------------------------------------------------------------------
     
    # Funciones
    # ---------------------------------------------------------------------
     
    # Quita el ultimo caracter de una lista.
    def quitarUltimo(lista):
        for i in range(len(lista)):
            lista[i] = lista[i][:-1]
        return lista
     
    # Covierte una cadena en una lista.
    def listarCadena(cadena):
        lista = []
        for i in range(len(cadena)):
            if cadena[i] == ".":
                lista.append(0)
            if cadena[i] == "*":
                lista.append(1)
        return lista
     
    # Lee un archivo de texto y lo convierte en una lista.
    def leerMapa(archivo):
        mapa = open(archivo, "r")
        mapa = mapa.readlines()
        mapa = quitarUltimo(mapa)
        for i in range(len(mapa)):
            mapa[i] = listarCadena(mapa[i])
        return mapa
    
    def load_image(filename, transparent=False):
            try: 
                image = pygame.image.load(filename)
            except pygame.error, message:
                raise SystemExit, message
                
            image = image.convert()
            
            if transparent:
                color = image.get_at((0,0))
                image.set_colorkey(color, RLEACCEL)
                    
            return image
    
    # ---------------------------------------------------------------------
     
    def main():
        print "Indica si quieres cargar una configuración o utilizar una aleatoria."
        print "1. Aleatoria"
        print "2. Cargar configuración"
        opcion = input("Introduce el número de la opción elegida: ")
        if opcion == 1:
            filas = input("Introduce el número de filas: ")
            columnas = input("Introduce el número de columnas: ")
            archivo = ""
        if opcion == 2:
            archivo = raw_input("Intruduce la ruta del archivo: ")
            filas = 0
            columnas = 0
     
        screen = pygame.display.set_mode((width, height))
        pygame.display.set_caption("Juego de la Vida")
        
        juego = Juego(opcion=opcion, archivo=archivo, fil=filas, col=columnas)
        fondo = load_image("fondo.png")
        
        clock = pygame.time.Clock()
        
        while True:
            clock.tick(30)
            
            screen.blit(fondo, (0,0))
            juego.dibujar(screen)
            juego.ciclo()
            time.sleep(0.35)
            
            for event in pygame.event.get():
                if event.type == QUIT:
                    exit(0)
                elif event.type == KEYDOWN and event.key == K_ESCAPE:
                    exit(0)
            
            pygame.display.flip()
        
        return 0
     
    if __name__ == '__main__':
        pygame.init()
        main()
    

    Espero que la “modificacion” les sea de ayuda.

    Saludos.

Deja un comentario