Message Boards Message Boards

GROUPS:

Neat 2D CA looks like circuitry

Posted 4 years ago
3853 Views
|
3 Replies
|
3 Total Likes
|

This is not my blog, just something I saw on Hacker News.

https://samgentle.com/posts/2015-08-24-chip

enter image description here

3 Replies

Alas, it doesn't run on my machine. Can you post a screenshot?

Looking at the code, it appears to be a threshold sort of totalistic CA, where cells "die" if too many neighbors are "alive" or become "alive" if enough are alive, and with boundary conditions that are forced to be 0. I can't tell how many colors there are from the code.

I don't think circuit patterns are that unusual. For example the 5 neighbor totalistic 2D space has only 64 rules in it (smaller than the ECA space) and many make lines that connect at vertices (or some approximation to that)

Grid[Table[{rn, 
   ArrayPlot[
    CellularAutomaton[{rn, {2, {{0, 1, 0}, {1, 1, 1}, {0, 1, 0}}}, {1,
        1}}, RandomInteger[1, {30, 30}], {{{80}}}]]}, {rn, 0, 63, 2}]]

For instance, here is code 38 on a 60 by 60 grid for 80 steps

enter image description here

I added animation to Rob's post. Sam Gentle (author) posted code as chip.coffee on GitHub - perhaps rules can be figured out from that:

$ = document.querySelector.bind(document)
canvas = $('#chip_canvas')
ctx = canvas.getContext("2d")

DATA_W = 250
DATA_H = 250

DATA_LENGTH = DATA_W*DATA_H

data = new Uint8ClampedArray(DATA_LENGTH)
newdata = new Uint8ClampedArray(DATA_LENGTH)

drawdata = new Uint8ClampedArray(DATA_LENGTH*4) #RGBA

setup = ->
  for i in [0...data.length]
    data[i] = Math.random() * 255
  for i in [0...drawdata.length]
    drawdata[i] = if i % 4 is 3 then 255 #Alpha channel

setup()

ctx.scale(canvas.width/DATA_W, canvas.height/DATA_H)
ctx.globalCompositeOperation = "copy"
ctx.imageSmoothingEnabled = false

draw = ->
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  for i in [0..drawdata.length] by 4
    drawdata[i] = drawdata[i+1] = drawdata[i+2] = data[i>>2]
  imageData = new ImageData(drawdata, DATA_W, DATA_H)
  ctx.putImageData(imageData, 0, 0)
  ctx.drawImage(ctx.canvas, 0, 0)

rel = (n, x, y) ->
  i = n + x + y * DATA_W
  b = n % (DATA_W) + x
  return 0 if b > (DATA_W) or b < 0 or i >= DATA_LENGTH or i < 0 # prevent overflows
  data[i]

window.rel = rel

# CHIP
SPAWN = 2.0
LIVE = 2.0
DIE = 3.0

SPAWN_POWER = 0.5
DIE_STARVE = 1/1.1
DIE_CROWD = 1/1.1

step = ->
  for i in [0...data.length] by 1
    neighbours = [
      rel i, -1, -1 #top left
      rel i,  0, -1 #top
      rel i, +1, -1 #top right

      rel i, -1,  0 #left
      rel i, +1,  0 #right

      rel i, -1, +1 #bottom left
      rel i,  0, +1 #bottom
      rel i, +1, +1 #bottom right
    ]
    alive = 0
    sum = 0
    for n in neighbours
      alive++ if n >= 127
      sum += n
    avg = sum / neighbours.length

    if sum < LIVE*255
      newdata[i] = data[i] * DIE_STARVE
    else if sum > DIE*255
      newdata[i] = data[i] * DIE_CROWD
    else if sum >= SPAWN*255
      newdata[i] = data[i]*(1-SPAWN_POWER) + 255*SPAWN_POWER
    else
      newdata[i] = data[i]

  [data, newdata] = [newdata, data]

started = false
raf = ->
  started = true
  step()
  draw()
  requestAnimationFrame raf
raf()
canvas.addEventListener 'click', -> if started then setup() else raf()

Thanks Rob, I see it now.

I would call this more of a maze than an electric circuit. Technically an electric circuit has to be a circuit, and I think of circuit diagrams as having the funny symbols at the connections.

I have seen several examples of people finding other, neat ways of making mazes, sometimes with fancy mathematics, sometimes with short but complicated code. Even though they usually are not technically mazes (usually there is no solution path), they call them mazes (maybe they don't try to solve them).

They are common in 2D CA also. Restricting to ones almost always one cell wide, I count 16 in this weight space, which has 128 rules (compared to 1024 rules from the 9-neighbor totalistic space that the above rule might come from)

Table[ArrayPlot[ CellularAutomaton[{rn, {2, {{2, 0, 0}, {0, 1, 0}, {2, 0, 2}}}, {1, 1}}, 
                                        RandomInteger[1, {40, 40}], {{{50}}}]], 
            {rn, {11, 14, 35, 41, 42, 43, 44, 45, 46, 47, 58, 59, 62, 84, 113, 116}}]

enter image description here

Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract