cellpimat.py
author Eugen Sawin <sawine@me73.com>
Thu, 30 Dec 2010 02:16:10 +0100
changeset 2 ccbf96145796
child 3 89d76549ba6e
permissions -rw-r--r--
Added Pi-approximating automatons.
     1 class Grid(object):
     2 
     3 	def __init__(self):
     4 		self.cells = {}
     5 		self.minx = 0
     6 		self.maxx = 0
     7 		self.miny = 0
     8 		self.maxy = 0
     9 
    10 	def set(self, pos, value=1):
    11 		if not pos in self.cells or value != self.cells[pos]:
    12 			self.cells[pos] = value
    13 			self.update(pos)
    14 		return self
    15 
    16 	def clear(self, pos):
    17 		if pos in self.cells:
    18 			del self.cells[pos]
    19 			self.update(pos)
    20 		return self
    21 
    22 	def update(self, (x, y)):
    23 		self.minx = min(x, self.minx)
    24 		self.maxx = max(x, self.maxx)
    25 		self.miny = min(y, self.miny)
    26 		self.maxy = max(y, self.maxy)
    27 		return self
    28 
    29 	def width(self):
    30 		return self.maxx - self.minx + 1
    31 
    32 	def height(self):
    33 		return self.maxy - self.miny + 1
    34 
    35 	def __len__(self):
    36 		return len(self.cells)
    37 
    38 	def __str__(self):
    39 		pass
    40 
    41 import copy
    42 
    43 class Rule(object):
    44 
    45 	def iterate(self, oldgrid):
    46 		grid = copy.deepcopy(oldgrid)
    47 		for x in xrange(oldgrid.minx - 1, oldgrid.maxx + 2):
    48 			for y in xrange(oldgrid.miny - 1, oldgrid.maxy + 2):
    49 				#print x, y, self.neighbours(oldgrid, x, y)
    50 				n = self.neighbours(oldgrid, (x, y))
    51 				if n > 2:
    52 					grid.set((x, y))					
    53 		return grid
    54 
    55 	def neighbours(self, grid, (testx, testy)):
    56 		n = 0
    57 		#print "testing ", testx, testy
    58 		for x in range(testx - 1, testx + 2):
    59 			for y in range(testy - 1, testy + 2):
    60 				if (x, y) in grid.cells:
    61 					n += 1
    62 				#print x, y, n
    63 		return n 
    64 	
    65 
    66 class Rule2(object):
    67 
    68 	def iterate(self, oldgrid):
    69 		grid = copy.deepcopy(oldgrid)
    70 		for x in xrange(oldgrid.minx - 1, oldgrid.maxx + 2):
    71 			for y in xrange(oldgrid.miny, oldgrid.maxy + 2):
    72 				#print "testing ", x, y,
    73 				if (x+1, y) in oldgrid.cells or (x, y-1) in oldgrid.cells:
    74 					grid.set((x, y), 1)								
    75 		return grid
    76 
    77 import random
    78 import marshal
    79 
    80 class PotentialGrowth(object):
    81 		
    82 	def __init__(self):
    83 		random.seed()
    84 
    85 	def iterate(self, oldgrid):
    86 		grid = copy.deepcopy(oldgrid)
    87 		for cell in oldgrid.cells.iteritems():
    88 			pos = cell[0]
    89 			value = cell[1]
    90 			if value > 1:
    91 				new_pos, new_value = self.grow(grid, pos)
    92 				grid.set(new_pos, new_value)
    93 				grid.set(pos, value - 1)
    94 		return grid
    95 
    96 	def grow(self, grid, (x, y)):
    97 		neighbours = [(x-1, y), (x, y+1), (x+1, y), (x, y-1)]
    98 		neighbours = [n for n in neighbours if n not in grid.cells]
    99 		try:
   100 			pos = random.choice(neighbours)	
   101 			value = 4
   102 		except IndexError:
   103 			pos = (x, y)
   104 			value = grid.cells[pos]
   105 		return pos, value
   106 
   107 import sys
   108 import math
   109 
   110 def ruleTest():
   111 	rule = Rule()
   112 	grid = Grid()
   113 	grid.set((0, 0))
   114 	grid.set((0, 1)).set((1, 0)).set((0, -1)).set((-1, 0))
   115 	
   116 	
   117 	print "iteration radius(diff) area(diff) pi"
   118 
   119 	iterations = int(sys.argv[1])
   120 
   121 	for i in range(iterations):
   122 		A = len(grid)
   123 		r = grid.width() / 2.0
   124 		r_ideal = math.sqrt(A / math.pi)
   125 		A_ideal = r**2 * math.pi
   126 		pi = A / r**2
   127 		print "%i %f(%f) %i(%i) %f" % (i, r, r - r_ideal, 
   128 										A, A - A_ideal, pi)
   129 
   130 		grid = rule.iterate(grid)
   131 		dumpGrid(grid, "grid.cfg")
   132 		#print
   133 
   134 def rule2Test():
   135 	rule = Rule2()
   136 	grid = Grid()
   137 	grid.set((0, 0)).set((-1, 0)).set((0, 1))
   138 	olda = 1
   139 
   140 	iterations = int(sys.argv[1])
   141 
   142 	for i in range(iterations):
   143 		a =  (float(len(grid)) - grid.width()) * 4.0
   144 		pi = 1.0 / ((grid.width()-1)**2 / ((a + olda) / 2.0))
   145 		print i, grid.width(), len(grid), pi
   146 		grid = rule.iterate(grid)
   147 		olda = a
   148 		dumpGrid(grid, "grid.cfg")
   149 
   150 def potentialTest():
   151 	rule = PotentialGrowth()
   152 	grid = Grid()
   153 	grid.set((0, 0), 4)
   154 
   155 	iterations = int(sys.argv[1])
   156 
   157 	for i in range(iterations):
   158 		A = len(grid)
   159 		r = grid.width() / 4.0 + grid.height() / 4.0
   160 		r_ideal = math.sqrt(A / math.pi)
   161 		A_ideal = r**2 * math.pi
   162 		pi = A / r**2
   163 		print "%i %f(%f) %i(%i) %f" % (i, r, r - r_ideal, 
   164 										A, A - A_ideal, pi)
   165 
   166 		grid = rule.iterate(grid)
   167 		dumpGrid(grid, "grid.cfg")
   168 
   169 def main():
   170 	ruleTest()
   171 	#rule2Test()
   172 	#potentialTest()
   173 
   174 if __name__ == "__main__":
   175 	main()