### Sesc Av. Paulista ## Grupo de estudos em Python # `hackmd.io/@sesc-av-paulista/estudos-em-python-17-abril` - Thonny + py5 https://abav.lugaralgum.com/como-instalar-py5/ - Dica de livro https://automatetheboringstuff.com/ ## Autômatos Celulares - Outros exemplos: https://abav.lugaralgum.com/material-aulas/Processing-Python-py5/automatos-celulares.html Primeiro passo: um tabuleiro com um dicionário ```python= from random import choice W = 10 tabuleiro = {} # dicionario vazio def setup(): global colunas, filas size(600, 400) colunas = int(width / W) filas = int(height / W) zera_tabuleiro() def zera_tabuleiro(): for coluna in range(colunas): for fila in range(filas): tabuleiro[coluna, fila] = 0 def sorteia_tabuleiro(): for coluna in range(colunas): for fila in range(filas): tabuleiro[coluna, fila] = choice([0, 1]) def draw(): for chave, valor in tabuleiro.items(): coluna, fila = chave x = coluna * W y = fila * W if valor == 1: fill('black') else: fill('white') square(x, y, W) def key_pressed(): if key == ' ': zera_tabuleiro() elif key == 's': sorteia_tabuleiro() ``` Exemplo funcionando! ```python= from random import choice W = 10 tabuleiro = {} # dicionario vazio VIZINHANÇA = ( (-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1) ) rodando = False amostra = 10 def setup(): global colunas, filas size(600, 400) colunas = int(width / W) filas = int(height / W) zera_tabuleiro() no_stroke() def zera_tabuleiro(): for coluna in range(colunas): for fila in range(filas): tabuleiro[coluna, fila] = 0 def sorteia_tabuleiro(): for coluna in range(colunas): for fila in range(filas): tabuleiro[coluna, fila] = choice([0, 1]) def conta_vizinhos(coluna, fila): contagem = 0 for dc, df in VIZINHANÇA: contagem += tabuleiro[(coluna + dc) % colunas, (fila + df) % filas] return contagem def passo(): global tabuleiro proximo_tabuleiro = {} for chave, estado in tabuleiro.items(): coluna, fila = chave soma_vizinhos = conta_vizinhos(coluna, fila) # morte por solidão (morre com menos de 2 vizinhos) if estado == 1 and soma_vizinhos < 2: proximo_tabuleiro[coluna, fila] = 0 # morte por superpopulação (morre com 4 ou mais vizinhos) elif estado == 1 and soma_vizinhos > 3: proximo_tabuleiro[coluna, fila] = 0 # nascimento (com 3 vizinhos nasce elif estado == 0 and soma_vizinhos == 3: proximo_tabuleiro[coluna, fila] = 1 else: proximo_tabuleiro[coluna, fila] = estado tabuleiro = proximo_tabuleiro def draw(): for chave, valor in tabuleiro.items(): coluna, fila = chave x = coluna * W y = fila * W if valor == 1: fill('black') else: fill('white') square(x, y, W) # fill('red') # text_align(CENTER, CENTER) # c = conta_vizinhos(coluna, fila) # text(c, x + W / 2, y + W / 2) if rodando and (frame_count % amostra) == 0: passo() def key_pressed(): global rodando if key == 'c': zera_tabuleiro() elif key == 's': sorteia_tabuleiro() elif key == ' ': rodando = not rodando ``` ![image](https://hackmd.io/_uploads/ryIbmCRAye.png) --- ```python= from random import choice W = 10 tabuleiro = {} # dicionario vazio VIZINHANÇA = ( (-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1) ) rodando = False amostra = 10 def setup(): global colunas, filas size(600, 400) colunas = int(width / W) filas = int(height / W) zera_tabuleiro() no_stroke() color_mode(HSB) def zera_tabuleiro(): for coluna in range(colunas): for fila in range(filas): tabuleiro[coluna, fila] = 0 def sorteia_tabuleiro(): for coluna in range(colunas): for fila in range(filas): tabuleiro[coluna, fila] = choice([0, 1]) def conta_vizinhos(coluna, fila): contagem = 0 for dc, df in VIZINHANÇA: contagem += tabuleiro[(coluna + dc) % colunas, (fila + df) % filas] return contagem def passo(): global tabuleiro proximo_tabuleiro = {} for chave, estado in tabuleiro.items(): coluna, fila = chave soma_vizinhos = conta_vizinhos(coluna, fila) # morte por solidão (morre com menos de 2 vizinhos) if estado == 1 and soma_vizinhos < 2: proximo_tabuleiro[coluna, fila] = 0 # morte por superpopulação (morre com 4 ou mais vizinhos) elif estado == 1 and soma_vizinhos > 3: proximo_tabuleiro[coluna, fila] = 0 # nascimento (com 3 vizinhos nasce elif estado == 0 and soma_vizinhos == 3: proximo_tabuleiro[coluna, fila] = 1 else: proximo_tabuleiro[coluna, fila] = estado tabuleiro = proximo_tabuleiro def draw(): for chave, valor in tabuleiro.items(): coluna, fila = chave x = coluna * W y = fila * W if valor == 1: c = conta_vizinhos(coluna, fila) fill(c * 25, 200, 200) else: fill('white') square(x, y, W) if rodando and (frame_count % amostra) == 0: passo() def key_pressed(): global rodando if key == 'c': zera_tabuleiro() elif key == 's': sorteia_tabuleiro() elif key == ' ': rodando = not rodando ``` ![image](https://hackmd.io/_uploads/r1q57RCCke.png) ```python= from random import choice from itertools import product import py5 W = 10 # cell size nbs = ( # neighbourhood (-1, -1), (0, -1), (1, -1), (-1, 0), (1, 0), (-1, 1), (0, 1), (1, 1) ) board = {} # empty dict live_nbs_count = {} debug = False play = False sample = 10 # smaller is faster def setup(): global cols, rows py5.size(800, 600) cols = int(py5.width / W) rows = int(py5.height / W) clear_board() py5.no_stroke() py5.color_mode(py5.HSB) def clear_board(): for col, row in product(range(cols), range(rows)): board[col, row] = 0 nbs_count_update() def random_board(): for col, row in product(range(cols), range(rows)): board[col, row] = choice([0, 1]) nbs_count_update() def nbs_count_update(): for col, row in product(range(cols), range(rows)): live_nbs_count[col, row] = sum( board[(col + dc) % cols, (row + df) % rows] for dc, df in nbs) def step(): global board next_board = {} for (col, row), state in board.items(): live_nbs = live_nbs_count[col, row] # death by loneliness if state == 1 and live_nbs < 2: next_board[col, row] = 0 # death by overcrowding elif state == 1 and live_nbs > 3: next_board[col, row] = 0 # birth elif state == 0 and live_nbs == 3: next_board[col, row] = 1 # keep same else: next_board[col, row] = state board = next_board nbs_count_update() def draw(): for (col, row), state in board.items(): x, y = col * W, row * W live_nbs = live_nbs_count[col, row] if state == 1: py5.fill(live_nbs * 32, 200, 200) elif live_nbs == 3: # state == 0 but will become alive next. py5.fill(64) else: # state == 0 py5.fill(0) py5.square(x, y, W) if debug: py5.fill(255) py5.text_align(py5.CENTER, py5.CENTER) py5.text(live_nbs, x + W / 2, y + W / 2) if play and (py5.frame_count % sample) == 0: step() def key_pressed(): global play if py5.key == 'c': clear_board() elif py5.key == 'r': random_board() elif py5.key == ' ': play = not play py5.run_sketch(block=False) ``` ![sketch_2025_04_17](https://hackmd.io/_uploads/rymaqEkyee.png)