1
|
//import processing.opengl.*;
|
2
|
|
3
|
/**
|
4
|
* A Processing implementation of Game of Life
|
5
|
* By Joan Soler-Adillon
|
6
|
*
|
7
|
* Press SPACE BAR to pause and change the cell's values with the mouse
|
8
|
* On pause, click to activate/deactivate cells
|
9
|
* Press R to randomly reset the cells' grid
|
10
|
* Press C to clear the cells' grid
|
11
|
*
|
12
|
* The original Game of Life was created by John Conway in 1970.
|
13
|
*/
|
14
|
|
15
|
/*boolean sketchFullScreen() {
|
16
|
return true;
|
17
|
} */
|
18
|
|
19
|
// Size of cells
|
20
|
int cellSize = 30;
|
21
|
|
22
|
// How likely for a cell to be alive at start (in percentage)
|
23
|
float probabilityOfAliveAtStart = 15;
|
24
|
|
25
|
// Variables for timer
|
26
|
int interval = 100;
|
27
|
int lastRecordedTime = 0;
|
28
|
|
29
|
// Colors for active/inactive cells
|
30
|
//color alive = color(190, 60, 146); //porpora
|
31
|
//color alive = color(48, 189, 175); //turchese
|
32
|
//color alive = color(169, 47, 50); //rosso
|
33
|
//color alive = color(17, 148, 104); //verde
|
34
|
color alive = color(202, 103, 83); //arancione
|
35
|
//color alive = color(51, 82, 128); //blu
|
36
|
color dead = color(255);
|
37
|
|
38
|
// Array of cells
|
39
|
int[][] cells;
|
40
|
// Buffer to record the state of the cells and use this while changing the others in the interations
|
41
|
int[][] cellsBuffer;
|
42
|
|
43
|
boolean pausa = true;
|
44
|
|
45
|
// Pause
|
46
|
boolean pause = false;
|
47
|
|
48
|
void init_random(){
|
49
|
// Initialization of cells
|
50
|
for (int x=0; x<width/cellSize; x++) {
|
51
|
for (int y=0; y<height/cellSize; y++) {
|
52
|
float state = random (100);
|
53
|
if (state > probabilityOfAliveAtStart) {
|
54
|
state = 0;
|
55
|
}
|
56
|
else {
|
57
|
state = 1;
|
58
|
}
|
59
|
cells[x][y] = int(state); // Save state of each cell
|
60
|
}
|
61
|
}
|
62
|
}
|
63
|
|
64
|
|
65
|
void setup() {
|
66
|
//size (640, 360);
|
67
|
//size (1024, 768);
|
68
|
size(1600,900);
|
69
|
//fullScreen();
|
70
|
|
71
|
// Instantiate arrays
|
72
|
cells = new int[width/cellSize][height/cellSize];
|
73
|
cellsBuffer = new int[width/cellSize][height/cellSize];
|
74
|
|
75
|
// This stroke will draw the background grid
|
76
|
stroke(220);
|
77
|
|
78
|
noSmooth();
|
79
|
init1();
|
80
|
//init2();
|
81
|
//init3(0, 0); //a
|
82
|
//init3(16, 0);
|
83
|
//init3(0, 12);
|
84
|
//init3(16, 6); //b
|
85
|
//init3(32, 0);
|
86
|
//init4();
|
87
|
background(255); // Fill in black in case cells don't cover all the windows
|
88
|
}
|
89
|
|
90
|
|
91
|
void draw() {
|
92
|
|
93
|
//Draw grid
|
94
|
for (int x=0; x<width/cellSize; x++) {
|
95
|
for (int y=0; y<height/cellSize; y++) {
|
96
|
if (cells[x][y]==1) {
|
97
|
fill(alive); // If alive
|
98
|
}
|
99
|
else {
|
100
|
fill(dead); // If dead
|
101
|
}
|
102
|
//rect (x*cellSize, y*cellSize, cellSize, cellSize);
|
103
|
ellipse(x*cellSize, y*cellSize, 30, 30);
|
104
|
|
105
|
}
|
106
|
}
|
107
|
if (pausa){
|
108
|
delay(2000);
|
109
|
pausa = false;
|
110
|
}
|
111
|
// Iterate if timer ticks
|
112
|
if (millis()-lastRecordedTime>interval) {
|
113
|
if (!pause) {
|
114
|
iteration();
|
115
|
lastRecordedTime = millis();
|
116
|
}
|
117
|
}
|
118
|
|
119
|
// Create new cells manually on pause
|
120
|
if (pause && mousePressed) {
|
121
|
// Map and avoid out of bound errors
|
122
|
int xCellOver = int(map(mouseX, 0, width, 0, width/cellSize));
|
123
|
xCellOver = constrain(xCellOver, 0, width/cellSize-1);
|
124
|
int yCellOver = int(map(mouseY, 0, height, 0, height/cellSize));
|
125
|
yCellOver = constrain(yCellOver, 0, height/cellSize-1);
|
126
|
|
127
|
// Check against cells in buffer
|
128
|
if (cellsBuffer[xCellOver][yCellOver]==1) { // Cell is alive
|
129
|
cells[xCellOver][yCellOver]=0; // Kill
|
130
|
fill(dead); // Fill with kill color
|
131
|
}
|
132
|
else { // Cell is dead
|
133
|
cells[xCellOver][yCellOver]=1; // Make alive
|
134
|
fill(alive); // Fill alive color
|
135
|
}
|
136
|
}
|
137
|
else if (pause && !mousePressed) { // And then save to buffer once mouse goes up
|
138
|
// Save cells to buffer (so we opeate with one array keeping the other intact)
|
139
|
for (int x=0; x<width/cellSize; x++) {
|
140
|
for (int y=0; y<height/cellSize; y++) {
|
141
|
cellsBuffer[x][y] = cells[x][y];
|
142
|
}
|
143
|
}
|
144
|
}
|
145
|
}
|
146
|
|
147
|
|
148
|
|
149
|
void iteration() { // When the clock ticks
|
150
|
// Save cells to buffer (so we opeate with one array keeping the other intact)
|
151
|
for (int x=0; x<width/cellSize; x++) {
|
152
|
for (int y=0; y<height/cellSize; y++) {
|
153
|
cellsBuffer[x][y] = cells[x][y];
|
154
|
}
|
155
|
}
|
156
|
|
157
|
// Visit each cell:
|
158
|
for (int x=0; x<width/cellSize; x++) {
|
159
|
for (int y=0; y<height/cellSize; y++) {
|
160
|
// And visit all the neighbours of each cell
|
161
|
int neighbours = 0; // We'll count the neighbours
|
162
|
for (int xx=x-1; xx<=x+1;xx++) {
|
163
|
for (int yy=y-1; yy<=y+1;yy++) {
|
164
|
if (((xx>=0)&&(xx<width/cellSize))&&((yy>=0)&&(yy<height/cellSize))) { // Make sure you are not out of bounds
|
165
|
if (!((xx==x)&&(yy==y))) { // Make sure to to check against self
|
166
|
if (cellsBuffer[xx][yy]==1){
|
167
|
neighbours ++; // Check alive neighbours and count them
|
168
|
}
|
169
|
} // End of if
|
170
|
} // End of if
|
171
|
} // End of yy loop
|
172
|
} //End of xx loop
|
173
|
// We've checked the neigbours: apply rules!
|
174
|
if (cellsBuffer[x][y]==1) { // The cell is alive: kill it if necessary
|
175
|
if (neighbours < 2 || neighbours > 3) {
|
176
|
cells[x][y] = 0; // Die unless it has 2 or 3 neighbours
|
177
|
}
|
178
|
}
|
179
|
else { // The cell is dead: make it live if necessary
|
180
|
if (neighbours == 3 ) {
|
181
|
cells[x][y] = 1; // Only if it has 3 neighbours
|
182
|
}
|
183
|
} // End of if
|
184
|
} // End of y loop
|
185
|
} // End of x loop
|
186
|
} // End of function
|
187
|
|
188
|
void keyPressed() {
|
189
|
if (key=='r' || key == 'R') {
|
190
|
// Restart: reinitialization of cells
|
191
|
for (int x=0; x<width/cellSize; x++) {
|
192
|
for (int y=0; y<height/cellSize; y++) {
|
193
|
float state = random (100);
|
194
|
if (state > probabilityOfAliveAtStart) {
|
195
|
state = 0;
|
196
|
}
|
197
|
else {
|
198
|
state = 1;
|
199
|
}
|
200
|
cells[x][y] = int(state); // Save state of each cell
|
201
|
}
|
202
|
}
|
203
|
}
|
204
|
if (key==' ') { // On/off of pause
|
205
|
pause = !pause;
|
206
|
}
|
207
|
if (key=='c' || key == 'C') { // Clear all
|
208
|
for (int x=0; x<width/cellSize; x++) {
|
209
|
for (int y=0; y<height/cellSize; y++) {
|
210
|
cells[x][y] = 0; // Save all to zero
|
211
|
}
|
212
|
}
|
213
|
}
|
214
|
}
|