71 lines
1.9 KiB
Python
71 lines
1.9 KiB
Python
'''
|
|
Wireworld implementation.
|
|
'''
|
|
|
|
from io import StringIO
|
|
from collections import namedtuple
|
|
from pprint import pprint as pp
|
|
import copy
|
|
|
|
WW = namedtuple('WW', 'world, w, h')
|
|
head, tail, conductor, empty = allstates = 'Ht. '
|
|
|
|
|
|
infile = StringIO('''\
|
|
tH.........
|
|
. .
|
|
...
|
|
. .
|
|
Ht.. ......\
|
|
''')
|
|
|
|
def readfile(f):
|
|
'''file > initial world configuration'''
|
|
world = [row.rstrip('\r\n') for row in f]
|
|
height = len(world)
|
|
width = max(len(row) for row in world)
|
|
# fill right and frame in empty cells
|
|
nonrow = [ " %*s " % (-width, "") ]
|
|
world = nonrow + \
|
|
[ " %*s " % (-width, row) for row in world ] + \
|
|
nonrow
|
|
world = [list(row) for row in world]
|
|
return WW(world, width, height)
|
|
|
|
def newcell(currentworld, x, y):
|
|
istate = currentworld[y][x]
|
|
assert istate in allstates, 'Wireworld cell set to unknown value "%s"' % istate
|
|
if istate == head:
|
|
ostate = tail
|
|
elif istate == tail:
|
|
ostate = conductor
|
|
elif istate == empty:
|
|
ostate = empty
|
|
else: # istate == conductor
|
|
n = sum( currentworld[y+dy][x+dx] == head
|
|
for dx,dy in ( (-1,-1), (-1,+0), (-1,+1),
|
|
(+0,-1), (+0,+1),
|
|
(+1,-1), (+1,+0), (+1,+1) ) )
|
|
ostate = head if 1 <= n <= 2 else conductor
|
|
return ostate
|
|
|
|
def nextgen(ww):
|
|
'compute next generation of wireworld'
|
|
world, width, height = ww
|
|
newworld = copy.deepcopy(world)
|
|
for x in range(1, width+1):
|
|
for y in range(1, height+1):
|
|
newworld[y][x] = newcell(world, x, y)
|
|
return WW(newworld, width, height)
|
|
|
|
def world2string(ww):
|
|
return '\n'.join( ''.join(row[1:-1]).rstrip() for row in ww.world[1:-1] )
|
|
|
|
ww = readfile(infile)
|
|
infile.close()
|
|
|
|
for gen in range(10):
|
|
print ( ("\n%3i " % gen) + '=' * (ww.w-4) + '\n' )
|
|
print ( world2string(ww) )
|
|
ww = nextgen(ww)
|