Created
October 29, 2012 12:00
-
-
Save alcides/3973181 to your computer and use it in GitHub Desktop.
Multi-Process Game of Life (One process per shape)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import threading | |
from Tkinter import * | |
root = Tk() | |
class Shape(threading.Thread): | |
def __init__(self, grid, pos=(4,4)): | |
threading.Thread.__init__(self) | |
self.grid = grid | |
self.pos = pos | |
self.max = (20,20) | |
grid.cells[pos[0]+3][pos[1]+2].displayState(Cell.LIVE) | |
grid.cells[pos[0]+4][pos[1]+3].displayState(Cell.LIVE) | |
grid.cells[pos[0]+2][pos[1]+4].displayState(Cell.LIVE) | |
grid.cells[pos[0]+3][pos[1]+4].displayState(Cell.LIVE) | |
grid.cells[pos[0]+4][pos[1]+4].displayState(Cell.LIVE) | |
def run(self): | |
c = 0 | |
while c < 100: | |
c+=1 | |
cell = self.grid.cell | |
for x in range(self.pos[0],self.pos[0] + self.max[0]): | |
for y in range(self.pos[1],self.pos[1] + self.max[1]): | |
sum = cell(x-1, y).state + cell(x+1,y).state + \ | |
cell(x, y-1).state + cell(x, y+1).state + \ | |
cell(x-1, y-1).state + cell(x+1, y-1).state + \ | |
cell(x-1, y+1).state + cell(x+1, y+1).state | |
cell(x, y).setNextState(sum) | |
for x in range(self.pos[0],self.pos[0] + self.max[0]): | |
for y in range(self.pos[1],self.pos[1] + self.max[1]): | |
cell(x,y).stepToNextState() | |
if c % 4 == 0: | |
self.pos = (self.pos[0]+1, self.pos[1]+1) | |
class Cell(Label): | |
DEAD = 0 | |
LIVE = 1 | |
def __init__(self,parent): | |
Label.__init__(self,parent,relief="raised",width=2,borderwidth=1) | |
self.bind("<Button-1>", self.toggle) | |
self.displayState(Cell.DEAD) | |
def toggle(self,event): | |
self.displayState(1-self.state) | |
def setNextState(self,numNeighbours): | |
"""Work out whether this cell will be alive at the next iteration.""" | |
if self.state==Cell.LIVE and \ | |
(numNeighbours>3 or numNeighbours<2): | |
self.nextState = Cell.DEAD | |
elif self.state==Cell.DEAD and numNeighbours==3: | |
self.nextState = Cell.LIVE | |
else: | |
self.nextState = self.state | |
def stepToNextState(self): | |
self.displayState(self.nextState) | |
def displayState(self,newstate): | |
self.state = newstate | |
if self.state==Cell.LIVE: | |
self["bg"] = "black" | |
else: | |
self["bg"] = "white" | |
class Grid: | |
def __init__(self,parent,sizex,sizey): | |
self.sizex = sizex | |
self.sizey = sizey | |
#numpy.zeros(sizex,sizey) is a better choice, | |
#but an additional dependency might be rude... | |
self.cells = [] | |
for a in range(0,self.sizex): | |
rowcells = [] | |
for b in range(0,self.sizey): | |
c = Cell(parent) | |
c.grid(row=b, column=a) | |
rowcells.append(c) | |
self.cells.append(rowcells) | |
s = Shape(self, pos=(0,0)) | |
s.start() | |
s = Shape(self, pos=(10,20)) | |
s.start() | |
def cell(self, x, y): | |
while x >= self.sizex: | |
x -= self.sizex | |
while y >= self.sizey: | |
y -= self.sizey | |
while x < 0: | |
x += self.sizex | |
while y < 0: | |
y += self.sizey | |
return self.cells[x][y] | |
def step(self): | |
"""Calculate then display the next iteration of the game of life. | |
This function uses wraparound boundary conditions. | |
""" | |
pass | |
def clear(self): | |
for row in self.cells: | |
for cell in row: | |
cell.displayState(Cell.DEAD) | |
if __name__ == "__main__": | |
frame = Frame(root) | |
frame.pack() | |
grid = Grid(frame,25,25) | |
bottomFrame = Frame(root) | |
bottomFrame.pack(side=BOTTOM) | |
buttonStep = Button(bottomFrame,text="Step",command=grid.step) | |
buttonStep.pack(side=LEFT) | |
buttonClear = Button(bottomFrame,text="Clear",command=grid.clear) | |
buttonClear.pack(side=LEFT,after=buttonStep) | |
root.mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment