An attempt at Conway’s Game of Life using PowerShell


Why did I get this itch?

Game of Life Intermediate state

Intermediate state in the game of life

While watching ‘Stephen Hawking’s Grand Design’ couple of weeks ago on Discovery channel where he talks about how conscience evolves and how simple cells could evolve into complex beings. As an example, I saw the game of life come up and show how simple starting states can evolve into complex self-sustaining groups. This got me thinking, and while investigating how we code this game of life; I found that the rules are pretty simple. So, I started looking at doing this in PowerShell.

The Origins

The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970.
Origins of the game are very interesting, according to Wikipedia, Conway was interested in a problem presented by mathematician John von Neumann, who attempted to find a hypothetical machine that could build copies of itself. The Game of Life emerged as Conway’s successful attempt to drastically simplify von Neumann’s ideas.
The “game” is a zero-player game, meaning that its evolution is determined by its initial state, requiring no further input. One interacts with the Game of Life by creating an initial configuration and observing how it evolves.

The Rules

The universe of the Game of Life is an infinite two-dimensional grid of square cells, each of which is in one of two possible states, alive or dead. Every cell interacts with its eight neighbours, which are the cells that are horizontally, vertically, or diagonally adjacent.
In each generation, the following transitions occur:

  1. Any live cell with fewer than two live neighbours dies, as if caused by under-population.
  2. Any live cell with two or three live neighbours lives on to the next generation.
  3. Any live cell with more than three live neighbours dies, as if by overcrowding.
  4. Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.

The above rules cause births and deaths at each generation and will set the seed for the next generation. And the preceding generation is a function of the previous one.

Based on the above rules each cell can have one of the following happen to it in each generation:

  1. STASIS : If, for a given cell, the number of on neighbours is exactly two, the cell maintains its status quo into the next generation. If the cell is on, it stays on, if it is off, it stays off.
  2. GROWTH : If the number of on neighbours is exactly three, the cell will be on in the next generation. This is regardless of the cell’s current state.
  3. DEATH : If the number of on neighbours is 0, 1, 4-8, the cell will be off in the next generation.

The Code

First let us look at the code that generates the next generation of cells based on the states of the current one.

#Currently Taking 10.5 Secs to generate next generation.
#consumes around 20-25% cpu.
#need to find a better way to do this.
Function Get-NextGeneration
{
	param(
	 [Int[,]]$GameMatrix
	)
	BEGIN
	{
		$tmpGameMatrix = $GameMatrix;
		#The game board for game of life is infinite. So, we simulate this by wrapping the
		#width and height.
		Function Get-WrappedWidth
		{
			param(
			    [Int]$x,
			    [Int]$xEdge
			)
			$x += $xEdge;
			while($x -lt 0){$x += $SCRIPT:BoardWidth;}
			while($x -ge $SCRIPT:BoardWidth){$x -= $SCRIPT:BoardWidth;}
			return $x;
		}

		Function Get-WrappedHeight
		{
			param(
				[Int]$y,
				[Int]$yEdge
			)
			$y += $yEdge;
			while($y -lt 0){$y += $SCRIPT:BoardHeight;}
			while($y -ge $SCRIPT:BoardHeight){$y -= $SCRIPT:BoardHeight}
			return $y;
		}

		Function Get-Neighbours
		{
			param(
				[Int[,]]$ArrayMatrix,
				[Int]$coordX,
				[Int]$coordY
			)
			[Int]$nx = 0;
			[Int]$ny = 0;
			[Int]$count = 0;
			for($nx = -1; $nx -le 1; $nx++)
			{
				for($ny = -1; $ny -le 1; $ny++)
				{
					if($nx -or $ny)
					{
						#$placeX = Get-WrappedWidth $coordX $nx
						#$placeY = Get-WrappedHeight $coordY $ny
						#We can put the function calls to get co-ords directly
						#when getting the positions in the matrix.
						#if($GameMatrix[$placeX, $placeY])
						if($ArrayMatrix[$(Get-WrappedWidth $coordX $nx), $(Get-WrappedHeight $coordY $ny)])
						{
							$count += 1;
						}
					}
				}
			}
			return $count;
		}

	}
	PROCESS
	{

		for($x = 0; $x -lt $SCRIPT:BoardWidth; $x++)
		{
			for($y = 0; $y -lt $SCRIPT:BoardHeight; $y++)
			{
				$neighbors = Get-Neighbours $tmpGameMatrix $x $y
				switch($neighbors)
				{
					{($neighbors -lt 2) -or ($neighbors -gt 3)}{$tmpGameMatrix[$x, $y] = 0;}
					{($neighbors -eq 3)}{$tmpGameMatrix[$x, $y] = 1;}
				}
			}
		}

	}
	END
	{
		$GameMatrix = $tmpGameMatrix;
		#should we even do this? : return ,$GameMatrix
		return ,$GameMatrix;
	}
}

Since the code is too long to post here, I put the code on github and poshcode:
Link to github

Link to poshcode

If you look at the code, please let me know how I can improve the code. Thank you, very much.

Made a few enhancements to the code last night after I posted code. Both the codes on github and poshcode have been updated with the new changes the code  now runs a little bit faster. I still believe that there is room for improvement. So, please provide any feedback you may have.

Here are some more screeshots with the new code running.

The new code populates a complex starting state.

The new code populates a complex starting state.

GOL_IntermediateState_2

This is about 5-10minutes into the code

GOL_IntermediateState_3

About 15-20 minutes into the code run.

GOL_IntermediateState_4

After about 30minutes into the code run

About

By profession, I’m a SQL Server Database Administrator. I love to poke my nose into different corners and see how stuff looks in there. I keep looking for new things to do as my mind refuses to settle on one topic.

Tagged with: , ,
Posted in Fun-Stuff, PowerShell

Leave a comment