Conway’s Game of Life has simple rules, yet can breed unpredictable behaviour. The game proceeds on a regular grid as follows: you update all cells at once, cells survive if there are more than one, but less than four, cells in neighbouring sites. Dead cells are (re)born if they have exactly three neighbours. It was originally played with counters on a Go board, but rose to fame with the increasing availability of computers, which can play it faster. I won’t go into more detail because many excellent descriptions already exist:
Nevertheless, here are a couple of my implementations which may be of interest.
It is possible to play the Game of Life in a single line of Matlab. It weighs in with twice the characters of the single line of APL, but at least you can find them all on a normal keyboard. If you can see a way of condensing it from these 53 characters, claim your prize in the comment form below. . .
l=9;G=int8(rand(l));u=[2:l 1];d=[l 1:l-1];for i=u,n=G(u,:)+G(d,:)+G(:,u)+G(:,d)+G(u,u)+G(u,d)+G(d,u)+G(d,d);G=n==3|G&n==2,end
An exercise in conciseness, with the update rule complete in two statements and although it would be hard to beat a version in one line of APL, this Matlab code wins in the readability stakes! You'll need Matlab; it runs with Octave too, but creates a new window for the grid at each timestep, so move the display outside the loop (and try imshow instead).
Update - someone emailed to tell me that Matlab actually plays life as a built-in function - just type life. But having looked at the code, while the method is obviously identical to the one below, I don't mind claiming that the code here is a little more elegant.

A stage of Life, as lived by Matlab
% life.m - Conway's Game of Life % % A grid of dead and living cells is made. % Cells are born to three adjacent parents, % and die of overcrowding or loneliness. % Iain Haslam, December 2005 len=50; GRID=int8(rand(len,len)); up=[2:len 1]; down=[len 1:len-1]; %the world is round colormap(gray(2)); for i=1:100 neighbours=GRID(up,:)+GRID(down,:)+GRID(:,up)+GRID(:,down)+... GRID(up,up)+GRID(up,down)+GRID(down,up)+GRID(down,down); GRID = neighbours==3 | GRID & neighbours==2; image(GRID*2); pause(0.02); end
The code as presented here starts with a random grid of living and dead cells. If you want to see a particular pattern,
start with a blank grid GRID=zero(len,len), and add one of the following:
| Blinker | GRID(5,4:6)=1; |
| Toad | GRID(5,4:6)=1;GRID(6,3:5)=1; |
| Glider | GRID(3,1:3)=1;GRID(2,3)=1;GRID(1,2)=1; |
| Lightweight spaceship |
GRID(5,5:8)=1;GRID(4,9)=1;GRID(3:4,5)=1; GRID(2,6)=1;GRID(2,9)=1; |
| Diehard | GRID(10,10:11)=1;GRID(11,11)=1; GRID(11,15:17)=1;GRID(9,16)=1; |
The Matlab version only allows you to define the initial grid by altering the code. This Python version allows you to toggle each cell's state of health with a mouse-click.
It also serves as a concise example of how to create a useful Tk Dialog with Python. Naturally, you'll need Python and
TkInter installed to run it, but they’re both free and top notch, so go for it.
#!/usr/bin/python """A minimal implementation of Conway's Game of Life. Each cell's survival depends on the number of occupied nearest and next-nearest neighbours (calculated in Grid::step). A living cell dies of overcrowding or loneliness if it has more than three or fewer than two neighbours; a dead cell is brought to life if it has exactly three neighbours (determined in Cell::setNextState). Iain Haslam, June 2005. """ from Tkinter import * root = Tk() 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) if sizex>10 and sizey>10: #Start with a glider self.cells[10][9].displayState(Cell.LIVE) self.cells[11][10].displayState(Cell.LIVE) self.cells[9][11].displayState(Cell.LIVE) self.cells[10][11].displayState(Cell.LIVE) self.cells[11][11].displayState(Cell.LIVE) def step(self): """Calculate then display the next iteration of the game of life. This function uses wraparound boundary conditions. """ cells = self.cells for x in range(0,self.sizex): if x==0: x_down = self.sizex-1 else: x_down = x-1 if x==self.sizex-1: x_up = 0 else: x_up = x+1 for y in range(0,self.sizey): if y==0: y_down = self.sizey-1 else: y_down = y-1 if y==self.sizey-1: y_up = 0 else: y_up = y+1 sum = cells[x_down][y].state + cells[x_up][y].state + \ cells[x][y_down].state + cells[x][y_up].state + \ cells[x_down][y_down].state + cells[x_up][y_up].state + \ cells[x_down][y_up].state + cells[x_up][y_down].state cells[x][y].setNextState(sum) for row in cells: for cell in row: cell.stepToNextState() 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()
Put that into a text file, run it through Python, and you'll get:

Pylife running under Gnome