John Conway (RIP) created the amazing game of life automaton, which is based on a simple rule.
Every cell that has either exactly 3 neighbours or was alive and has 2 neighbours is alive in the next generation.
Must Watch: https://www.youtube.com/watch?v=FdMzngWchDk
// constraint for lookup
create constraint if not exists on (p:Point) assert p.loc is unique;
// create points
unwind range(0,99) as x
unwind range(0,99) as y
create (:Point {loc:point({x:x, y:y})});
// with diagonals (8 neighbours each)
:auto unwind range(0,99) as x
unwind range(0,99) as y
call { with x,y
match (p:Point {loc:point({x:x, y:y})})
unwind range(-1,1) as dx
unwind range(-1,1) as dy
match (o:Point {loc:point({x:x+dx, y:y+dy})})
where o<>p
merge (p)-[:NB]-(o)
} in transactions of 1000 rows;
Show a few nodes
// show a bunch starting from 0,0
MATCH p=(:Point {loc:point({x:0,y:0})})-[*3]-() RETURN p LIMIT 100
We are using an R-Pentomino the smallest 5 element starting point. Could also use a glider or such.
// set smallest r-pentomino // .OO // OO. // .O. unwind [[1,0],[2,0],[0,1],[1,1],[1,2]] as pento match (p:Point {loc:point({x: 5+pento[0], y:5+pento[1]})}) SET p:Alive;
// iterate generations
match (p:Point)
with p, case size((p)--(:Alive)) when 2 then p:Alive when 3 then true else false end as alive
call { with p, alive
WITH * WHERE alive SET p:Alive
}
call { with p, alive
WITH * WHERE not alive REMOVE p:Alive
};
In Neo4j Browser it’s a bit of dragging involved, in Neo4j Bloom it should be automatically updated
// display results
unwind range(0,9) as x
unwind range(0,9) as y
match (p:Point {loc:point({x:x,y:y})}) return p
game-of-life-bloom.mp4