The Game of Life with a twist.

Community Forums/Showcase/The Game of Life with a twist.

Nate the Great(Posted 2009) [#1]
I decided to make a copy of the game of life. The rules can be found here.
http://en.wikipedia.org/wiki/Conway's_Game_of_Life

So after making a standard version, I figured why not add a twist. So I added a rule to the game of life. The new rule is that there is a certain probability that the game will make a mistake causing some random dots, these dots randomly form life and eventually the screen is filled with life. It doesnt serve much more purpose than that.

Here is the download:
http://naillproductions.synthasite.com/resources/Life/Life.zip

And a screen shot:




Warpy(Posted 2009) [#2]
Cool. Now make a stable structure.

I like your file names!


Blitzplotter(Posted 2009) [#3]
Looks interesting ;)


Tachyon(Posted 2009) [#4]
Interesting.

I'd like to see Game of Life with a chance of mutation thrown in, so that every once in a while a pixel is made that violates the rules and thrives with one more or one less neighbor. It can then pass this new trait to it's offspring.


Shambler(Posted 2009) [#5]
How about different types of life ( represented by different colours ) that react to each other in different ways when they meet.


Nate the Great(Posted 2009) [#6]
wow some interesting ideas... Ill try them out.


Yahfree(Posted 2009) [#7]
Or.. Going on the mutation thing, try some different traits (colors, abilities such as shifting, size, etc) that get passed down when they reproduce.


Chroma(Posted 2009) [#8]
Lol I thot this was a remake of the boardgame!


Yahfree(Posted 2009) [#9]
I made a game of life clone thingy too:

SuperStrict
AppTitle = "The Game of Life"
Graphics 800, 600
SeedRnd MilliSecs()

Const GRIDSIZE:Int = 10
Global IsGoing:Byte
Global mousegridx:Int, mousegridy:Int
Global StepTimer:Int = 29
Global CREATURES:Byte[800 / GRIDSIZE, 600 / GRIDSIZE]

Type TCreatureHandler
	Global TCreatureHandlerList:TList = CreateList()
	
	Function DrawCreatures()
		For Local X:Int = 0 To (800 / GRIDSIZE) - 1
			For Local Y:Int = 0 To (600 / GRIDSIZE) - 1
				If TCreatureHandler.GetStatus(X, Y)
					Local DrawX:Int = X + 1
					Local DrawY:Int = Y + 1
					DrawRect (DrawX * GRIDSIZE) - GRIDSIZE, (DrawY * GRIDSIZE) - GRIDSIZE, GRIDSIZE, GRIDSIZE
				End If
			Next
		Next
	End Function
	
	Function UpdateCreatures()
		StepTimer:+1
		If StepTimer < 30 Return
		If StepTimer = 30 StepTimer = 0
		Local aliveneighbors:Int = 0
		For Local X:Int = 0 To (800 / GRIDSIZE) - 1
			For Local Y:Int = 0 To (600 / GRIDSIZE) - 1
				aliveneighbors:Int = 0
				If TCreatureHandler.GetStatus(X, Y)
					'check neighbors
					If TCreatureHandler.GetStatus(X, Y - 1) aliveneighbors:+1 'top
					If TCreatureHandler.GetStatus(X, Y + 1) aliveneighbors:+1 'bottom
					If TCreatureHandler.GetStatus(X - 1, Y) aliveneighbors:+1 'left
					If TCreatureHandler.GetStatus(X + 1, Y) aliveneighbors:+1 'right
					If TCreatureHandler.GetStatus(X + 1, Y - 1) aliveneighbors:+1 'top-right
					If TCreatureHandler.GetStatus(X + 1, Y + 1) aliveneighbors:+1 'bottom-right
					If TCreatureHandler.GetStatus(X - 1, Y - 1) aliveneighbors:+1 'top-left
					If TCreatureHandler.GetStatus(X - 1, Y + 1) aliveneighbors:+1 'bottom-left
					'dies if less than two alive neighbors
					If aliveneighbors < 2 CREATURES[X, Y] = False
					'dies if more than three alive neighbors
					If aliveneighbors > 3 CREATURES[X, Y] = False
					'lives on if it has two or three live neighbors
					If aliveneighbors = 2 Or aliveneighbors = 3 CREATURES[X, Y] = True
				Else
					'check neighbors
					If TCreatureHandler.GetStatus(X, Y - 1) aliveneighbors:+1 'top
					If TCreatureHandler.GetStatus(X, Y + 1) aliveneighbors:+1 'bottom
					If TCreatureHandler.GetStatus(X - 1, Y) aliveneighbors:+1 'left
					If TCreatureHandler.GetStatus(X + 1, Y) aliveneighbors:+1 'right
					If TCreatureHandler.GetStatus(X + 1, Y - 1) aliveneighbors:+1 'top-right
					If TCreatureHandler.GetStatus(X + 1, Y + 1) aliveneighbors:+1 'bottom-right
					If TCreatureHandler.GetStatus(X - 1, Y - 1) aliveneighbors:+1 'top-left
					If TCreatureHandler.GetStatus(X - 1, Y + 1) aliveneighbors:+1 'bottom-left
					
					'dead becomes alive if it has exactly 3 neighbors
					If aliveneighbors = 3 Then CREATURES[X, Y] = True
				End If
			Next
		Next
	End Function
	
	Function ToggleLife(_x:Int, _y:Int)
		Local x:Int = (_x)
		Local y:Int = (_y)
		CREATURES[x, y] = Not CREATURES[x, y]
	End Function
	
	Function GetStatus:Byte(_x:Int, _y:Int)
		Local x:Int = (_x)
		Local y:Int = (_y)
		If x > (800 / GRIDSIZE) - 1 Or y > (600 / GRIDSIZE) - 1 Or x < 0 Or y < 0
			Return False
		End If
		Return CREATURES[x, y]
	End Function
	
	Function EraseAll()
		For Local X:Int = 0 To (800 / GRIDSIZE) - 1
			For Local Y:Int = 0 To (600 / GRIDSIZE) - 1
				CREATURES[X, Y] = False
			Next
		Next
	End Function
	
End Type



ReDraw()
While Not KeyHit(KEY_ESCAPE) Or AppTerminate()
		CheckInput()
		If IsGoing
			TCreatureHandler.UpdateCreatures()

			ReDraw()
		Else
			ReDraw()
		End If
Wend


Function CheckInput()
		mousegridx = MouseX() / GRIDSIZE * GRIDSIZE
		mousegridy = MouseY() / GRIDSIZE * GRIDSIZE
		If KeyHit(KEY_SPACE) IsGoing = Not IsGoing StepTimer = 29 ReDraw()
		If MouseHit(1) TCreatureHandler.ToggleLife(mousegridx / GRIDSIZE, mousegridy / GRIDSIZE) ReDraw()
		If MouseHit(2) TCreatureHandler.EraseAll()
End Function

Function ReDraw()
	Cls
		TCreatureHandler.DrawCreatures()
		SetColor 255, 0, 0
		If IsGoing
			DrawText "Press Space to STOP Simulation", 0, 0
		Else
			DrawText "Press Space to START Simulation", 0, 0
		End If
		DrawText StepTimer, 0, 20
		DrawRect mousegridx, mousegridy, GRIDSIZE, GRIDSIZE
		DrawText TCreatureHandler.GetStatus(mousegridx / GRIDSIZE, mousegridy / GRIDSIZE), 0, 50
		SetColor 255, 255, 255
	Flip 1
End Function


Although, I must be doing the cell logic wrong according to the wiki, some patterns on mine are different. Does anyone know what I'm doing wrong?

Specifically the gilder(it should move):

--[]
----[]
[][][]

PS: you can change the GRIDSIZE constant, as long as it's a factor of both 800 and 600.


Nate the Great(Posted 2009) [#10]
hey Yahfree, I think I found your problem... you have two problems.

One is that you say it lives if it has 2 for 3 neighbors on this line

If aliveneighbors = 2 Or aliveneighbors = 3 CREATURES[X, Y] = True


But that means if it is not alive then it will be on if 2 or 3 of its neighbors are alive which disobeys the rule that a cell can only be born if it has exactly 3 live neighbors. now your update function should look like this (with compressed logic)


Function UpdateCreatures()
		StepTimer:+1
		If StepTimer < 30 Return
		If StepTimer = 30 StepTimer = 0
		Local aliveneighbors:Int = 0
		For Local X:Int = 0 To (800 / GRIDSIZE) - 1
			For Local Y:Int = 0 To (600 / GRIDSIZE) - 1
				aliveneighbors:Int = 0
									'check neighbors
					If TCreatureHandler.GetStatus(X, Y - 1) aliveneighbors:+1 'top
					If TCreatureHandler.GetStatus(X, Y + 1) aliveneighbors:+1 'bottom
					If TCreatureHandler.GetStatus(X - 1, Y) aliveneighbors:+1 'left
					If TCreatureHandler.GetStatus(X + 1, Y) aliveneighbors:+1 'right
					If TCreatureHandler.GetStatus(X + 1, Y - 1) aliveneighbors:+1 'top-right
					If TCreatureHandler.GetStatus(X + 1, Y + 1) aliveneighbors:+1 'bottom-right
					If TCreatureHandler.GetStatus(X - 1, Y - 1) aliveneighbors:+1 'top-left
					If TCreatureHandler.GetStatus(X - 1, Y + 1) aliveneighbors:+1 'bottom-left
					
					'lives on if it has two or three live neighbors
					If creatures[x, y] = True And (aliveneighbors = 2 Or aliveneighbors = 3) Then   'now it reads the original and modifies the temporary grid
						CREATUREStmp[X, Y] = True
					Else
						CREATUREStmp[X, Y] = False
					EndIf
					If Creatures[x, y] = False And aliveneighbors = 3 Then Creaturestmp[x, y] = True
			Next
		Next
		
		copy()			'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! this line is important, it copies the tmp modified grid over the original grid.
	End Function





edit: ignore the above, I didnt see the big if statement surrounding most of the function. Your logic was correct. see below to see what was not.


so there is still one major flaw in your system, you are modifying the grid you are reading from, you must modify a temporary grid so that you modifications do not affect the grid until the next update when the temporary grid is simply copied over the real grid.

here is the fixed code.

SuperStrict
AppTitle = "The Game of Life"
Graphics 800, 600
SeedRnd MilliSecs()

Const GRIDSIZE:Int = 10
Global IsGoing:Byte
Global mousegridx:Int, mousegridy:Int
Global StepTimer:Int = 29
Global CREATURES:Byte[800 / GRIDSIZE, 600 / GRIDSIZE]
Global Creaturestmp:Byte[800 / gridsize, 600 / gridsize]

Type TCreatureHandler
	Global TCreatureHandlerList:TList = CreateList()
	
	Function DrawCreatures()
		For Local X:Int = 0 To (800 / GRIDSIZE) - 1
			For Local Y:Int = 0 To (600 / GRIDSIZE) - 1
				If TCreatureHandler.GetStatus(X, Y)
					Local DrawX:Int = X + 1
					Local DrawY:Int = Y + 1
					DrawRect (DrawX * GRIDSIZE) - GRIDSIZE, (DrawY * GRIDSIZE) - GRIDSIZE, GRIDSIZE, GRIDSIZE
				End If
			Next
		Next
	End Function
	
	Function UpdateCreatures()
		StepTimer:+1
		If StepTimer < 30 Return
		If StepTimer = 30 StepTimer = 0
		Local aliveneighbors:Int = 0
		For Local X:Int = 0 To (800 / GRIDSIZE) - 1
			For Local Y:Int = 0 To (600 / GRIDSIZE) - 1
				aliveneighbors:Int = 0
									'check neighbors
					If TCreatureHandler.GetStatus(X, Y - 1) aliveneighbors:+1 'top
					If TCreatureHandler.GetStatus(X, Y + 1) aliveneighbors:+1 'bottom
					If TCreatureHandler.GetStatus(X - 1, Y) aliveneighbors:+1 'left
					If TCreatureHandler.GetStatus(X + 1, Y) aliveneighbors:+1 'right
					If TCreatureHandler.GetStatus(X + 1, Y - 1) aliveneighbors:+1 'top-right
					If TCreatureHandler.GetStatus(X + 1, Y + 1) aliveneighbors:+1 'bottom-right
					If TCreatureHandler.GetStatus(X - 1, Y - 1) aliveneighbors:+1 'top-left
					If TCreatureHandler.GetStatus(X - 1, Y + 1) aliveneighbors:+1 'bottom-left
					
					'lives on if it has two or three live neighbors
					If creatures[x, y] = True And (aliveneighbors = 2 Or aliveneighbors = 3) Then   'now it reads the original and modifies the temporary grid
						CREATUREStmp[X, Y] = True
					Else
						CREATUREStmp[X, Y] = False
					EndIf
					If Creatures[x, y] = False And aliveneighbors = 3 Then Creaturestmp[x, y] = True
			Next
		Next
		
		copy()			'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! this line is important, it copies the tmp modified grid over the original grid.
	End Function
	
	Function ToggleLife(_x:Int, _y:Int)
		Local x:Int = (_x)
		Local y:Int = (_y)
		CREATURES[x, y] = Not CREATURES[x, y]
	End Function
	
	Function GetStatus:Byte(_x:Int, _y:Int)
		Local x:Int = (_x)
		Local y:Int = (_y)
		If x > (800 / GRIDSIZE) - 1 Or y > (600 / GRIDSIZE) - 1 Or x < 0 Or y < 0
			Return False
		End If
		Return CREATURES[x, y]
	End Function
	
	Function copy()
		For Local x:Int = 0 To (800/gridsize)-1
			For Local y:Int = 0 To (600/gridsize)-1
				Creatures[x,y] = creaturestmp[x,y]
			Next
		Next
	End Function
	
	Function EraseAll()
		For Local X:Int = 0 To (800 / GRIDSIZE) - 1
			For Local Y:Int = 0 To (600 / GRIDSIZE) - 1
				CREATURES[X, Y] = False
			Next
		Next
	End Function
	
End Type



ReDraw()
While Not KeyHit(KEY_ESCAPE) Or AppTerminate()
		CheckInput()
		If IsGoing
			TCreatureHandler.UpdateCreatures()

			ReDraw()
		Else
			ReDraw()
		End If
Wend


Function CheckInput()
		mousegridx = MouseX() / GRIDSIZE * GRIDSIZE
		mousegridy = MouseY() / GRIDSIZE * GRIDSIZE
		If KeyHit(KEY_SPACE) IsGoing = Not IsGoing StepTimer = 29 ReDraw()
		If MouseHit(1) TCreatureHandler.ToggleLife(mousegridx / GRIDSIZE, mousegridy / GRIDSIZE) ReDraw()
		If MouseHit(2) TCreatureHandler.EraseAll()
End Function

Function ReDraw()
	Cls
		TCreatureHandler.DrawCreatures()
		SetColor 255, 0, 0
		If IsGoing
			DrawText "Press Space to STOP Simulation", 0, 0
		Else
			DrawText "Press Space to START Simulation", 0, 0
		End If
		DrawText StepTimer, 0, 20
		DrawRect mousegridx, mousegridy, GRIDSIZE, GRIDSIZE
		DrawText TCreatureHandler.GetStatus(mousegridx / GRIDSIZE, mousegridy / GRIDSIZE), 0, 50
		SetColor 255, 255, 255
	Flip 1
End Function




Yahfree(Posted 2009) [#11]
Thanks Nate.