import sys
import random
import Image, ImageDraw,ImageColor

# probability that tree exists when creating forest
p = 0.5

# probability that cell spontaneously cathes fire 
f = 0.00005

# pixel width to scale image
scale = 3

EMPTY = ImageColor.getcolor("#B19E7E","RGB")
TREE = ImageColor.getcolor("#576E4A","RGB")
FIRE = ImageColor.getcolor("#C6000E","RGB")

class ffsim:
	forest = [[0 for col in range(128)] for row in range(128)]
	frame = 1000

	def save_frames(self):
		fp = open("fire.gif", "wb")
		fp.close()   

	def render_frame(self):
		im = Image.new("RGB",(128*scale,128*scale), (255,255,255))
		draw = ImageDraw.Draw(im)
		for x in xrange(128):
			for y in xrange(128):
				draw.rectangle([(x*scale,y*scale),((x*scale)+scale,(y*scale)+scale)],fill=self.forest[x][y],outline=self.forest[x][y])
		del draw
		im.save("frame_%d.png" % self.frame, "PNG")
		self.frame += 1

	def create_cell(self):
		if random.random() <= p:
			return TREE
		else:
			return EMPTY

	def create_forest(self):
		for x in xrange(128):
			for y in xrange(128):
				self.forest[x][y] = self.create_cell()

	def start_fire(self):
		x = random.randint(0,128)
		y = random.randint(0,128)
		self.forest[x][y] = FIRE

	def spontaneous_fire(self):
		if random.random() <= f:
			return True
		else:
			return False

	def valid(self,x,y):
		return x < 128 and x >= 0 and y >= 0 and y < 128

	def neighbors(self,x,y):
		ret = []
		if self.valid(x-1,y-1):
			ret.append(self.forest[x-1][y-1])
		if self.valid(x-1,y+1):
			ret.append(self.forest[x-1][y+1])
		if self.valid(x+1,y+1):
			ret.append(self.forest[x+1][y+1])
		if self.valid(x+1,y-1):
			ret.append(self.forest[x+1][y-1])
		if self.valid(x,y-1):
			ret.append(self.forest[x][y-1])
		if self.valid(x-1,y):
			ret.append(self.forest[x-1][y])
		if self.valid(x,y+1):
			ret.append(self.forest[x][y+1])
		if self.valid(x+1,y):
			ret.append(self.forest[x+1][y])
		return ret


	def process_pixel(self,x,y):
		"""
			1. An empty cell becomes occupied with probability p. 
			2. A cell with a tree will burn if any of its neighbors is on fire
			3. A cell with a tree will spontaneously burn, with probability f, even if none of its neighbors is on fire
			4. A cell with a burning tree becomes an empty cell in the next time step. 
		"""
		if self.forest[x][y] == EMPTY:
			return EMPTY

		if self.forest[x][y] == FIRE:
			return EMPTY

		if self.forest[x][y] == TREE:
			if self.spontaneous_fire():
				return FIRE

			if FIRE in self.neighbors(x,y):
				return FIRE

			return TREE

	def step_time(self):
		next = [[0 for col in range(128)] for row in range(128)]
		for x in xrange(128):
			for y in xrange(128):
				next[x][y] = self.process_pixel(x,y)
		self.forest = next

		return False;


	def runsim(self):
		self.create_forest()
		self.render_frame()
		self.start_fire()
		self.render_frame()
		for i in xrange(100):
			self.step_time()
			self.render_frame()

ff = ffsim()
ff.runsim()
