ΠΡ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΡΡΠ΅Ρ ΠΌΠ΅ΡΠ½ΡΡ Π²Π΅ΡΡΠΈΡ ΠΈΠ³ΡΡ «ΠΠΈΠ·Π½Ρ» ΠΠΎΠ½Π²Π΅Ρ, Π³Π΄Π΅ ΠΊΠ»Π΅ΡΠΊΠΈ ΡΠ²ΠΎΠ»ΡΡΠΈΠΎΠ½ΠΈΡΡΡΡ Π² 3D-ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²Π΅!
3D Game of Life:
cpp
#define GRID_SIZE 8
#define CELL_COUNT (GRID_SIZE * GRID_SIZE * GRID_SIZE)
// Π‘ΠΎΡΡΠΎΡΠ½ΠΈΡ ΠΊΠ»Π΅ΡΠΎΠΊ (0=ΠΌΠ΅ΡΡΠ²Π°, 1=ΠΆΠΈΠ²Π°, 2=Π΄Π΅Π»ΠΈΡΡΡ)
uint8_t grid[GRID_SIZE][GRID_SIZE][GRID_SIZE];
uint8_t newGrid[GRID_SIZE][GRID_SIZE][GRID_SIZE];
// ΠΠΈΠ·Π½Π΅Π½Π½ΡΠΉ ΡΠΈΠΊΠ» ΠΊΠ»Π΅ΡΠΊΠΈ
uint8_t cellCycle[3] = {1, 2, 0}; // ΠΠΈΠ²Π° -> ΠΠ΅Π»ΠΈΡΡΡ -> ΠΠ΅ΡΡΠ²Π°
// ΠΠΎΠ΄ΡΡΠ΅Ρ ΡΠΎΡΠ΅Π΄Π΅ΠΉ Π² 3D (26 ΡΠΎΡΠ΅Π΄Π΅ΠΉ)
uint8_t countNeighbors3D(uint8_t x, uint8_t y, uint8_t z) {
uint8_t count = 0;
for (int8_t dx = -1; dx <= 1; dx++) {
for (int8_t dy = -1; dy <= 1; dy++) {
for (int8_t dz = -1; dz <= 1; dz++) {
if (dx == 0 && dy == 0 && dz == 0) continue;
uint8_t nx = (x + dx + GRID_SIZE) % GRID_SIZE;
uint8_t ny = (y + dy + GRID_SIZE) % GRID_SIZE;
uint8_t nz = (z + dz + GRID_SIZE) % GRID_SIZE;
if (grid[nx][ny][nz] > 0) count++;
}
}
}
return count;
}
// ΠΠ²ΠΎΠ»ΡΡΠΈΡ (3D ΠΏΡΠ°Π²ΠΈΠ»Π°)
void evolve3D() {
memset(newGrid, 0, sizeof(newGrid));
for (uint8_t x = 0; x < GRID_SIZE; x++) {
for (uint8_t y = 0; y < GRID_SIZE; y++) {
for (uint8_t z = 0; z < GRID_SIZE; z++) {
uint8_t neighbors = countNeighbors3D(x, y, z);
if (grid[x][y][z] > 0) {
// ΠΠΈΠ²Π°Ρ ΠΊΠ»Π΅ΡΠΊΠ°
if (neighbors < 2 || neighbors > 6) {
// Π‘ΠΌΠ΅ΡΡΡ
newGrid[x][y][z] = 0;
} else if (neighbors >= 4 && neighbors <= 5) {
// ΠΠ΅Π»Π΅Π½ΠΈΠ΅
newGrid[x][y][z] = 2;
} else {
// ΠΡΡΠ°Π΅ΡΡΡ ΠΆΠΈΠ²ΠΎΠΉ
newGrid[x][y][z] = 1;
}
} else {
// ΠΠ΅ΡΡΠ²Π°Ρ ΠΊΠ»Π΅ΡΠΊΠ° - ΡΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅
if (neighbors == 3) {
newGrid[x][y][z] = 1;
}
}
}
}
}
// ΠΠ±Π½ΠΎΠ²Π»ΡΠ΅ΠΌ ΡΠ΅ΡΡ ΠΈ ΠΆΠΈΠ·Π½Π΅Π½Π½ΡΠ΅ ΡΠΈΠΊΠ»Ρ
memcpy(grid, newGrid, sizeof(grid));
// Π‘ΡΠ°ΡΠ΅Π½ΠΈΠ΅ ΠΊΠ»Π΅ΡΠΎΠΊ
for (uint8_t x = 0; x < GRID_SIZE; x++) {
for (uint8_t y = 0; y < GRID_SIZE; y++) {
for (uint8_t z = 0; z < GRID_SIZE; z++) {
if (grid[x][y][z] > 0) {
grid[x][y][z] = cellCycle[grid[x][y][z] % 3];
}
}
}
}
}
// ΠΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΡΠ»ΡΡΠ°ΠΉΠ½ΠΎΠΉ ΠΆΠΈΠ·Π½ΠΈ
void initLife() {
randomSeed(analogRead(A0));
for (uint8_t x = 0; x < GRID_SIZE; x++) {
for (uint8_t y = 0; y < GRID_SIZE; y++) {
for (uint8_t z = 0; z < GRID_SIZE; z++) {
grid[x][y][z] = (random(100) < 30) ? 1 : 0;
}
}
}
}
// Π Π΅Π½Π΄Π΅ΡΠΈΠ½Π³ 3D ΠΆΠΈΠ·Π½ΠΈ Π½Π° OLED (ΠΏΡΠΎΠ΅ΠΊΡΠΈΡ)
void renderLife3D() {
clearScreen();
// ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠ»ΠΎΡ Z ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°Π΅ΠΌ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡ
for (uint8_t z = 0; z < GRID_SIZE; z++) {
uint8_t offsetY = z * 2;
for (uint8_t x = 0; x < GRID_SIZE; x++) {
for (uint8_t y = 0; y < GRID_SIZE; y++) {
if (grid[x][y][z] > 0) {
uint8_t screenX = x * 4 + z * 2;
uint8_t screenY = y * 4 + offsetY;
if (screenX < 64 && screenY < 64) {
drawPixel(screenX, screenY, 1);
}
}
}
}
}
updateDisplay();
}
void setup() {
initOLED();
initLife();
}
void loop() {
// ΠΠ²ΠΎΠ»ΡΡΠΈΠΎΠ½ΠΈΡΡΠ΅ΠΌ 10 ΠΏΠΎΠΊΠΎΠ»Π΅Π½ΠΈΠΉ Π·Π° ΡΠ°Π·
for (uint8_t gen = 0; gen < 10; gen++) {
evolve3D();
}
renderLife3D();
delay(100);
}