Reputation: 3
So I'm learning python and trying to code Conway's game of life : (link)
I created a grid, on which you can click to select tiles, and a 2D array that contain the value 1 if the tiles is active, 0 if it's not.
Then, i need to calculate the number of neighboors of each tile. To do that I created a function (voisins_calc) and an other 2D array containing the number of neighboors for each tile.
The problem is : the 2D arrays 'state' and 'voisins' are copys of each other, and I really don't know why ! I think state is copying the value of voisins but I can't see where.
Here's the code ( I put the entire code despite the rules, since I don't know where it's going wrong, sorry for that)
import pygame
pygame.init()
screen_height = screen_width = 700
win = pygame.display.set_mode((screen_height, screen_width))
run = True
cols = rows = 2
state = []
voisins = []
def state_init():
line = []
line_transi = []
for col in range (cols):
for row in range (rows):
line.append(0)
line_transi = line.copy()
state.append(line_transi)
voisins.append(line_transi)
line.clear()
return (state)
def voisins_calc (x, y):
voisin = 0
for i in range (-1, 2, 1):
for j in range (-1, 2, 1):
if state[(y + rows + i) % rows][(x + cols + j) % cols] == 1:
voisin += 1
if state[x][y] == 1 :
voisin -= 1
return (voisin)
state_init()
while run :
print(state, voisins)
pygame.time.delay(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if pygame.mouse.get_pressed()[0]:
state[round(pygame.mouse.get_pos()[1] // (screen_height / rows))]
[round(pygame.mouse.get_pos()[0] // (screen_width / cols))] = 1
if pygame.mouse.get_pressed()[1]:
state[round(pygame.mouse.get_pos()[1] // (screen_height / rows))]
[round(pygame.mouse.get_pos()[0] // (screen_width / cols))] = 0
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
for col in range (cols):
for row in range (rows):
voisins[row][col] = voisins_calc(row, col)
win.fill((249, 203, 156))
for col in range (cols):
for row in range (rows):
if state[col][row] == 1 :
pygame.draw.rect(win, (75, 75, 75), (row * (screen_width /
rows), col * (screen_height / cols), (screen_width / cols), (screen_height
/ rows)), 0)
for row in range (rows) :
pygame.draw.line(win, (0, 0, 0),(row * screen_height / rows, 0),
(row * screen_height / rows, screen_width), 1)
for col in range (cols):
pygame.draw.line(win, (0, 0, 0),(0, col * screen_width / cols),
(screen_width, col * screen_width / cols), 1)
print(state, voisins)
pygame.display.update()
pygame.quit()
Upvotes: 0
Views: 37
Reputation: 45750
In state_init
, you add the same copy to each state
and voisins
:
state.append(line_transi) # These are the same lists
voisins.append(line_transi)
You need to add a copy to voisins
if you want them to be separate.
I'll note though, you're making this a lot more complicated than it needs to be. Just create a helper to create a grid, then call it twice:
def create_grid(width, height):
# 2D list comprehension to create nested list
return [[0 for _ in range(width)] for _ in range(height)]
state = create_grid(cols, rows)
voisins = create_grid(cols, rows)
Upvotes: 2
Reputation: 922
line_transi = line.copy()
state.append(line_transi)
voisins.append(line_transi)
Here you append
the same array line_transi
to both state
and voisins
. An alternative,
state.append(line.copy())
voisins.append(line.copy())
Upvotes: 1