Last active
May 19, 2023 14:17
-
-
Save villares/2334c2c014070b9d0ac1e06c1170338c to your computer and use it in GitHub Desktop.
GOL with numpy & scipy convolve2d
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# based on https://www.jpytr.com/post/game_of_life/ | |
# previous version calculated neighbours twice at each step... it could be useful to color cells but I removed it. | |
import py5 | |
import numpy as np | |
from scipy.signal import convolve2d | |
board_img = None | |
def setup(): | |
global status | |
py5.size(600, 600) | |
py5.no_smooth() | |
status = get_init_status((py5.width, py5.height)) | |
def draw(): | |
global status, board_img | |
status = apply_conways_game_of_life_rules(status) | |
board_img = py5.create_image_from_numpy(status * 255, 'L', dst=board_img) | |
py5.image(board_img, 0, 0) | |
def get_init_status(size=(50, 50), initial_prob_life=0.5): | |
status = np.random.uniform(0, 1, size=size) <= initial_prob_life | |
return status | |
def apply_conways_game_of_life_rules(status): | |
"""Applies Conway's Game of Life rules given the current status of the game""" | |
live_neighbors = count_live_neighbors(status) | |
survive_underpopulation = live_neighbors >= 2 | |
survive_overpopulation = live_neighbors <= 3 | |
survive = status * survive_underpopulation * survive_overpopulation | |
new_status = np.where(live_neighbors==3, True, survive) # Born | |
return new_status | |
def count_live_neighbors(status): | |
"""Counts the number of neighboring live cells""" | |
kernel = np.array( | |
[[1, 1, 1], | |
[1, 0, 1], | |
[1, 1, 1]]) | |
return convolve2d(status, kernel, mode='same', boundary="wrap") | |
py5.run_sketch() | |
When you pass a dst
param to py5.create_image_from_numpy
it will simply make a call to the Py5Image object's set_np_pixels()
method, so the first alternate implementation is basically identical to what you coded.
I would expect the second one to be slightly faster than the first.
Very cool, thanks @hx2A !
I have used the second one at times, but I have missed the Py5Image method used in the first one, nice to know both!
You are welcome, @villares!
I thought you would be interested to see some of the other useful approaches for this kind of work.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Good job writing this! Using convolve2d works very well here.
There are two alternate implementations I will point out to you:
or you can remove
board_img
entirely with this: