# version 0.5 from Tkinter import * import random class Ant: def __init__(self,size=100,cellsize=2): self.size = size self.root = Tk() self.root.title("Ants") self.cellsize = cellsize self.celldist = self.cellsize+1 w = self.celldist*self.size self.raster = PhotoImage(width=w,height=w) self.label = Label(self.root,image=self.raster,background="grey") self.label.pack() self.root.update() self.steps = 0 self.colors = ["#ffffff","#ff0000","#00ff00","#0000ff", "#00ffff","#ff00ff","#ffff00","#000000","#80ffff"] self.x = self.size/2 self.y = self.size/2 self.dir = 3 self.initworld() # sets rule. setrule(10) and setrule("1010") are the same def setrule(self,rule): if type(rule)==type(" "): rule = int(rule,2) l = [] while rule: rule,n = divmod(rule,2) l = [n]+l self.rule = l self.states = len(self.rule) s = "" for b in l: s=s+str(b) self.root.title("Ant "+str(int(s,2))+"="+s) # clear bitmap and world def reset(self): self.x = self.size/2 self.y = self.size/2 self.dir = 3 self.steps = 0 self.initworld() self.root.update() # build empty world def initworld(self): self.world = [0]*self.size*self.size self.raster.blank() # spray some values around starting position def spray(self,num,dist): for n in range(num): v = random.randint(0,self.states-1) x = random.randint(0,2*dist)-dist+self.x y = random.randint(0,dist*2)-dist+self.y self.world[x+self.size*y] = v x,y = self.celldist*x, self.celldist*y self.raster.put(self.colors[v],(x,y,x+self.cellsize,y+self.cellsize)) self.label.update() # set a point (x/y) relative to start coordinate to value v def setpoint(self,x,y,value): x,y = x+self.size/2,y+self.size/2 self.world[x+self.size*y] = value x,y = self.celldist*x, self.celldist*y self.raster.put(self.colors[value],(x,y,x+self.cellsize,y+self.cellsize)) self.label.update() # do a single ant-step def step(self): pos = self.x+self.y*self.size v = self.world[pos] self.world[pos] = (v+1)%self.states x,y = self.celldist*self.x, self.celldist*self.y self.raster.put(self.colors[v],(x,y,x+self.cellsize,y+self.cellsize)) if self.rule[v]==0 : self.dir = (self.dir-1)%4 else: self.dir = (self.dir+1)%4 if self.dir==0: self.y -= 1 if self.y<0: return 0 elif self.dir==2: self.y += 1 if self.y>=self.size: return 0 elif self.dir==1: self.x -= 1 if self.x<0: return 0 elif self.dir==3: self.x += 1 if self.x>=self.size: return 0 return 1 # run n steps updating screen every multi steps def run(self,n=100,multi=1): for i in range(n): r = self.step() if i%multi==0: self.label.update() if r==0: break self.label.update() # not necessary def wait(self): while 1: self.root.update() ############################################################## # symmetric patterns def demo1(): a = Ant(100,3) a.setrule(9) # (60) a.run(40000,1) # highway builder def demo2(): a = Ant(150,2) a.setrule("11110") a.run(40000,20) # delayed builder def demo2a(): a = Ant(150,2) a.setrule(2) a.run(40000,20) # complex pattern def demo3(): a = Ant(100,3) a.setrule(12) a.run(40000,50) # just testing rules... def demo(rule): a = Ant(100,3) a.setrule(rule) a.run(40000,50)