LIFE plane

August 17, 2017

Life on expanding network. Only nodes needed are included into network.

# https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
# 1. Any live cell with fewer than two live neighbours dies,
#    as if caused by underpopulation.
# 2. Any live cell with two or three live neighbours lives on
#    to the next generation.
# 3. Any live cell with more than three live neighbours dies,
#    as if by overpopulation.
# 4. Any dead cell with exactly three live neighbours becomes
#    a live cell, as if by reproduction.
 
from Nets import Network
 
def expandNode(L,u):
    if L.getNode(u,'active') is not None: return
    L.setNode(u,'active',False); r,c = u
    for dr,dc in [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]:
        v = (r+dr,c+dc)
        if v not in L._nodes: L.addNode(v)
        if v not in L.edgeNeighbors(u): id = L.addEdge(u,v)
def setActive(L,A):
    for v in A:
        if v not in L._nodes: L.addNode(v)
        if L.getNode(v,'active') is None: expandNode(L,v)
        L.setNode(v,'active',True); L.setNode(v,'s',[])
def show(Active,m1=None,m2=None,M1=None,M2=None):
    if m1 is None: m1 = min([r for r,c in Active])
    if M1 is None: M1 = max([r for r,c in Active])
    if m2 is None: m2 = min([c for r,c in Active])
    if M2 is None: M2 = max([c for r,c in Active])
    print(m1,m2,M1,M2)
    P = [['□'] * (M2-m2+1) for i in range(M1-m1+1)]
    for r,c in Active: P[r-m1][c-m2] = '■'
    for l in P: print(' '.join(l))
 
L = Network()
glider = [(1,2),(2,3),(3,1),(3,2),(3,3)]; setActive(L,glider)
nStep = 5; Cand = glider #; m1=None; m2=None; M1=None; M2=None
m1=1; m2=1; M1=5; M2=5 
# pentadecathlon = [(5,7),(5,12),(6,5),(6,6),(6,8),(6,9),(6,10),(6,11),(6,13),
#                  (6,14),(7,7),(7,12)]
# setActive(L,pentadecathlon); nStep = 16; Cand = pentadecathlon
for step in range(nStep+1):
# display current state
    Active = { v for v in Cand if L.getNode(v,'active') }
    print('\nStep',step,'/',len(L._nodes)) 
    show(Active,m1,m2,M1,M2)
    for v in Active: L.setNode(v,'s',L.getNode(v,'s')+[step])
    if step>=nStep: break
# determine Candidates for change
    Cand = Active
    for v in Active: Cand = Cand | L.neighbors(v)
# prepare change
    S = [ (u, sum([ L.getNode(v,'active',False) for v in {u}|L.neighbors(u) ])) \
          for u in Cand ]
# make change
# To avoid decisions and branches -if the sum of all nine fields:
# - is 3, the inner field state for the next generation will be life
# - is 4, the inner field retains its current state
# - every other sum sets the inner field to death.
    for v,s in S:
        if s==3:
            expandNode(L,v); L.setNode(v,'active',True);
            if 's' not in L._nodes[v][3]: L.setNode(v,'s',[])
        elif (s!=4) and L.getNode(v,'active'): L.setNode(v,'active',False)
print("\nNode activity")
for v in L.nodes():
    s = L.getNode(v,'s')
    if s is not None: print(v,"=",s)
m1=None; m2=None; M1=None; M2=None
======= RESTART: C:\Users\batagelj\work\Python\graph\Nets\lifePlane.py =======
 
Step 0 / 22
1 1 3 3
□ ■ □
□ □ ■
■ ■ ■
 
Step 1 / 26
2 1 4 3
■ □ ■
□ ■ ■
□ ■ □
 
Step 2 / 27
2 1 4 3
□ □ ■
■ □ ■
□ ■ ■
 
Step 3 / 30
2 2 4 4
■ □ □
□ ■ ■
■ ■ □
 
Step 4 / 31
2 2 4 4
□ ■ □
□ □ ■
■ ■ ■
 
Step 5 / 34
3 2 5 4
■ □ ■
□ ■ ■
□ ■ □
 
Node activity
(1, 2) = [0]
(2, 1) = [1]
(2, 2) = [3]
(2, 3) = [0, 1, 2, 4]
(3, 2) = [0, 1, 5]
(3, 3) = [0, 1, 2, 3]
(3, 4) = [3, 4, 5]
(3, 1) = [0, 2]
(4, 2) = [1, 2, 3, 4]
(4, 3) = [2, 3, 4, 5]
(4, 4) = [4, 5]
(5, 3) = [5]
>>> 
m1=1; m2=1; M1=5; M2=5
======= RESTART: C:\Users\batagelj\work\Python\graph\Nets\lifePlane.py =======
 
Step 0 / 22
1 1 5 5
□ ■ □ □ □
□ □ ■ □ □
■ ■ ■ □ □
□ □ □ □ □
□ □ □ □ □
 
Step 1 / 26
1 1 5 5
□ □ □ □ □
■ □ ■ □ □
□ ■ ■ □ □
□ ■ □ □ □
□ □ □ □ □
 
Step 2 / 27
1 1 5 5
□ □ □ □ □
□ □ ■ □ □
■ □ ■ □ □
□ ■ ■ □ □
□ □ □ □ □
 
Step 3 / 30
1 1 5 5
□ □ □ □ □
□ ■ □ □ □
□ □ ■ ■ □
□ ■ ■ □ □
□ □ □ □ □
 
Step 4 / 31
1 1 5 5
□ □ □ □ □
□ □ ■ □ □
□ □ □ ■ □
□ ■ ■ ■ □
□ □ □ □ □
 
Step 5 / 34
1 1 5 5
□ □ □ □ □
□ □ □ □ □
□ ■ □ ■ □
□ □ ■ ■ □
□ □ ■ □ □

Variant

# https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
# 1. Any live cell with fewer than two live neighbours dies,
#    as if caused by underpopulation.
# 2. Any live cell with two or three live neighbours lives on
#    to the next generation.
# 3. Any live cell with more than three live neighbours dies,
#    as if by overpopulation.
# 4. Any dead cell with exactly three live neighbours becomes
#    a live cell, as if by reproduction.
 
from Nets import Network
 
def expandNode(L,u):
    if L.getNode(u,'active') is not None: return
    L.setNode(u,'active',True); L.setNode(u,'s',[]); r,c = u
    for dr,dc in [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]:
        v = (r+dr,c+dc)
        if v not in L._nodes: L.addNode(v)
        if v not in L.edgeNeighbors(u): id = L.addEdge(u,v)
def setActive(L,A):
    for v in A:
        if v not in L._nodes: L.addNode(v)
        expandNode(L,v)
def show(Active,m1=None,m2=None,M1=None,M2=None):
    if m1 is None: m1 = min([r for r,c in Active])
    if M1 is None: M1 = max([r for r,c in Active])
    if m2 is None: m2 = min([c for r,c in Active])
    if M2 is None: M2 = max([c for r,c in Active])
    print(m1,m2,M1,M2)
    P = [['□'] * (M2-m2+1) for i in range(M1-m1+1)]
    for r,c in Active: P[r-m1][c-m2] = '■'
    for l in P: print(' '.join(l))
 
L = Network()
glider = [(1,2),(2,3),(3,1),(3,2),(3,3)]; setActive(L,glider)
nStep = 10; Cand = glider #; m1=None; m2=None; M1=None; M2=None
m1=1; m2=1; M1=6; M2=6 
# pentadecathlon = [(5,7),(5,12),(6,5),(6,6),(6,8),(6,9),(6,10),(6,11),(6,13),
#                  (6,14),(7,7),(7,12)]
# setActive(L,pentadecathlon); nStep = 16; Cand = pentadecathlon
for step in range(nStep+1):
# display current state
    Active = { v for v in Cand if L.getNode(v,'active') }
    print('\nStep',step,'/',len(L._nodes),len(Cand),len(Active)) 
    show(Active,m1,m2,M1,M2)
    for v in Active: L.setNode(v,'s',L.getNode(v,'s')+[step])
    if step>=nStep: break
# determine Candidates for change
    Cand = Active
    for v in Active: Cand = Cand | L.neighbors(v)
# prepare change
    S = [ (u,sum([L.getNode(v,'active',False) for v in {u}|L.neighbors(u)])) \
          for u in Cand ]
# make change
# To avoid decisions and branches -if the sum of all nine fields:
# - is 3, the inner field state for the next generation will be life
# - is 4, the inner field retains its current state
# - every other sum sets the inner field to death.
    for v,s in S:
        if s==3: expandNode(L,v); L.setNode(v,'active',True);
        elif (s!=4) and L.getNode(v,'active'): L.setNode(v,'active',False)
print("\nNode activity")
for v in L.nodes():
    s = L.getNode(v,'s')
    if s is not None: print(v,"=",s)
========= RESTART: C:/Users/batagelj/work/Python/graph/Nets/lifeP.py =========
 
Step 0 / 22 5 5
1 1 6 6
□ ■ □ □ □ □
□ □ ■ □ □ □
■ ■ ■ □ □ □
□ □ □ □ □ □
□ □ □ □ □ □
□ □ □ □ □ □
 
Step 1 / 26 22 5
1 1 6 6
□ □ □ □ □ □
■ □ ■ □ □ □
□ ■ ■ □ □ □
□ ■ □ □ □ □
□ □ □ □ □ □
□ □ □ □ □ □
 
Step 2 / 27 22 5
1 1 6 6
□ □ □ □ □ □
□ □ ■ □ □ □
■ □ ■ □ □ □
□ ■ ■ □ □ □
□ □ □ □ □ □
□ □ □ □ □ □
 
Step 3 / 30 22 5
1 1 6 6
□ □ □ □ □ □
□ ■ □ □ □ □
□ □ ■ ■ □ □
□ ■ ■ □ □ □
□ □ □ □ □ □
□ □ □ □ □ □
 
Step 4 / 31 22 5
1 1 6 6
□ □ □ □ □ □
□ □ ■ □ □ □
□ □ □ ■ □ □
□ ■ ■ ■ □ □
□ □ □ □ □ □
□ □ □ □ □ □
 
Step 5 / 34 22 5
1 1 6 6
□ □ □ □ □ □
□ □ □ □ □ □
□ ■ □ ■ □ □
□ □ ■ ■ □ □
□ □ ■ □ □ □
□ □ □ □ □ □
 
Step 6 / 35 22 5
1 1 6 6
□ □ □ □ □ □
□ □ □ □ □ □
□ □ □ ■ □ □
□ ■ □ ■ □ □
□ □ ■ ■ □ □
□ □ □ □ □ □
 
Step 7 / 38 22 5
1 1 6 6
□ □ □ □ □ □
□ □ □ □ □ □
□ □ ■ □ □ □
□ □ □ ■ ■ □
□ □ ■ ■ □ □
□ □ □ □ □ □
 
Step 8 / 39 22 5
1 1 6 6
□ □ □ □ □ □
□ □ □ □ □ □
□ □ □ ■ □ □
□ □ □ □ ■ □
□ □ ■ ■ ■ □
□ □ □ □ □ □
 
Step 9 / 42 22 5
1 1 6 6
□ □ □ □ □ □
□ □ □ □ □ □
□ □ □ □ □ □
□ □ ■ □ ■ □
□ □ □ ■ ■ □
□ □ □ ■ □ □
 
Step 10 / 43 22 5
1 1 6 6
□ □ □ □ □ □
□ □ □ □ □ □
□ □ □ □ □ □
□ □ □ □ ■ □
□ □ ■ □ ■ □
□ □ □ ■ ■ □
 
Node activity
(1, 2) = [0]
(2, 1) = [1]
(2, 2) = [3]
(2, 3) = [0, 1, 2, 4]
(3, 2) = [0, 1, 5]
(3, 3) = [0, 1, 2, 3, 7]
(3, 4) = [3, 4, 5, 6, 8]
(3, 1) = [0, 2]
(4, 2) = [1, 2, 3, 4, 6]
(4, 3) = [2, 3, 4, 5, 9]
(4, 4) = [4, 5, 6, 7]
(5, 3) = [5, 6, 7, 8, 10]
(5, 4) = [6, 7, 8, 9]
(4, 5) = [7, 8, 9, 10]
(5, 5) = [8, 9, 10]
(6, 4) = [9, 10]
(6, 5) = [10]
>>> 
notes/net/exe/lifp.txt · Last modified: 2017/08/17 16:22 by vlado
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki