---
# System prepended metadata

title: Grupo de estudos em Python - Autômatos Celulares - 17/abril

---

### 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)

