[Open source] Conway's game of life

Greetings devs!
I am now open sourcing two of my projects and this is one of them!
This is a simple implementation of the famous cellular automata - Conway’s game of life!
For anyone who does not know what that is, here is an explantation.
Demonstration:

Uncopylocked place
Download here (50.2 KB)

Source code:

-- Main
local Players = game.Players
local ReplicatedFirst = game.ReplicatedFirst
local ReplicatedStorage = game.ReplicatedStorage

-- Services
local TweenService = game:GetService("TweenService")
local UserInputService = game:GetService("UserInputService")

local Frame = script.Parent
local Settings = Frame.Parent.Settings
local CellOriginal = script.Cell

local Test = false

local Playing = false

local AliveNeighborSpawnInt, MinimumAliveNeighborAmount, MaximumAliveNeighborAmount = 3,2,3

wait(2)

local GridSize = Vector2.new(math.floor(Frame.AbsoluteSize.X / (Frame.UIGridLayout.CellSize.X.Offset + Frame.UIGridLayout.CellPadding.X.Offset)),math.floor(Frame.AbsoluteSize.Y / (Frame.UIGridLayout.CellSize.Y.Offset + Frame.UIGridLayout.CellPadding.Y.Offset)))

local CellTable = {}

local function GetCellAliveFromVector2(Vector) -- Cell coordinates go in and alive status goes out.
	-- This checks if the requested cell is out of the grid
	if Vector.X == 0 or Vector.Y == 0 or Vector.X == GridSize.X + 1 or Vector.X == GridSize.Y + 1 or CellTable[Vector.X][Vector.Y] == nil then
		return false
	end
	return CellTable[Vector.X][Vector.Y]:GetAttribute("Alive")
end

local function GenerateGrid() -- Generates grid.
	-- Deletes any old cells
	for index,value in pairs(Frame:GetChildren()) do
		if value:IsA("TextButton") then
			value:Destroy()
		end
	end
	-- Made for debuging, just couns the cells
	local Count = 0
	for Y = 1,GridSize.Y do
		for X = 1,GridSize.X do
			-- Creates cell and configures it here, gives it attributes like X,Y and Alive
			local Cell = CellOriginal:Clone()
			Cell.Parent = Frame
			-- Assigns a function to run when the cell changes the "Alive" attribute
			Cell.AttributeChanged:Connect(function(attribute)
				if attribute == "Alive" then
					if Cell:GetAttribute("Alive") == true then
						local Tween = TweenService:Create(Cell.Glow,TweenInfo.new(0.5,Enum.EasingStyle.Quad),{ImageTransparency = 0.8})
						Tween:Play()
						Cell.BackgroundColor3 = Color3.new(0.933333, 0.933333, 0.933333)
					else
						local Tween = TweenService:Create(Cell.Glow,TweenInfo.new(0.5,Enum.EasingStyle.Quad),{ImageTransparency = 1})
						Tween:Play()
						Cell.BackgroundColor3 = Color3.new(0.14902, 0.14902, 0.14902)
					end
				end
			end)
			Cell:SetAttribute("X",X)
			Cell:SetAttribute("Y",Y)
			Cell:SetAttribute("Alive",false)
			if CellTable[X] == nil then
				CellTable[X] = {}
			end
			CellTable[X][Y] = Cell
			-- Set the "Test" variable (at the begginning of the script) to true and you will see what this does.
			if Test == true then
				Cell.TextTransparency = 0
				Cell.TextStrokeTransparency = 0
				Cell.Text = "X: " .. X .. " Y: " .. Y
			end
			-- Reacts to mouse clicks
			Cell.MouseButton1Click:Connect(function()
				if Cell:GetAttribute("Alive") == true then
					Cell:SetAttribute("Alive",false)
				else
					Cell:SetAttribute("Alive",true)
				end
			end)
			-- Counts cells
			if Cell ~= nil and Cell.Parent == Frame then
				Count += 1
			end
		end
		-- Waits so your pc won't get annihilated
		wait()
	end
	if Test == true then
		print(Count)
	end
end

local function Generation() -- Will calculate 1 generation when called
	local OperationsPlanned = {} -- Records changes to do when everything is calculated
	for index,value in pairs(Frame:GetChildren()) do -- Goes through every cell
		if value:IsA("TextButton") then
			-- Gets the cell X,Y and Alive status
			local X = value:GetAttribute("X")
			local Y = value:GetAttribute("Y")
			local Alive = value:GetAttribute("Alive")
			local TotalAliveNeighbors = 0
			-- Counts how many of the eight neighbors are alive
			if GetCellAliveFromVector2(Vector2.new(X - 1,Y)) == true then
				TotalAliveNeighbors += 1
			end
			if GetCellAliveFromVector2(Vector2.new(X - 1,Y + 1)) == true then
				TotalAliveNeighbors += 1
			end
			if GetCellAliveFromVector2(Vector2.new(X,Y + 1)) == true then
				TotalAliveNeighbors += 1
			end
			if GetCellAliveFromVector2(Vector2.new(X + 1,Y + 1)) == true then
				TotalAliveNeighbors += 1
			end
			if GetCellAliveFromVector2(Vector2.new(X + 1,Y)) == true then
				TotalAliveNeighbors += 1
			end
			if GetCellAliveFromVector2(Vector2.new(X + 1,Y - 1)) == true then
				TotalAliveNeighbors += 1
			end
			if GetCellAliveFromVector2(Vector2.new(X,Y - 1)) == true then
				TotalAliveNeighbors += 1
			end
			if GetCellAliveFromVector2(Vector2.new(X - 1,Y - 1)) == true then
				TotalAliveNeighbors += 1
			end
			-- The game rules are here, you can change the numbers and see what happens!
			if Alive == true then
				if TotalAliveNeighbors < MinimumAliveNeighborAmount or TotalAliveNeighbors > MaximumAliveNeighborAmount then
					OperationsPlanned[value] = false
				end
			else
				if TotalAliveNeighbors == AliveNeighborSpawnInt then
					OperationsPlanned[value] = true
				end
			end
		end
	end
	--[[ Applies all the operations that where planned before, this is done later, so that we calculate the 
	everything and ONLY THEN apply the chanages
	]]
	for Object, AliveStatus in pairs(OperationsPlanned) do
		Object:SetAttribute("Alive",AliveStatus)
	end
end

Settings.Generate.MouseButton1Click:Connect(function() -- This runs when the user generates the grid
	local Size = Settings.CellSize.Text
	Frame.UIGridLayout.CellSize = UDim2.fromOffset(tonumber(Size),tonumber(Size))
	GridSize = Vector2.new(math.floor(Frame.AbsoluteSize.X / (Frame.UIGridLayout.CellSize.X.Offset + Frame.UIGridLayout.CellPadding.X.Offset)),math.floor(Frame.AbsoluteSize.Y / (Frame.UIGridLayout.CellSize.Y.Offset + Frame.UIGridLayout.CellPadding.Y.Offset)))
	GenerateGrid()
end)

Settings.Play.MouseButton1Click:Connect(function() -- This runs when the user wants to itterate generations.
	Playing = not Playing
	if Playing == true then
		Settings.Play.Text = "Pause"
		Settings.One.Visible = false
	else
		Settings.Play.Text = "Play"
		Settings.One.Visible = true
	end
end)

Settings.One.MouseButton1Click:Connect(function() -- One generation
	Generation()
end)

GenerateGrid() -- Generates start grid

while wait(0.3) do
	if Playing == true then
		Generation()
	end
end
10 Likes

it’d be great if you added screenshots and/or videos of what exactly this is so people know before having to download it and see it for themselves.

4 Likes

Not needed, everyone knows what conways game of life is.

6 Likes

well i don’t know what it is
also, screenshots would be useful either way for people who know and don’t

5 Likes

The ‘generate’ button yields the game for some reason. You forgot to add yields to a loop possibly.

2 Likes

Yes, I know that this is an open source and anyone can change it. But here I have suggestions for the original developer and anyone who uses it and modifies.

  • Spacebar hotkey to start/stop
  • Generate button not crashing the player
  • Drag select
  • Multiplayer mode??
1 Like

How do you not know what Conway’s game of life is?

3 Likes

Or use google. It’s Conway’s game of life, it’s very documented.

Ahem,
" The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970. It is a zero-player game, meaning that its evolution is determined by its initial state, requiring no further input. "Wikipedia

3 Likes

It is one of the most popular “games” ever, so big to the point where it is part of Google, look up the Conway Game of Life Google easter egg

3 Likes

That’s actually false, I have no idea who conway is.

2 Likes

And you can find out with a google search. John Conway is a very famous mathematician.

3 Likes

Hey @hackhack6776! Your post inspired be to redo my particle simulation based on The Powder Toy, which also works on a 2D UI, but with much more particles and each particle having their own properties!

2 Likes

That’s great! Can’t wait to see what turns out!

1 Like

am i the only one that doesnt know what this does??

1 Like