Game of Life in 3D (finally)
Now that we are entering the third dimension, let's disable the 2D lock from our scene:
In addition, we need to change the camera Projection back to Perspective:
Change the position and rotation of the main camera so that we have a good view on the 3d scene, I suggest the following values:
This is what you should see now:
Let's make it more interesting and add cubes in the third dimension. For this, update the zCubes value through the Unity editor:
resulting in the following:
Hmm, all cubes disappear after the first generation. If you look back to the rules, this makes sense. Since we are now dealing in three dimensions, every single cube has at least (the corner cubes) 7 living neighbours in the above example, causing starvation throughout all cubes.
Let's make a simple change to set the probability of an initial cube to be alive or dead. Open up your Grid script again and add the following variable:
[Range(0.0f, 1.0f)] public double lifeProbability;
Note that the Range bracket above the variable will allow us to set the lifeProbability value through the Unity editor using a slider rather than a simple input box:
Set it to something sensible like 0.5, meaning that any cube has a likelihood of 50% to be alive at the start of the simulation.
Let's modify our initialSetup method so that it accepts a new parameter containing the states (alive or dead) for every cube of the initial generation. We then either enable rendering (alive) or disable rendering of the cube based on that state.
private void initialSetup(bool[,,] firstGeneration) { matrix = new GameObject[xCubes, yCubes, zCubes]; scaleVector = new Vector3(scale, scale, scale); for (int i = 0; i < matrix.GetLength(0); i++) { for (int j = 0; j < matrix.GetLength(1); j++) { for (int k = 0; k < matrix.GetLength(2); k++) { GameObject cubeClone = Instantiate( cube, new Vector3(i, j, k), Quaternion.identity ); cubeClone.transform.localScale = scaleVector; Renderer renderer = cubeClone.GetComponent(); if (firstGeneration[i, j, k]) { renderer.enabled = true; } else { renderer.enabled = false; } matrix[i, j, k] = cubeClone; } } } }
Now, let's write a small helper method that creates a random initial state, taking our lifeProbability variable into account:
private bool[,,] createProbabilisticFirstGeneration() { bool[,,] arr = new bool[xCubes, yCubes, zCubes]; System.Random random = new System.Random(); for (int i = 0; i < arr.GetLength(0); i++) { for (int j = 0; j < arr.GetLength(1); j++) { for (int k = 0; k < arr.GetLength(2); k++) { if (random.NextDouble() >= (1 - lifeProbability)) { arr[i, j, k] = true; } } } } return arr; }
Let's now call the above method to initialize the first generation as part of the Start method:
void Start () { bool[,,] firstGeneration = createProbabilisticFirstGeneration(); initialSetup(firstGeneration); InvokeRepeating("nextGeneration", 1.0f, 1.0f); }
Run the simulation and depending on your lifeProbability value, you will now see your 3D Game of Life evolving, possibly over many generations:
We have done it! And with this, we conclude this tutorial. Below are a couple of possible improvements that the interested reader might try out.
Improvement Suggestions
While the code we implemented here works and shows how Conway's Game of Life can work in 3D, it can most certainly be improved:
- Play around with the rules by changing how many numbers a cube requires to survive to the next generation. The maximum number of neighbours increases from 8 in 2D to 26 in 3D.
- Distinguish the cubes based on which rule affected it to survive or be born. This can easily be done by assigning different colors to each cube.
- Implement a way to easily provide "initial configurations": In this tutorial, we used probability to create initial generations. This can be expanded on so that different types of initial configurations can easily be fed to the code. Check out Game of Life - Wikipedia to find some interesting patterns and see how they work in 3D.
If there is interest, let me know and I may expand this tutorial with some or all of the above improvements.
Great job making it all the way to the end. Please let me know if this was useful to you. Also, if you have any questions or issues, leave a comment and I will get back to you. Thanks!
Lynx
Heya i'm foг the first time here. I found this board and Ӏ find It reallү useful & it heⅼped me out muсh.
I hope to givе something back and aid others like you aided me.
https://waterfallmagazine.com
Hi, this weekend is nice designed for me, because this time
i am reading this enormous informative paragraph here at my house.