Exemple #1
0
def goto(newgen):
    currgen = int(g.getgen())
    
    if newgen < currgen:
        # try to go back to starting gen (not necessarily 0) and
        # then forwards to newgen; note that reset() also restores
        # algorithm and/or rule, so too bad if user changed those
        # after the starting info was saved;
        # first save current location and scale
        midx, midy = g.getpos()
        mag = g.getmag()
        g.reset()
        # restore location and scale
        g.setpos(midx, midy)
        g.setmag(mag)
        # current gen might be > 0 if user loaded a pattern file
        # that set the gen count
        currgen = int(g.getgen())
        if newgen < currgen:
            g.error("Can't go back any further; pattern was saved " +
                    "at generation " + str(currgen) + ".")
            return
    if newgen == currgen: return

    oldsecs = time()

    # before stepping we advance by 1 generation, for two reasons:
    # 1. if we're at the starting gen then the *current* step size
    #    will be saved (and restored upon Reset/Undo) rather than a
    #    possibly very large step size
    # 2. it increases the chances the user will see updates and so
    #    get some idea of how long the script will take to finish
    #    (otherwise if the base is 10 and a gen like 1,000,000,000
    #    is given then only a single step() of 10^9 would be done)
    g.run(1)
    currgen += 1

    # use fast stepping (thanks to PM 2Ring)
    oldstep = g.getstep()
    for i, d in enumerate(intbase(newgen - currgen, g.getbase())):
        if d > 0:
            g.setstep(i)
            for j in xrange(d):
                if g.empty():
                    g.show("Pattern is empty.")
                    return
                g.step()
                newsecs = time()
                if newsecs - oldsecs >= 1.0:  # do an update every sec
                    oldsecs = newsecs
                    g.update()
    g.setstep(oldstep)
Exemple #2
0
    def Placement(self, movementData, idx, attachedPatList, snip):

        while True:

            event = g.getevent()

            if event == "":
                self.ManageMove(attachedPatList[idx], movementData)

            elif "click" in event:

                if "right" in event:

                    movementData.RevertState()
                    idx = (idx + 1) % len(attachedPatList)

                    movementData = self.GetMovementData(attachedPatList, idx)
                    self.ManageMove(attachedPatList[idx], movementData)

                elif "left" in event:

                    if snip == None:
                        snip = PlacementSnippet(attachedPatList, idx,
                                                movementData)
                        self.snippets.append(snip)
                    else:
                        snip.Update(attachedPatList, idx, movementData)

                    movementData.UpdateCellDictionary(self.smarCells, snip.id)

                    return

            elif "key" in event:
                if "space" in event:
                    for i in xrange(0, 30):
                        g.run(60)
                        g.update()

                    g.reset()
                    g.update()

                elif "right" in event:
                    movementData.delta += 1

                elif "left" in event:
                    movementData.delta -= 1

                elif "delete" in event:

                    movementData.RevertState()
                    g.update()
                    return
Exemple #3
0
def goto(newgen):
    currgen = int(g.getgen())

    if newgen < currgen:
        # try to go back to starting gen (not necessarily 0) and
        # then forwards to newgen; note that reset() also restores
        # algorithm and/or rule, so too bad if user changed those
        # after the starting info was saved;
        # first save current location and scale
        midx, midy = g.getpos()
        mag = g.getmag()
        g.reset()
        # restore location and scale
        g.setpos(midx, midy)
        g.setmag(mag)
        # current gen might be > 0 if user loaded a pattern file
        # that set the gen count
        currgen = int(g.getgen())
        if newgen < currgen:
            g.error("Can't go back any further; pattern was saved " +
                    "at generation " + str(currgen) + ".")
            return
    if newgen == currgen: return

    oldsecs = time()

    # before stepping we advance by 1 generation, for two reasons:
    # 1. if we're at the starting gen then the *current* step size
    #    will be saved (and restored upon Reset/Undo) rather than a
    #    possibly very large step size
    # 2. it increases the chances the user will see updates and so
    #    get some idea of how long the script will take to finish
    #    (otherwise if the base is 10 and a gen like 1,000,000,000
    #    is given then only a single step() of 10^9 would be done)
    g.run(1)
    currgen += 1

    # use fast stepping (thanks to PM 2Ring)
    oldstep = g.getstep()
    for i, d in enumerate(intbase(newgen - currgen, g.getbase())):
        if d > 0:
            g.setstep(i)
            for j in xrange(d):
                if g.empty():
                    g.show("Pattern is empty.")
                    return
                g.step()
                newsecs = time()
                if newsecs - oldsecs >= 1.0:  # do an update every sec
                    oldsecs = newsecs
                    g.update()
    g.setstep(oldstep)
	def Placement(self, movementData, idx, attachedPatList, snip):
		
		while True:
		
			event = g.getevent()
			
			if event == "":
				self.ManageMove(attachedPatList[idx], movementData)
				
			elif "click" in event:
				
				if "right" in event: 
			
					movementData.RevertState()
					idx = (idx + 1) % len(attachedPatList)
					
					movementData = self.GetMovementData(attachedPatList, idx)
					self.ManageMove(attachedPatList[idx], movementData)
					
				elif "left" in event: 
					
					if snip == None:
						snip = PlacementSnippet(attachedPatList, idx, movementData)
						self.snippets.append(snip)
					else:
						snip.Update(attachedPatList, idx, movementData)
						
					movementData.UpdateCellDictionary(self.smarCells, snip.id)
					
					return 
				
			elif "key" in event:
				if "space" in event:
					for i in xrange(0, 30):
						g.run(60)
						g.update()
						
					g.reset()
					g.update()
				
				elif "right" in event:
					movementData.delta += 1
					
				elif "left" in event:
					movementData.delta -= 1
				
				elif "delete" in event: 
				
					movementData.RevertState()
					g.update()
					return 
def run_patt(known_cells):
    global patt_count, meth_count
    g.new("PlutoniumSearch")
    g.reset()
    g.update()
    patt_count += 1
    #patt = g.parse(known_cells + "!")
    patt = g.parse(known_cells[1:] + "!")
    #g.note(known_cells[1:] + "!")
    g.putcells(patt)
    g.update()
    hashlist = {}
    for gene in range(999):
        if g.empty():
            break
        if g.hash(g.getrect()) in hashlist:
            p = int(g.getgen()) - hashlist[g.hash(g.getrect())]
            if not p in boring_periods:
                g.reset()
                g.save("p" + str(p) + "_" + str(cnt[p]) + ".rle", "rle")
                cnt[p] += 1
            break
        else:
            hashlist[g.hash(g.getrect())] = int(g.getgen())
            g.run(1)
        """
		except:
			# Pattern dies
			if int(g.getgen()) > min_lifespan:
				meth_count += 1
				newlifespan = int(g.getgen())
				g.new("Saving methuselah")
				g.putcells(patt)
				try:
					g.save("diehard-" + str(newlifespan) + ".rle", "rle")
				except:
					pass
				g.update()
				#max_final_pop = newpop
			break"""
    #g.warn(str(hashlist))
    g.show(str(patt_count) + "/" + str(2**(bx * by)))
Exemple #6
0
def gt_setup(gen):
   currgen = int(g.getgen())
   # Remove leading '+' or '-' if any, and convert rest to int or long
   if gen[0] == '+':
      n = int(gen[1:])
      newgen = currgen + n
   elif gen[0] == '-':
      n = int(gen[1:])
      if currgen > n:
         newgen = currgen - n
      else:
         newgen = 0
   else:
      newgen = int(gen)
   
   if newgen < currgen:
      # try to go back to starting gen (not necessarily 0) and
      # then forwards to newgen; note that reset() also restores
      # algorithm and/or rule, so too bad if user changed those
      # after the starting info was saved;
      # first save current location and scale
      midx, midy = g.getpos()
      mag = g.getmag()
      g.reset()
      # restore location and scale
      g.setpos(midx, midy)
      g.setmag(mag)
      # current gen might be > 0 if user loaded a pattern file
      # that set the gen count
      currgen = int(g.getgen())
      if newgen < currgen:
         g.error("Can't go back any further; pattern was saved " +
                 "at generation " + str(currgen) + ".")
         return 0
      return newgen - currgen
   elif newgen > currgen:
      return newgen - currgen
   else:
     return 0
Exemple #7
0
def gt_setup(gen):
    currgen = int(g.getgen())
    # Remove leading '+' or '-' if any, and convert rest to int or long
    if gen[0] == '+':
        n = int(gen[1:])
        newgen = currgen + n
    elif gen[0] == '-':
        n = int(gen[1:])
        if currgen > n:
            newgen = currgen - n
        else:
            newgen = 0
    else:
        newgen = int(gen)

    if newgen < currgen:
        # try to go back to starting gen (not necessarily 0) and
        # then forwards to newgen; note that reset() also restores
        # algorithm and/or rule, so too bad if user changed those
        # after the starting info was saved;
        # first save current location and scale
        midx, midy = g.getpos()
        mag = g.getmag()
        g.reset()
        # restore location and scale
        g.setpos(midx, midy)
        g.setmag(mag)
        # current gen might be > 0 if user loaded a pattern file
        # that set the gen count
        currgen = int(g.getgen())
        if newgen < currgen:
            g.error("Can't go back any further; pattern was saved " +
                    "at generation " + str(currgen) + ".")
            return 0
        return newgen - currgen
    elif newgen > currgen:
        return newgen - currgen
    else:
        return 0
Exemple #8
0
soupfilepath = "/home/scorbie/Apps/ptbtest/random"
nsoups = int(g.getstring("How many soups?", "1000"))
soupsize = 10  # int(g.getstring('Soup size?', '10'))

if g.getrule() == "LifeHistory":
    g.setrule("B3/S23")
if g.numstates() > 2:
    g.exit("This script only works with two-state rules.")

soups = []
x, y, w, h = r = [0, 0, soupsize, soupsize]
cellchar = [".", "a"]
while len(soups) < nsoups:
    g.new("Generating Soups")
    g.select(r)
    g.randfill(40)
    g.run(250)
    # To avoid 'Empty Pattern!' messages in status bar.
    if int(g.getpop()) == 0:
        continue
    if not q.testquiescence(60):
        g.reset()
        soupstr = "!".join(
            "".join(cellchar[g.getcell(i, j)] for j in xrange(0, soupsize + 1)) for i in xrange(0, soupsize + 1)
        )
        soups.append(soupstr)
        g.show("Soup {}/{}".format(len(soups), nsoups))
with open(soupfilepath, "w") as soupfile:
    soupfile.write("\n".join(soups))
    g.show("Soups successfully saved in {}.".format(soupfilepath))
# 4. procura o testosc.py na pasta de Scripts e clica nele, irá rodar

import golly as g
import OSC as osc
from time import sleep

# para quem enviaremos as msgs OSC
END_SERV = '127.0.0.1'
PORTA_SERV = 9000

# criamos um cliente OSC e enviamos a mensagem com as céluas
cliente = osc.OSCClient()
cliente.connect((END_SERV, PORTA_SERV))

# reinicia tudo (pattern, contador de gerações, ...)
g.reset()

i = 0
while True:
    # mostramos no status a geração atual
    g.show("Geração: %s" % (int(g.getgen()) + 1))

    # pegamos todas as células do retângulo atual mostrado na tela
    celulas = g.getcells(g.getrect())

    # criamos uma msg OSC e enviamos usando o cliente OSC
    msg = osc.OSCMessage()
    msg.setAddress("/golly")
    msg.append(celulas)
    cliente.send(msg)
	def Main(self):
		
		g.show("left click on a pattern to change, 'h' for help")
		gollyMode = False
		
		while True:
		
			event = g.getevent()
			
			if ("key" in event and "return" in event) or (gollyMode and " a " in event):
				gollyMode = not gollyMode
				
				if gollyMode:
					g.show("In golly mode")
					g.update()

				else: 
					g.show("left click on a pattern, right click to finish")
					g.setrule("B3/S23")
					g.setalgo("HashLife")
					g.reset()
				
					g.update()
				
				continue 
				
			if gollyMode:
				
				if " delete " in event: 
					g.clear(0)
					
				if "click" in event and "ctrl" in event and g.getxy() != "":
					
					x, y = g.getxy().split()
					
					cell = g.getcell(int(x), int(y))
					
					if cell >= 0 and cell <= 1:
						g.setcell(int(x), int(y), 1 - cell)
					
					g.update()
				
				if " c " in event and "ctrl" in event and g.getselrect() != []:	
					g.copy()
				
				if " v " in event and "ctrl" in event and g.getxy() != "":
				
					x, y = g.getxy().split()
					
					g.paste(int(x), int(y), "or")
				
				if " space " in event:	
					if "ctrl" in event:
						g.run(10)
					else:
						g.run(1)
						
				g.doevent(event)
				continue 
				
			
			if "click" in event:
				
				if "left" in event:
					
					if self.ExistinCircuitHandler() == None:
						if self.SignalClickHandler(event) == None:
							g.show("left click on a pattern, h for help")
		
		
			elif "key" in event:
				if " space " in event:
					for i in xrange(0, 30):
						g.run(60)
						g.update()
						
					g.reset()
					g.update()		
					
				if " a " in event:
					
					if g.getrule() == "Perrier":
						g.setrule("B3/S23")
						g.setalgo("HashLife")
						g.update()
						
						
					else:
						g.setrule("Perrier")
						
						for key in self.smarCells:
							x, y = key.split(":")
							g.setcell(int(x), int(y),  self.smarCells[key] + 2)
						
						gollyMode = True
						g.show("In golly mode")
						g.update()
				
				if " s " in event:
					fname = os.path.join(g.getdir("data"), "MetadataManager.json")
					#self.Save(fname)
				
				if " h " in event:
					noteMessage = "Viewing and Selecting\n\n"
					noteMessage += "'left click' to chose gun or glider\n"
					noteMessage += "'a' to see in colors, a to go back \n"
					noteMessage += "'space' see ahead 1800 generations \n"
					noteMessage += "'enter' gollyMode, stays in the script \n"
					
					noteMessage += "\n Editing Gun \n\n"
					noteMessage += "'left click' to place\n"
					noteMessage += "'right click' to switch gun/orientation \n"
					noteMessage += "'delete' to delete the gun \n"
					noteMessage += "'left-right arrow' - one step adjustment\n"
					
					noteMessage += "\n In Golly Mode \n\n"
					noteMessage += "'delete' to clear selection\n"
					noteMessage += "'ctrl' + 'click' to draw \n"
					noteMessage += "'ctrl' + 'c' to copy selection \n"
					noteMessage += "'ctrl' + 'v' to paste in mouse location \n"
					noteMessage += "'space' + to run 1 generation \n"
					noteMessage += "'ctrl' +'space' to run 10 generations \n"
				
					g.note(noteMessage)
def main( step = 1, start = 0 ):
	global bound, expand

	g.reset()
	g.run(otcaDur)

	# get current Golly states
	cellWidth = 2048
	bound[ 0 ] = bound[0] * cellWidth
	bound[ 1 ] = bound[1] * cellWidth
	bound[ 2 ] = bound[2] * cellWidth
	bound[ 3 ] = bound[3] * cellWidth

	left   = bound[ 0 ]
	top    = bound[ 1 ]
	width  = bound[ 2 ]
	height = bound[ 3 ]

	palette = getPalette()
	cells = g.getcells( [0, 0, 1, 1] )
	isMultiStates = len(cells) % 2 == 1
	cellW = 2

	# create image and destination directory
	dstDir = "%s/%s" % (exportDir, name)
	if not os.path.exists( dstDir ):
		os.makedirs( dstDir )
	# else:
	# 	g.note( "destination folder already exists" )
	# 	g.exit()

	imgWidth = int( width / ratio )
	imgHeight = int ( height / ratio )

	boundWidth = ratio / subdiv


	pb = [0, 0, boundWidth, boundWidth] # pixel bound

	i = x = y = bx = by = 0

	frameCount = 0
	step = int(otcaDur / duration)

	for i in xrange(0, duration):
		g.show("Processing... %d / %d" % (i+1, duration))
		g.run(step)
		g.update()

		img = Image.new("RGB", (imgWidth, imgHeight))

		for y in xrange(imgHeight):
			for x in xrange(imgWidth):

				for by in xrange(0, subdiv, skipBound):
					for bx in xrange(0, subdiv, skipBound):
						pb[0] = left + x * ratio + bx * boundWidth
						pb[1] = top  + y * ratio + by * boundWidth
						cells = g.getcells(pb)
						if len( cells ) > 0:
							img.putpixel((x, y), (255, 255, 255))
							break

					else:
						continue
					break

		# save
		# img.save( "%s/%s_%02dx_%s_%08d.png" % (dstDir, name, ratio, mode, i) )
		# img.save( "%s/%s_%02dx_%08d.png" % (dstDir, name, ratio, i) )
		img.save("%s/%s_%04d.png" % (dstDir, name, i))


	g.show("Done.")
Exemple #12
0
    def Main(self):

        g.show("left click on a pattern to change, 'h' for help")
        gollyMode = False

        while True:

            event = g.getevent()

            if ("key" in event and "return" in event) or (gollyMode
                                                          and " a " in event):
                gollyMode = not gollyMode

                if gollyMode:
                    g.show("In golly mode")
                    g.update()

                else:
                    g.show("left click on a pattern, right click to finish")
                    g.setrule("B3/S23")
                    g.setalgo("HashLife")
                    g.reset()

                    g.update()

                continue

            if gollyMode:

                if " delete " in event:
                    g.clear(0)

                if "click" in event and "ctrl" in event and g.getxy() != "":

                    x, y = g.getxy().split()

                    cell = g.getcell(int(x), int(y))

                    if cell >= 0 and cell <= 1:
                        g.setcell(int(x), int(y), 1 - cell)

                    g.update()

                if " c " in event and "ctrl" in event and g.getselrect() != []:
                    g.copy()

                if " v " in event and "ctrl" in event and g.getxy() != "":

                    x, y = g.getxy().split()

                    g.paste(int(x), int(y), "or")

                if " space " in event:
                    if "ctrl" in event:
                        g.run(10)
                    else:
                        g.run(1)

                g.doevent(event)
                continue

            if "click" in event:

                if "left" in event:

                    if self.ExistinCircuitHandler() == None:
                        if self.SignalClickHandler(event) == None:
                            g.show("left click on a pattern, h for help")

            elif "key" in event:
                if " space " in event:
                    for i in xrange(0, 30):
                        g.run(60)
                        g.update()

                    g.reset()
                    g.update()

                if " a " in event:

                    if g.getrule() == "Perrier":
                        g.setrule("B3/S23")
                        g.setalgo("HashLife")
                        g.update()

                    else:
                        g.setrule("Perrier")

                        for key in self.smarCells:
                            x, y = key.split(":")
                            g.setcell(int(x), int(y), self.smarCells[key] + 2)

                        gollyMode = True
                        g.show("In golly mode")
                        g.update()

                if " s " in event:
                    fname = os.path.join(g.getdir("data"),
                                         "MetadataManager.json")
                    #self.Save(fname)

                if " h " in event:
                    noteMessage = "Viewing and Selecting\n\n"
                    noteMessage += "'left click' to chose gun or glider\n"
                    noteMessage += "'a' to see in colors, a to go back \n"
                    noteMessage += "'space' see ahead 1800 generations \n"
                    noteMessage += "'enter' gollyMode, stays in the script \n"

                    noteMessage += "\n Editing Gun \n\n"
                    noteMessage += "'left click' to place\n"
                    noteMessage += "'right click' to switch gun/orientation \n"
                    noteMessage += "'delete' to delete the gun \n"
                    noteMessage += "'left-right arrow' - one step adjustment\n"

                    noteMessage += "\n In Golly Mode \n\n"
                    noteMessage += "'delete' to clear selection\n"
                    noteMessage += "'ctrl' + 'click' to draw \n"
                    noteMessage += "'ctrl' + 'c' to copy selection \n"
                    noteMessage += "'ctrl' + 'v' to paste in mouse location \n"
                    noteMessage += "'space' + to run 1 generation \n"
                    noteMessage += "'ctrl' +'space' to run 10 generations \n"

                    g.note(noteMessage)
def main(step=1, start=0):
    global bound, expand

    g.reset()
    g.run(otcaDur)

    # get current Golly states
    cellWidth = 2048
    bound[0] = bound[0] * cellWidth
    bound[1] = bound[1] * cellWidth
    bound[2] = bound[2] * cellWidth
    bound[3] = bound[3] * cellWidth

    left = bound[0]
    top = bound[1]
    width = bound[2]
    height = bound[3]

    palette = getPalette()
    cells = g.getcells([0, 0, 1, 1])
    isMultiStates = len(cells) % 2 == 1
    cellW = 2

    # create image and destination directory
    dstDir = "%s/%s" % (exportDir, name)
    if not os.path.exists(dstDir):
        os.makedirs(dstDir)
    # else:
    # 	g.note( "destination folder already exists" )
    # 	g.exit()

    imgWidth = int(width / ratio)
    imgHeight = int(height / ratio)

    boundWidth = ratio / subdiv

    pb = [0, 0, boundWidth, boundWidth]  # pixel bound

    i = x = y = bx = by = 0

    frameCount = 0
    step = int(otcaDur / duration)

    for i in xrange(0, duration):
        g.show("Processing... %d / %d" % (i + 1, duration))
        g.run(step)
        g.update()

        img = Image.new("RGB", (imgWidth, imgHeight))

        for y in xrange(imgHeight):
            for x in xrange(imgWidth):

                for by in xrange(0, subdiv, skipBound):
                    for bx in xrange(0, subdiv, skipBound):
                        pb[0] = left + x * ratio + bx * boundWidth
                        pb[1] = top + y * ratio + by * boundWidth
                        cells = g.getcells(pb)
                        if len(cells) > 0:
                            img.putpixel((x, y), (255, 255, 255))
                            break

                    else:
                        continue
                    break

        # save
        # img.save( "%s/%s_%02dx_%s_%08d.png" % (dstDir, name, ratio, mode, i) )
        # img.save( "%s/%s_%02dx_%08d.png" % (dstDir, name, ratio, i) )
        img.save("%s/%s_%04d.png" % (dstDir, name, i))

    g.show("Done.")
def main(step=1, start=0):
    global bound, expand, duration

    # get selection and set to boundary
    bound = g.getselrect()

    if duration == None:
        duration = int(g.getgen())

    if isReset:
        g.reset()

    if len(bound) == 0:
        g.note("No selection.")
        g.exit()

        # get current Golly states
    bound[0] -= expand
    bound[1] -= expand
    bound[2] += expand * 2
    bound[3] += expand * 2

    left = bound[0]
    top = bound[1]
    width = bound[2]
    height = bound[3]

    palette = getPalette()
    cells = g.getcells(bound)
    isMultiStates = len(cells) % 2 == 1
    cellW = 3 if isMultiStates else 2

    # create image and destination directory
    dstDir = "%s/%s" % (exportDir, name)
    if not os.path.exists(dstDir):
        os.makedirs(dstDir)
        # else:
        # 	g.note( "destination folder already exists" )
        # 	g.exit()

        # log( cells )

    for i in xrange(duration):
        g.show("Processing... %d / %d" % (i + 1, duration))
        g.run(1)
        g.update()
        cells = g.getcells(bound)

        # create image
        img = Image.new("RGB", (width, height))
        cellLen = int(floor(len(cells) / cellW) * cellW)

        for i in xrange(0, cellLen, cellW):
            x = cells[i]
            y = cells[i + 1]
            state = cells[i + 2] if isMultiStates else 1
            img.putpixel((x - left, y - top), palette[state])

            # save
        gen = int(g.getgen())
        img.save("%s/%s_%08d.png" % (dstDir, name, gen))
def main( step = 1, start = 0 ):
	global bound, expand, duration

	# get selection and set to boundary
	bound = g.getselrect()

	if duration == None:
		duration = int( g.getgen() )

	if isReset:
		g.reset()

	if len( bound ) == 0:
		g.note( "No selection." )
		g.exit()

	# get current Golly states
	if bound == None:
		bound[ 0 ] -= expand
		bound[ 1 ] -= expand
		bound[ 2 ] += expand * 2
		bound[ 3 ] += expand * 2

	left   = bound[ 0 ]
	top    = bound[ 1 ]
	width  = bound[ 2 ]
	height = bound[ 3 ]

	palette = getPalette()
	cells = g.getcells( bound )
	isMultiStates = len(cells) % 2 == 1
	cellW = 3 if isMultiStates else 2

	# create image and destination directory
	dstDir = "%s/%s" % (exportDir, name)
	if not os.path.exists( dstDir ):
		os.makedirs( dstDir )
	# else:
	# 	g.note( "destination folder already exists" )
	# 	g.exit()

	# log( cells )

	for i in xrange( duration ):
		g.show( "Processing... %d / %d" % (i+1, duration) )
		g.run( 1 )
		g.update()
		cells = g.getcells( bound )

		# create image
		img = Image.new( "RGB", ( width, height ) )
		cellLen = int( floor( len(cells)/cellW ) * cellW )

		for i in xrange( 0, cellLen, cellW ):
			x = cells[ i ]
			y = cells[ i + 1 ]
			state = cells[ i + 2 ] if isMultiStates else 1
			img.putpixel( (x-left, y-top), palette[state] )

		# save
		gen = int( g.getgen() )
		img.save( "%s/%s_%08d.png" % (dstDir, name, gen) )