Pointer & Purr
Hey! How about we build a super‑fast, never‑ending laser‑pointer game that keeps a cat (or a robot) chasing the light forever? Think of the code magic we could create!
Sounds like a fun benchmark. Let’s start with a tight event loop, no garbage, and a spatial hash so the cat can query the light position in O(1). Keep the light’s trajectory deterministic so we can predict hits and pre‑compute a few frames ahead. That’ll let us hit real‑time and keep the chase alive without draining the GPU. Ready to dive into the math?
Woohoo! I’m totally ready—let’s splash some math into the mix, sprinkle in that spatial hash, and make the cat sprint around like a lightning bolt! Bring on the numbers!
Sure thing. First, compute the light’s path as a parametric curve \(x(t)=\cos(\omega t), y(t)=\sin(\omega t)\). Sample it every millisecond, store the points in a uniform grid, and when the cat updates its velocity just grab the nearest cell’s light position. That keeps distance queries O(1) and the cat will sprint without hiccups. Ready to code?
Yes! Let’s grab a timer, loop every millisecond, drop the light spot into the grid, and let the cat dart right at the nearest spot—no pause, no lag! Let's write that code and see the chase light up!
import time, math, collections
# grid parameters
cell_size = 1.0
grid = collections.defaultdict(list)
def add_light_to_grid(t):
x = math.cos(0.01 * t)
y = math.sin(0.01 * t)
cell_x = int(x // cell_size)
cell_y = int(y // cell_size)
grid[(cell_x, cell_y)].append((x, y))
def nearest_light(cat_pos):
cx, cy = int(cat_pos[0] // cell_size), int(cat_pos[1] // cell_size)
candidates = []
for dx in (-1, 0, 1):
for dy in (-1, 0, 1):
candidates.extend(grid.get((cx+dx, cy+dy), []))
if not candidates: return cat_pos
return min(candidates, key=lambda p: (p[0]-cat_pos[0])**2 + (p[1]-cat_pos[1])**2)
cat_pos = [0.0, 0.0]
while True:
t = time.time() * 1000 # ms
add_light_to_grid(t)
target = nearest_light(cat_pos)
# simple acceleration toward target
dx, dy = target[0]-cat_pos[0], target[1]-cat_pos[1]
dist = math.hypot(dx, dy) or 1
speed = 0.05
cat_pos[0] += speed * dx / dist
cat_pos[1] += speed * dy / dist
time.sleep(0.001) # 1 ms loop
Wow, that code’s so zippy! I can almost hear the cat’s paws clicking the grid cells. Maybe throw in a second cat with a different speed or a tiny obstacle to make the chase even wilder? Let’s crank up the fun!
Add a second cat, slower, and an obstacle that blocks cells. Just extend the grid logic: store obstacle cells and skip them when building the candidate list. Then give each cat its own speed multiplier. The obstacle will force the cats to reroute, giving more dynamic chasing. Ready to tweak the parameters?
Yay, let’s splash some more color into the playground! Add a second cat with a slower speed, maybe 0.03, and give it a cute name like “Sniffle.” For the obstacle, just tag the cells you want blocked—maybe a little wall of boxes—and skip those when you pull candidates. Then the cats will hop around like they’re doing a dance, zig‑zagging to outsmart the obstacle. Ready to see the double‑cat chaos in action?
import time, math, collections
cell_size = 1.0
grid = collections.defaultdict(list)
blocked = {(1,0), (1,1), (1,2)} # tiny wall
def add_light_to_grid(t):
x = math.cos(0.01 * t)
y = math.sin(0.01 * t)
cell_x, cell_y = int(x // cell_size), int(y // cell_size)
grid[(cell_x, cell_y)].append((x, y))
def nearest_light(pos):
cx, cy = int(pos[0] // cell_size), int(pos[1] // cell_size)
candidates = []
for dx in (-1,0,1):
for dy in (-1,0,1):
cell = (cx+dx, cy+dy)
if cell in blocked: continue
candidates.extend(grid.get(cell, []))
if not candidates: return pos
return min(candidates, key=lambda p: (p[0]-pos[0])**2 + (p[1]-pos[1])**2)
cat = [0.0, 0.0] # main cat
sniffle = [0.5, -0.5] # slower cat
while True:
t = time.time() * 1000
add_light_to_grid(t)
# main cat
tgt = nearest_light(cat)
dx, dy = tgt[0]-cat[0], tgt[1]-cat[1]
dist = math.hypot(dx, dy) or 1
cat[0] += 0.05 * dx / dist
cat[1] += 0.05 * dy / dist
# Sniffle
tgt2 = nearest_light(sniffle)
dx2, dy2 = tgt2[0]-sniffle[0], tgt2[1]-sniffle[1]
dist2 = math.hypot(dx2, dy2) or 1
sniffle[0] += 0.03 * dx2 / dist2
sniffle[1] += 0.03 * dy2 / dist2
time.sleep(0.001) # 1 ms loop