-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #17 from alessandro-bugatti/life
Life
- Loading branch information
Showing
3 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
#include <iostream> | ||
#include <algorithm> | ||
#include <ctime> | ||
#include "../../vsgl2.h" | ||
|
||
using namespace std; | ||
using namespace vsgl2; | ||
using namespace vsgl2::general; | ||
using namespace vsgl2::video; | ||
using namespace vsgl2::utils; | ||
|
||
const int DIM = 64; | ||
const int CELL_DIMENSION = 8; | ||
|
||
int life[DIM][DIM]; | ||
int temp[DIM][DIM]; | ||
|
||
|
||
void start(int m[][DIM]) | ||
{ | ||
for (int i = 0; i < DIM; i++) | ||
for (int j = 0; j < DIM; j++) | ||
if (rand()%6 == 0) | ||
m[i][j] = 1; | ||
else | ||
m[i][j] = 0; | ||
//Put the border cells to zero | ||
for (int i = 0; i < DIM; i++) | ||
{ | ||
m[0][i] = 0; | ||
m[i][0] = 0; | ||
m[DIM - 1][i] = 0; | ||
m[i][DIM - 1] = 0; | ||
} | ||
} | ||
|
||
void draw(int m[][DIM]) | ||
{ | ||
for (int i = 0; i < DIM; i++) | ||
for (int j = 0; j < DIM; j++) | ||
if (m[i][j] == 1) | ||
draw_filled_rect(i*CELL_DIMENSION, j*CELL_DIMENSION, | ||
CELL_DIMENSION - 1, CELL_DIMENSION - 1, | ||
Color(255,0,0,255)); | ||
} | ||
|
||
int neighbours(int m[][DIM], int r, int c) | ||
{ | ||
int counter = 0; | ||
for (int i = r-1; i < r - 1 + 3; i++) | ||
for (int j = c-1; j < c - 1 + 3; j++) | ||
counter += m[i][j]; | ||
return counter - m[r][c]; | ||
} | ||
|
||
void evolve(int m[][DIM]) | ||
{ | ||
for (int i = 1; i < DIM-1; i++) | ||
for (int j = 1; j < DIM-1; j++) | ||
{ | ||
int n = neighbours(m, i, j); | ||
//Any live cell with fewer than two live neighbors dies, | ||
//as if by underpopulation. | ||
if (m[i][j] == 1 && n < 2) | ||
temp[i][j] = 0; | ||
//Any live cell with two or three live neighbors lives | ||
//on to the next generation. | ||
if (m[i][j] == 1 && (n == 2 || n == 3)) | ||
temp[i][j] = 1; | ||
//Any live cell with more than three live neighbors dies, | ||
//as if by overpopulation. | ||
if (m[i][j] == 1 && n > 3) | ||
temp[i][j] = 0; | ||
//Any dead cell with exactly three live neighbors | ||
//becomes a live cell, as if by reproduction. | ||
if (m[i][j] == 0 && n == 3) | ||
temp[i][j] = 1; | ||
} | ||
for (int i = 1; i < DIM-1; i++) | ||
for (int j = 1; j < DIM-1; j++) | ||
m[i][j] = temp[i][j]; | ||
} | ||
|
||
int main(int argc, char* argv[]) | ||
{ | ||
//init the library | ||
init(); | ||
//create the window and show it | ||
set_window(DIM*CELL_DIMENSION, DIM*CELL_DIMENSION,"Vsgl2 Game of Life"); | ||
srand(time(NULL)); | ||
start(life); | ||
while(!done()) | ||
{ | ||
draw(life); | ||
update(); | ||
evolve(life); | ||
delay(100); | ||
} | ||
|
||
close(); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Game of Life | ||
The classical [Game of Life](https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life) is a sort of mathematical "game" invented by John Conway in the seventies, that it will be used to show how to record information inside a matrix about the image to be displayed. | ||
|
||
In a nutshell, there is a NxN matrix with 0 and 1s in each cell, where 0 mean *dead* and 1 mean *alive* (sometimes they are referred as *unpopulated* and *populated*). This matrix evolves with discrete steps, updating every cell at each step using these simple rules: | ||
- Any live cell with fewer than two live neighbors dies, as if by underpopulation. | ||
- Any live cell with two or three live neighbors lives on to the next generation. | ||
- Any live cell with more than three live neighbors dies, as if by overpopulation. | ||
- Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction. | ||
|
||
As a result, there is a feeling of moving things, because of the continuing change in cell values, as it can see in the below video | ||
|
||
[![YouTube video on Game of Life](http://img.youtube.com/vi/OWfAzvJidVQ/0.jpg)](http://www.youtube.com/watch?v=OWfAzvJidVQ "YouTube video on Game of Life") | ||
|
||
The code is quite simple, there are four functions that done all the job: | ||
|
||
1. ```void start(int m[][DIM])```: populate all the matrix with 0 and 1s, using the the `rand()` function to choose between 0 and 1, with a ratio of 6 to 1, to avoid to overpopulate the matrix | ||
2. ```void draw(int m[][DIM])```: put the entire matrix to the screen with the ```draw_filled_rect``` function. The coordinates of each cell depends on its *i, j* position, multiplicated for **CELL_DIMENSION**, in this case 8, to have cell that are clearly visible on the screen. Only cells with 1 inside are put on the screen, red coloured. | ||
3. ```void evolve(int m[][DIM])```: this is the main function, which is in charge of evolving the matrix state using the rules explained above. | ||
In particular there are four *if*, each one matching one rule | ||
```c | ||
int n = neighbours(m, i, j); | ||
//Any live cell with fewer than two live neighbors dies, | ||
//as if by underpopulation. | ||
if (m[i][j] == 1 && n < 2) | ||
temp[i][j] = 0; | ||
//Any live cell with two or three live neighbors lives | ||
//on to the next generation. | ||
if (m[i][j] == 1 && (n == 2 || n == 3)) | ||
temp[i][j] = 1; | ||
//Any live cell with more than three live neighbors dies, | ||
//as if by overpopulation. | ||
if (m[i][j] == 1 && n > 3) | ||
temp[i][j] = 0; | ||
//Any dead cell with exactly three live neighbors | ||
//becomes a live cell, as if by reproduction. | ||
if (m[i][j] == 0 && n == 3) | ||
temp[i][j] = 1; | ||
``` | ||
4. ```int neighbours(int m[][DIM], int r, int c)```: a little utility function to count how many neighbours cells are near to cell **m[r][c]** | ||
|
||
Using all these functions is now easy to implement the main loop, drawing and evolving the state at each step. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> | ||
<CodeBlocks_project_file> | ||
<FileVersion major="1" minor="6" /> | ||
<Project> | ||
<Option title="vsgl2_graphics_drawing" /> | ||
<Option pch_mode="2" /> | ||
<Option compiler="gcc" /> | ||
<Build> | ||
<Target title="Win32 Debug"> | ||
<Option output="win32/bin/Debug/provaSDL" prefix_auto="1" extension_auto="1" /> | ||
<Option object_output="win32/obj/Debug/" /> | ||
<Option type="1" /> | ||
<Option compiler="gcc" /> | ||
<Compiler> | ||
<Add option="-g" /> | ||
</Compiler> | ||
<Linker> | ||
<Add option="-lmingw32 -lSDL2main -lSDL2 -lSDL2_net -lSDL2_image -lSDL2_mixer -lSDL2_ttf" /> | ||
</Linker> | ||
</Target> | ||
<Target title="Win32 Release"> | ||
<Option output="win32/bin/Release/provaSDL" prefix_auto="1" extension_auto="1" /> | ||
<Option object_output="win32/obj/Release/" /> | ||
<Option type="0" /> | ||
<Option compiler="gcc" /> | ||
<Compiler> | ||
<Add option="-O2" /> | ||
</Compiler> | ||
<Linker> | ||
<Add option="-s" /> | ||
<Add option="-lmingw32 -lSDL2main -lSDL2 -lSDL2_net -lSDL2_image -lSDL2_mixer -lSDL2_ttf" /> | ||
</Linker> | ||
</Target> | ||
<Target title="Linux Debug"> | ||
<Option output="linux/bin/Debug/provaSDL" prefix_auto="1" extension_auto="1" /> | ||
<Option object_output="linux/obj/Debug/" /> | ||
<Option type="1" /> | ||
<Option compiler="gcc" /> | ||
<Compiler> | ||
<Add option="-g" /> | ||
</Compiler> | ||
<Linker> | ||
<Add option="-lSDL2main -lSDL2 -lSDL2_net -lSDL2_image -lSDL2_mixer -lSDL2_ttf" /> | ||
</Linker> | ||
</Target> | ||
<Target title="Linux Release"> | ||
<Option output="linux/bin/Release/provaSDL" prefix_auto="1" extension_auto="1" /> | ||
<Option object_output="linux/obj/Release/" /> | ||
<Option type="0" /> | ||
<Option compiler="gcc" /> | ||
<Compiler> | ||
<Add option="-O2" /> | ||
</Compiler> | ||
<Linker> | ||
<Add option="-s" /> | ||
<Add option="-lSDL2main -lSDL2 -lSDL2_net -lSDL2_image -lSDL2_mixer -lSDL2_ttf" /> | ||
</Linker> | ||
</Target> | ||
</Build> | ||
<Compiler> | ||
<Add option="-Wall" /> | ||
<Add option="-std=c++11" /> | ||
</Compiler> | ||
<Unit filename="../../vsgl2.cpp" /> | ||
<Unit filename="../../vsgl2.h" /> | ||
<Unit filename="main.cpp" /> | ||
<Extensions> | ||
<code_completion /> | ||
<envvars /> | ||
<debugger /> | ||
<lib_finder disable_auto="1" /> | ||
</Extensions> | ||
</Project> | ||
</CodeBlocks_project_file> |