August 3rd, 2025 – late summer light filtering through the trees like golden syrup, slow and thick and a little sticky. A breeze now and then, enough to keep the bugs confused. One of those afternoons where the world feels paused between chapters.
🧶📚 We made our way to Dragon Bite Books, where the paperbacks lean in like old friends sharing secrets and the air smells like stories. Betty Grable, the shop cat, was very much on duty—zipping between shelves, brushing our legs with friendly purpose, pausing just long enough for a head bump before darting off to patrol her realm. Skittish, but sociable, like a librarian who’s short on time but still wants to say hello.
The take-home haul was a lovely one—some back issues of spinning magazines full of wooly dreams, a couple of gently-used novels, and a pleasing handful of art supplies. The wooden spheres clacked comfortingly in their little bag, the new stencil set looked ready to shape some fresh ideas, and the Halloween ribbon—orange and black plaid with a thin gold thread stitched through—caught the light in a way that felt like a wink from October. No pumpkins, no ghosts—just that subtle seasonal suggestion.
🐈⬛✨🎃
The Little Free Art Library was a bit bare today—just a bent paperclip and a sticker that said “You tried.” We tucked in three 3D printed llamas, all different sizes, ready to be adopted by passing hands. The kind of tiny thing that might make someone’s day brighter, or at least weirder in a good way.
We split a croissant from BreadCraft by the fountain, layers crisp and warm, little flakes tumbling into the water like edible confetti. A couple of pigeons watched us with obvious judgment. One tried to edge closer. We did not share.
Currently listening: the soft clack of wooden spheres and passing cicadas
Currently planning: what to stencil first
Currently grateful for: Betty Grable the shop cat, art surprises, and the quiet delight of orange and gold plaid
#scottobearstyle #salemva #dragonbitebooks #littlefreeartlibrary #3dprintedllamas #autumninspo #bookshopcat #breadcraftbreak
Daily Archives: August 3, 2025
Game of life, pydroid v.2
import pygame
import pickle
import os
import copy
# — Configuration —
SCREEN_WIDTH, SCREEN_HEIGHT = 800, 600
CELL_SIZE = 10
GRID_WIDTH = SCREEN_WIDTH // CELL_SIZE
GRID_HEIGHT = (SCREEN_HEIGHT – 100) // CELL_SIZE # Reserve space for buttons
# Colors
COLOR_WHITE = (255, 255, 255)
COLOR_BLACK = (0, 0, 0)
COLOR_GRAY = (40, 40, 40)
COLOR_GREEN = (0, 255, 0)
COLOR_BLUE = (30, 144, 255)
COLOR_RED = (255, 69, 0)
# — Game of Life Logic (using standard lists) —
def create_grid(width, height):
“””Creates a 2D list to represent the grid.”””
return [[0 for _ in range(height)] for _ in range(width)]
def next_generation(grid):
“””Computes the next generation of the grid based on the rules.”””
width = len(grid)
height = len(grid[0])
new_grid = copy.deepcopy(grid) # Use deepcopy for lists of lists
for x in range(width):
for y in range(height):
# Count live neighbors, handling wrapping at the edges (toroidal array)
total = 0
for i in range(-1, 2):
for j in range(-1, 2):
if i == 0 and j == 0:
continue
# Calculate wrapped coordinates
nx, ny = (x + i) % width, (y + j) % height
total += grid[nx][ny]
# Apply Conway’s rules
if grid[x][y] == 1:
if (total < 2) or (total > 3):
new_grid[x][y] = 0
else:
if total == 3:
new_grid[x][y] = 1
return new_grid
# — Classic Patterns —
def get_patterns():
“””Returns a dictionary of classic Game of Life patterns.”””
patterns = {
“Gosper Glider Gun”: [
(5, 1), (5, 2), (6, 1), (6, 2), (5, 11), (6, 11), (7, 11),
(4, 12), (8, 12), (3, 13), (9, 13), (3, 14), (9, 14), (6, 15),
(4, 16), (8, 16), (5, 17), (6, 17), (7, 17), (6, 18),
(3, 21), (4, 21), (5, 21), (3, 22), (4, 22), (5, 22),
(2, 23), (6, 23), (1, 25), (2, 25), (6, 25), (7, 25),
(3, 35), (4, 35), (3, 36), (4, 36)
],
“Glider”: [(0, 1), (1, 2), (2, 0), (2, 1), (2, 2)],
“Pulsar”: [
(2,4),(3,4),(4,4),(8,4),(9,4),(10,4), (2,5),(7,5),(9,5),(14,5),
(2,6),(7,6),(9,6),(14,6), (4,7),(5,7),(6,7),(10,7),(11,7),(12,7),
(4,9),(5,9),(6,9),(10,9),(11,9),(12,9), (2,10),(7,10),(9,10),(14,10),
(2,11),(7,11),(9,11),(14,11), (2,12),(3,12),(4,12),(8,12),(9,12),(10,12)
],
“Clear”: []
}
return patterns
def place_pattern(grid, pattern_name, offset_x=10, offset_y=5):
“””Places a pattern onto the grid.”””
patterns = get_patterns()
pattern = patterns.get(pattern_name)
width = len(grid)
height = len(grid[0])
# Clear grid before placing pattern
for x in range(width):
for y in range(height):
grid[x][y] = 0
if pattern:
for pos in pattern:
# Ensure pattern fits on screen
if 0 <= pos[0] + offset_x < width and 0 <= pos[1] + offset_y < height:
grid[pos[0] + offset_x][pos[1] + offset_y] = 1
# — Pygame Setup —
pygame.init()
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption(“Conway’s Game of Life”)
clock = pygame.time.Clock()
font = pygame.font.SysFont(“sans”, 20)
# — Button Class —
class Button:
def __init__(self, x, y, width, height, text, color):
self.rect = pygame.Rect(x, y, width, height)
self.text = text
self.color = color
def draw(self, surface):
pygame.draw.rect(surface, self.color, self.rect)
pygame.draw.rect(surface, COLOR_WHITE, self.rect, 2)
text_surf = font.render(self.text, True, COLOR_WHITE)
text_rect = text_surf.get_rect(center=self.rect.center)
surface.blit(text_surf, text_rect)
def is_clicked(self, pos):
return self.rect.collidepoint(pos)
# — UI Elements —
buttons = {
“play_pause”: Button(10, SCREEN_HEIGHT – 80, 100, 30, “Play”, COLOR_BLUE),
“step”: Button(120, SCREEN_HEIGHT – 80, 70, 30, “Step”, COLOR_BLUE),
“save”: Button(10, SCREEN_HEIGHT – 40, 70, 30, “Save”, COLOR_BLUE),
“load”: Button(90, SCREEN_HEIGHT – 40, 70, 30, “Load”, COLOR_BLUE),
}
pattern_buttons = {}
pattern_names = list(get_patterns().keys())
x_offset = 200
for i, name in enumerate(pattern_names):
pattern_buttons[name] = Button(x_offset + (i * 120), SCREEN_HEIGHT – 80, 110, 30, name, COLOR_GRAY)
# — Main Game Loop —
def main():
grid = create_grid(GRID_WIDTH, GRID_HEIGHT)
running = True
paused = True
drawing = False
speed = 10 # Generations per second
while running:
for event in pygame.event.get():
if event.type == pygame.QUIT: running = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_AC_BACK: running = False
if event.type == pygame.MOUSEBUTTONDOWN:
pos = pygame.mouse.get_pos()
on_button = any(btn.is_clicked(pos) for btn in list(buttons.values()) + list(pattern_buttons.values()))
if on_button:
# Handle UI buttons
if buttons[“play_pause”].is_clicked(pos):
paused = not paused
buttons[“play_pause”].text = “Play” if paused else “Pause”
buttons[“play_pause”].color = COLOR_BLUE if paused else COLOR_RED
elif buttons[“step”].is_clicked(pos) and paused:
grid = next_generation(grid)
elif buttons[“save”].is_clicked(pos):
try:
with open(“life_save.dat”, “wb”) as f:
pickle.dump(grid, f)
print(“Grid saved!”)
except Exception as e:
print(f”Error saving file: {e}”)
elif buttons[“load”].is_clicked(pos):
try:
if os.path.exists(“life_save.dat”):
with open(“life_save.dat”, “rb”) as f:
grid = pickle.load(f)
print(“Grid loaded!”)
except Exception as e:
print(f”Error loading file: {e}”)
for name, btn in pattern_buttons.items():
if btn.is_clicked(pos):
place_pattern(grid, name)
else:
# Handle drawing on the grid
drawing = True
x, y = pos[0] // CELL_SIZE, pos[1] // CELL_SIZE
if 0 <= x < GRID_WIDTH and 0 <= y < GRID_HEIGHT:
grid[x][y] = 1 – grid[x][y] # Toggle cell
if event.type == pygame.MOUSEBUTTONUP:
drawing = False
if event.type == pygame.MOUSEMOTION and drawing:
pos = pygame.mouse.get_pos()
x, y = pos[0] // CELL_SIZE, pos[1] // CELL_SIZE
if 0 <= x < GRID_WIDTH and 0 <= y < GRID_HEIGHT:
grid[x][y] = 1 # Draw live cells
if not paused:
grid = next_generation(grid)
# — Drawing —
screen.fill(COLOR_BLACK)
for x in range(GRID_WIDTH):
for y in range(GRID_HEIGHT):
if grid[x][y] == 1:
pygame.draw.rect(screen, COLOR_GREEN, (x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE))
pygame.draw.rect(screen, COLOR_GRAY, (x*CELL_SIZE, y*CELL_SIZE, CELL_SIZE, CELL_SIZE), 1)
pygame.draw.rect(screen, (50,50,50), (0, SCREEN_HEIGHT – 100, SCREEN_WIDTH, 100))
for btn in buttons.values():
btn.draw(screen)
for btn in pattern_buttons.values():
btn.draw(screen)
pygame.display.flip()
clock.tick(speed)
pygame.quit()
if __name__ == ‘__main__’:
main()