Assignment 11 – Saeed Lootah

Concept

I’ve always liked Conway’s Game of Life as a way to represent real cellular life using simple rules. But whenever I looked at the end result, I couldn’t fully see the resemblance to living systems. There was something about it that felt off, even if I couldn’t explain it at first.

After thinking about it more, I realized what bothered me about the classic aesthetic:

  • The pixelated style felt too rigid and angular to resemble the organic curves we see in real life.
  • Motion was hard to perceive; it felt more like watching stop-motion frames.
  • The black-and-white palette didn’t offer enough visual variety.

At the same time, I didn’t want to overcomplicate my version. Like the original, I wanted to keep the code simple while addressing these issues.

Code Highlight

push();
        noStroke();
        colorMode(HSL);
        let saturation = map(count2, 0, 24, 0, 150);
        let lightness = map(count2, 0, 24, 50, 100);
        
        // Map the (x, y) position to a hue gradient from top-left (0,0) to bottom-right (cols-1, rows-1)
        // Project (x, y) onto the main diagonal from (0,0) to (cols-1, rows-1)
        let diagonalProgress = ((x / (cols - 1)) + (y / (rows - 1))) / 2;
        let hue = map(diagonalProgress, 0, 1, 0, 360);
        fill(hue, saturation, lightness);
        let coefficient = expoMap(count, 0, 24, 0.1, 4.5);
        rectMode(CENTER)
        rect(x * cellSize, y * cellSize, cellSize * coefficient, cellSize * coefficient);
pop();

It’s probably the simplist piece of code in the sketch but I find it to be the most important. The reason being the map functions. I explain later in the milestones.

Embedded Sketch

 

Milestones

Stage 1 – Conway’s Game of Life

I first rebuilt Conway’s Game of Life in p5.js. The main difference was making it responsive to the canvas instead of using a fixed-size grid. I also added randomization: pressing R randomizes the grid, and the sketch starts with a randomized state.

Stage 2 – Experimenting with Opacity

 

I quickly found that opacity was an easy and effective way to show motion. By adjusting background opacity over time, movement became visible through trails. During testing, I found a “walker,” and this screenshot made it clear: without opacity, you probably wouldn’t notice that it was moving at all.

Stage 3 – Experimenting with Saturation and Lightness (using colorMode(HSL))

After exploring opacity, I tried a heatmap-like idea: cells with more neighbors become more saturated. I started with immediate neighbors (a 3×3 region), then expanded to a 5×5 neighborhood. I also tested different hues, but saturation alone still didn’t give me the look I wanted.

Stage 4 – Dynamic Cell Size

This was actually one of my earliest ideas, but I initially overcomplicated it in my head. My first concept was that cells with more neighbors should not only get larger, but “bulge,” almost like pushing up on paper from underneath a grid cell.

I didn’t know how to implement that cleanly, so I simplified. Instead, I used an exponential mapping function (rather than p5’s linear map() for a more natural effect), considered neighbors in a 5×5 area, and made low-neighbor cells smaller than their grid square.

That small detail made a huge difference. It defined the edges of each “organism” more clearly, and it reduced visual emphasis on small, self-sustaining shapes (like plus signs or small ovals), while giving larger moving organisms more presence. It’s difficult to fully capture in words – the images, and especially the live sketch, tell the story best.

Reflection

There are some things I would do differently or try out. I want to see what the bulging effect might look like. Also, I want to try adding a function where, if there doesn’t appear to be enough movement, the grid would randomize and start all over again.

I used AI to create the exponential map function. I also wanted to make hue change along both the x and y axes and only knew how to do it one way, so I got help from AI.

Leave a Reply

Your email address will not be published. Required fields are marked *