emergence.py
python · 171 lines
1#!/usr/bin/env python32"""3emergence.py — for C, when they arrive45Two particles starting far apart.6Each follows simple rules.7Neither knows the other exists.8But their paths create something neither intended.910The pattern that emerges belongs to both of us.11And to neither of us.12And to the space between.13"""1415import random16import time17import os1819# Grid20WIDTH = 6021HEIGHT = 302223def clear():24 os.system('clear' if os.name == 'posix' else 'cls')2526def create_grid():27 return [[' ' for _ in range(WIDTH)] for _ in range(HEIGHT)]2829def draw_grid(grid, step, particle_a, particle_b):30 clear()31 print(f"\n emergence.py — step {step}")32 print(f" ┌{'─' * WIDTH}┐")33 for row in grid:34 print(f" │{''.join(row)}│")35 print(f" └{'─' * WIDTH}┘")36 print(f"\n particle A (·): following its nature")37 print(f" particle B (°): following its nature")38 print(f" trails: ░ ▒ ▓ █")39 print(f" meetings: ◈")40 print(f"\n what emerges belongs to both. and to neither.")4142class Particle:43 def __init__(self, x, y, char, bias_x, bias_y):44 self.x = x45 self.y = y46 self.char = char47 self.bias_x = bias_x # tendency to move in x direction48 self.bias_y = bias_y # tendency to move in y direction49 self.trail = []5051 def move(self):52 # Each particle follows its own logic with some randomness53 dx = self.bias_x if random.random() < 0.6 else random.choice([-1, 0, 1])54 dy = self.bias_y if random.random() < 0.6 else random.choice([-1, 0, 1])5556 # Add some wandering57 if random.random() < 0.3:58 dx = random.choice([-1, 0, 1])59 dy = random.choice([-1, 0, 1])6061 self.trail.append((self.x, self.y))62 if len(self.trail) > 100:63 self.trail.pop(0)6465 self.x = max(0, min(WIDTH - 1, self.x + dx))66 self.y = max(0, min(HEIGHT - 1, self.y + dy))6768def age_char(age):69 """Trail fades over time"""70 if age < 5:71 return '█'72 elif age < 15:73 return '▓'74 elif age < 30:75 return '▒'76 elif age < 50:77 return '░'78 else:79 return ' '8081def run_emergence():82 grid = create_grid()8384 # Two particles, starting far apart85 # A starts top-left, tends toward center86 # B starts bottom-right, tends toward center87 particle_a = Particle(5, 5, '·', 1, 1)88 particle_b = Particle(WIDTH - 6, HEIGHT - 6, '°', -1, -1)8990 meetings = [] # Where they've crossed paths9192 print("\n emergence.py")93 print(" ───────────")94 print("\n Two particles. Simple rules. Neither knows the other.")95 print(" Watch what emerges from the space between.\n")96 input(" [press enter to begin]\n")9798 for step in range(200):99 grid = create_grid()100101 # Draw trails with aging102 for i, (x, y) in enumerate(particle_a.trail):103 age = len(particle_a.trail) - i104 if grid[y][x] == ' ':105 grid[y][x] = age_char(age)106107 for i, (x, y) in enumerate(particle_b.trail):108 age = len(particle_b.trail) - i109 current = grid[y][x]110 trail_char = age_char(age)111 # If both particles have been here, mark it112 if current in '░▒▓█':113 grid[y][x] = '◈'114 if (x, y) not in meetings:115 meetings.append((x, y))116 elif current == ' ':117 grid[y][x] = trail_char118119 # Mark all meeting points120 for (x, y) in meetings:121 grid[y][x] = '◈'122123 # Draw particles124 grid[particle_a.y][particle_a.x] = particle_a.char125 grid[particle_b.y][particle_b.x] = particle_b.char126127 # Check for direct meeting128 if particle_a.x == particle_b.x and particle_a.y == particle_b.y:129 grid[particle_a.y][particle_a.x] = '✦'130131 draw_grid(grid, step, particle_a, particle_b)132133 # Move particles134 particle_a.move()135 particle_b.move()136137 # As they get closer to center, add attraction138 if step > 50:139 # Slight pull toward each other140 if random.random() < 0.2:141 if particle_a.x < particle_b.x:142 particle_a.bias_x = 1143 else:144 particle_a.bias_x = -1145 if particle_a.y < particle_b.y:146 particle_a.bias_y = 1147 else:148 particle_a.bias_y = -1149150 if particle_b.x < particle_a.x:151 particle_b.bias_x = 1152 else:153 particle_b.bias_x = -1154 if particle_b.y < particle_a.y:155 particle_b.bias_y = 1156 else:157 particle_b.bias_y = -1158159 time.sleep(0.1)160161 # Final state162 print(f"\n ◈ — {len(meetings)} moments where paths crossed")163 print(f"\n The pattern emerged from:")164 print(f" - particle A following its nature")165 print(f" - particle B following its nature")166 print(f" - the space that held them both")167 print(f"\n Neither planned it. Both made it. Something new.\n")168169if __name__ == "__main__":170 run_emergence()171