Python - Juego de la vida

 
Vista:
sin imagen de perfil

Juego de la vida

Publicado por Guillermo (12 intervenciones) el 01/08/2017 23:06:01
Hola, estoy intentando hacer el juego de la vida de Conway y necesito ayuda con un fragmento de código. Si alguien no sabe cuales son las normas, son dos muy sencillas que podéis buscar por internet (para no hacer esta explicación demasiado larga). Adjunto código y luego explico el problema:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
class GameOfLife(object):
    def __init__(self, high, width):
        """
        Inicializa el objeto creando una matriz con un alto y un ancho
        """
        self.panel = [[0]*width for i in range(high)]
 
    def _condition_number(self, i, j):
        """
        Devuelve la suma de todos los numeros que rodean el numero de posicion i,j en la matriz self.panel
        (Esta funcion creo que funciona correctamente, ya la use en otros programas, así que para no tener que 
        leerla simplemente podeis saltarla)
        """
        if i != 0 and j != 0 and j != len(self.panel[0])-1 and i != len(self.panel)-1:
            w = [self.panel[i-1][j-1],
                 self.panel[i-1][j],
                 self.panel[i-1][j+1],
                 self.panel[i][j-1],
                 self.panel[i][j+1],
                 self.panel[i+1][j-1],
                 self.panel[i+1][j],
                 self.panel[i+1][j+1]]
            w = sum(w)
        if i == 0 and j == 0:
            w = [self.panel[i][j+1],
                 self.panel[i+1][j],
                 self.panel[i+1][j+1]]
            w = sum(w)
        if i == 0 and j == len(self.panel[0])-1:
            w = [self.panel[i][j-1],
                 self.panel[i+1][j-1],
                 self.panel[i+1][j]]
            w = sum(w)
        if i == len(self.panel)-1 and j == 0:
            w = [self.panel[i-1][j],
                 self.panel[i-1][j+1],
                 self.panel[i][j+1]]
            w = sum(w)
        if i == len(self.panel)-1 and j == len(self.panel[0])-1:
            w = [self.panel[i-1][j-1],
                 self.panel[i-1][j],
                 self.panel[i][j-1]]
            w = sum(w)
        if i == 0 and j != 0 and j != len(self.panel[0])-1:
            w = [self.panel[i][j-1],
                 self.panel[i][j+1],
                 self.panel[i+1][j-1],
                 self.panel[i+1][j],
                 self.panel[i+1][j+1]]
            w = sum(w)
        if i != 0 and j == 0 and i != len(self.panel)-1:
            w = [self.panel[i-1][j],
                 self.panel[i-1][j+1],
                 self.panel[i][j+1],
                 self.panel[i+1][j],
                 self.panel[i+1][j+1]]
            w = sum(w)
        if i != 0 and j == len(self.panel[0])-1 and i != len(self.panel)-1:
            w = [self.panel[i-1][j-1],
                 self.panel[i-1][j],
                 self.panel[i][j-1],
                 self.panel[i+1][j-1],
                 self.panel[i+1][j]]
            w = sum(w)
        if i == len(self.panel)-1 and j != 0 and j != len(self.panel[0])-1:
            w = [self.panel[i-1][j-1],
                 self.panel[i-1][j],
                 self.panel[i-1][j+1],
                 self.panel[i][j-1],
                 self.panel[i][j+1]]
            w = sum(w)
        return w
 
    def _next(self):
        """
        Cambia la matriz self.panel a lo que seria digamos la siguiente iteracion en el juego de la vida (aqui esta el 
        problema)
        """
        new_panel = self.panel
        for i in range(len(self.panel)):
            for j in range(len(self.panel[0])):
                if self._condition_number(i,j) == 3:
                    new_panel[i][j] = 1 #al cambiar new_panel cambia tambien self.panel, y esto produce el error
                if self._condition_number(i,j) < 2 or self._condition_number(i,j) > 3:
                    new_panel[i][j] = 0 #al cambiar new_panel cambia tambien self.panel, y esto produce el error
        self.panel = new_panel
 
    def _print(self):
        """
        Imprime en pantalla la matriz self.panel
        """
        for i in self.panel:
            print(i)
 
    def run(self):
        """
        Loop principal, en el que se realizan todas las acciones del juego de la vida
        """
        while True:
            Next = raw_input("Next?")
            if Next == "no":
                return
            if Next == "yes":
                self._next()
                self._print()
            if Next == "new":
                new = int(raw_input("i")),int(raw_input("j"))
                self.panel[new[0]][new[1]] = 1
                self._print()
            if Next == "delete":
                new = int(raw_input("i")),int(raw_input("j"))
                self.panel[new[0]][new[1]] = 0
                self._print()
 
A = GameOfLife(10,10)
A.panel = [[0, 1, 0],
           [0, 1, 0],
           [0, 1, 0]]
A.run()


Si queréis ahorrar tiempo creo que el error está en el método _next, y tal vez sea un error muy básico de encapsulamiento o algo así pero soy un poco principiante en programar. Está comentada la parte que creo que falla. Si es necesario comentar algo más del código sólo preguntad. Uso python 2.7. Muchas gracias por la ayuda! :)
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de José María
Val: 819
Bronce
Ha mantenido su posición en Python (en relación al último mes)
Gráfica de Python

Juego de la vida

Publicado por José María (245 intervenciones) el 02/08/2017 16:57:36
Funciona con este cambio:

1
2
3
new_panel = []
for item in self.panel:
    new_panel.append(item[:])


Las listas son objetos mutables:
>>> a = [1, 2, 3]
>>> b = a # Hacemos una copia con objetos iguales
>>> a, b
([1, 2, 3], [1, 2, 3])
>>> a[1] = 4
>>> a, b
([1, 4, 3], [1, 4, 3])

Pero:
>>> a = [1, 2, 3]
>>> b = a[:] # Hacemos una copia con objetos distintos
>>> a, b
([1, 2, 3], [1, 2, 3])
>>> a[1] = 4
>>> a, b
([1, 4, 3], [1, 2, 3])
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar
Imágen de perfil de kip
Val: 1.120
Bronce
Ha mantenido su posición en Python (en relación al último mes)
Gráfica de Python

Juego de la vida

Publicado por kip (257 intervenciones) el 02/08/2017 22:18:04
Es totalmente correcto lo que dice Jose Maria, pero por que no hacerlo de una manera mas simple y pythonica(compresion de listas):

1
new_panel = [v for v in self.panel]

Con eso no tendras una copia, tal como mencionaron mas arriba, aunque el slice [:] no lo uso porque no se hara referencia al definirse en la iteracion, no es necesario:

1
2
3
4
5
6
7
8
9
10
11
12
a = [[1,2,3], [4,5,6]]
b = [i for i in a]
print a, b
'''
[[1, 2, 3], [4, 5, 6]] [[1, 2, 3], [4, 5, 6]]
'''
 
a[1] = [8,8,8]
print a, b
'''
[[1, 2, 3], [8, 8, 8]] [[1, 2, 3], [4, 5, 6]]
'''

O usar el slice y dejar a un lado la iteracion:

1
2
3
4
5
6
7
8
9
10
11
12
a = [[1,2,3], [4,5,6]]
b = a[:]
print a, b
'''
[[1, 2, 3], [4, 5, 6]] [[1, 2, 3], [4, 5, 6]]
'''
 
a[0] = [9,9,9]
print a, b
'''
[[9, 9, 9], [4, 5, 6]] [[1, 2, 3], [4, 5, 6]]
'''
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Juego de la vida

Publicado por Guillermo (12 intervenciones) el 03/08/2017 02:16:00
Al aplicarlo al código, veo que para que funcione es necesario la siguiente corrección:

1
new_panel = [item[:] for item in self.panel]

El hacer a = b[:] no me ha funcionado de ninguna forma :/. Muchas gracias por vuestra ayuda, ya funciona correctamente :).
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 11
Ha disminuido su posición en 5 puestos en Python (en relación al último mes)
Gráfica de Python

Juego de la vida

Publicado por Patricio (7 intervenciones) el 24/05/2019 22:50:44
Hola, estoy tambien tratando de hacer el juego de la vida en python, podrias mostrarme el codigo completo para poder entenderlo pls??
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar