cellpimat.py
changeset 2 ccbf96145796
child 3 89d76549ba6e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/cellpimat.py	Thu Dec 30 02:16:10 2010 +0100
     1.3 @@ -0,0 +1,175 @@
     1.4 +class Grid(object):
     1.5 +
     1.6 +	def __init__(self):
     1.7 +		self.cells = {}
     1.8 +		self.minx = 0
     1.9 +		self.maxx = 0
    1.10 +		self.miny = 0
    1.11 +		self.maxy = 0
    1.12 +
    1.13 +	def set(self, pos, value=1):
    1.14 +		if not pos in self.cells or value != self.cells[pos]:
    1.15 +			self.cells[pos] = value
    1.16 +			self.update(pos)
    1.17 +		return self
    1.18 +
    1.19 +	def clear(self, pos):
    1.20 +		if pos in self.cells:
    1.21 +			del self.cells[pos]
    1.22 +			self.update(pos)
    1.23 +		return self
    1.24 +
    1.25 +	def update(self, (x, y)):
    1.26 +		self.minx = min(x, self.minx)
    1.27 +		self.maxx = max(x, self.maxx)
    1.28 +		self.miny = min(y, self.miny)
    1.29 +		self.maxy = max(y, self.maxy)
    1.30 +		return self
    1.31 +
    1.32 +	def width(self):
    1.33 +		return self.maxx - self.minx + 1
    1.34 +
    1.35 +	def height(self):
    1.36 +		return self.maxy - self.miny + 1
    1.37 +
    1.38 +	def __len__(self):
    1.39 +		return len(self.cells)
    1.40 +
    1.41 +	def __str__(self):
    1.42 +		pass
    1.43 +
    1.44 +import copy
    1.45 +
    1.46 +class Rule(object):
    1.47 +
    1.48 +	def iterate(self, oldgrid):
    1.49 +		grid = copy.deepcopy(oldgrid)
    1.50 +		for x in xrange(oldgrid.minx - 1, oldgrid.maxx + 2):
    1.51 +			for y in xrange(oldgrid.miny - 1, oldgrid.maxy + 2):
    1.52 +				#print x, y, self.neighbours(oldgrid, x, y)
    1.53 +				n = self.neighbours(oldgrid, (x, y))
    1.54 +				if n > 2:
    1.55 +					grid.set((x, y))					
    1.56 +		return grid
    1.57 +
    1.58 +	def neighbours(self, grid, (testx, testy)):
    1.59 +		n = 0
    1.60 +		#print "testing ", testx, testy
    1.61 +		for x in range(testx - 1, testx + 2):
    1.62 +			for y in range(testy - 1, testy + 2):
    1.63 +				if (x, y) in grid.cells:
    1.64 +					n += 1
    1.65 +				#print x, y, n
    1.66 +		return n 
    1.67 +	
    1.68 +
    1.69 +class Rule2(object):
    1.70 +
    1.71 +	def iterate(self, oldgrid):
    1.72 +		grid = copy.deepcopy(oldgrid)
    1.73 +		for x in xrange(oldgrid.minx - 1, oldgrid.maxx + 2):
    1.74 +			for y in xrange(oldgrid.miny, oldgrid.maxy + 2):
    1.75 +				#print "testing ", x, y,
    1.76 +				if (x+1, y) in oldgrid.cells or (x, y-1) in oldgrid.cells:
    1.77 +					grid.set((x, y), 1)								
    1.78 +		return grid
    1.79 +
    1.80 +import random
    1.81 +import marshal
    1.82 +
    1.83 +class PotentialGrowth(object):
    1.84 +		
    1.85 +	def __init__(self):
    1.86 +		random.seed()
    1.87 +
    1.88 +	def iterate(self, oldgrid):
    1.89 +		grid = copy.deepcopy(oldgrid)
    1.90 +		for cell in oldgrid.cells.iteritems():
    1.91 +			pos = cell[0]
    1.92 +			value = cell[1]
    1.93 +			if value > 1:
    1.94 +				new_pos, new_value = self.grow(grid, pos)
    1.95 +				grid.set(new_pos, new_value)
    1.96 +				grid.set(pos, value - 1)
    1.97 +		return grid
    1.98 +
    1.99 +	def grow(self, grid, (x, y)):
   1.100 +		neighbours = [(x-1, y), (x, y+1), (x+1, y), (x, y-1)]
   1.101 +		neighbours = [n for n in neighbours if n not in grid.cells]
   1.102 +		try:
   1.103 +			pos = random.choice(neighbours)	
   1.104 +			value = 4
   1.105 +		except IndexError:
   1.106 +			pos = (x, y)
   1.107 +			value = grid.cells[pos]
   1.108 +		return pos, value
   1.109 +
   1.110 +import sys
   1.111 +import math
   1.112 +
   1.113 +def ruleTest():
   1.114 +	rule = Rule()
   1.115 +	grid = Grid()
   1.116 +	grid.set((0, 0))
   1.117 +	grid.set((0, 1)).set((1, 0)).set((0, -1)).set((-1, 0))
   1.118 +	
   1.119 +	
   1.120 +	print "iteration radius(diff) area(diff) pi"
   1.121 +
   1.122 +	iterations = int(sys.argv[1])
   1.123 +
   1.124 +	for i in range(iterations):
   1.125 +		A = len(grid)
   1.126 +		r = grid.width() / 2.0
   1.127 +		r_ideal = math.sqrt(A / math.pi)
   1.128 +		A_ideal = r**2 * math.pi
   1.129 +		pi = A / r**2
   1.130 +		print "%i %f(%f) %i(%i) %f" % (i, r, r - r_ideal, 
   1.131 +										A, A - A_ideal, pi)
   1.132 +
   1.133 +		grid = rule.iterate(grid)
   1.134 +		dumpGrid(grid, "grid.cfg")
   1.135 +		#print
   1.136 +
   1.137 +def rule2Test():
   1.138 +	rule = Rule2()
   1.139 +	grid = Grid()
   1.140 +	grid.set((0, 0)).set((-1, 0)).set((0, 1))
   1.141 +	olda = 1
   1.142 +
   1.143 +	iterations = int(sys.argv[1])
   1.144 +
   1.145 +	for i in range(iterations):
   1.146 +		a =  (float(len(grid)) - grid.width()) * 4.0
   1.147 +		pi = 1.0 / ((grid.width()-1)**2 / ((a + olda) / 2.0))
   1.148 +		print i, grid.width(), len(grid), pi
   1.149 +		grid = rule.iterate(grid)
   1.150 +		olda = a
   1.151 +		dumpGrid(grid, "grid.cfg")
   1.152 +
   1.153 +def potentialTest():
   1.154 +	rule = PotentialGrowth()
   1.155 +	grid = Grid()
   1.156 +	grid.set((0, 0), 4)
   1.157 +
   1.158 +	iterations = int(sys.argv[1])
   1.159 +
   1.160 +	for i in range(iterations):
   1.161 +		A = len(grid)
   1.162 +		r = grid.width() / 4.0 + grid.height() / 4.0
   1.163 +		r_ideal = math.sqrt(A / math.pi)
   1.164 +		A_ideal = r**2 * math.pi
   1.165 +		pi = A / r**2
   1.166 +		print "%i %f(%f) %i(%i) %f" % (i, r, r - r_ideal, 
   1.167 +										A, A - A_ideal, pi)
   1.168 +
   1.169 +		grid = rule.iterate(grid)
   1.170 +		dumpGrid(grid, "grid.cfg")
   1.171 +
   1.172 +def main():
   1.173 +	ruleTest()
   1.174 +	#rule2Test()
   1.175 +	#potentialTest()
   1.176 +
   1.177 +if __name__ == "__main__":
   1.178 +	main()