Added cell simulation thingie

This commit is contained in:
Casey 2024-05-29 13:19:08 +03:00
parent 84b7493a4a
commit 058a007265
Signed by: hkc
GPG Key ID: F0F6CFE11CDB0960
5 changed files with 132 additions and 1 deletions

1
_templates/raylib/empty/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
__PROGNAME

View File

@ -1,7 +1,8 @@
name = "Empty Raylib project"
templates = [
"Makefile",
"main.c"
"main.c",
".gitignore"
]
[params.WINDOW_WIDTH]

1
sim/cellular/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
cellular

12
sim/cellular/Makefile Executable file
View File

@ -0,0 +1,12 @@
CFLAGS += -Wall -Wextra `exec pkg-config --cflags raylib`
LDFLAGS := -lm `pkg-config --libs raylib`
cellular: main.c
$(CC) $(CFLAGS) main.c $(LDFLAGS) -o cellular
clean:
$(RM) cellular
run: cellular
./cellular

116
sim/cellular/main.c Normal file
View File

@ -0,0 +1,116 @@
// x-run: make run
#include <raylib.h>
#include <stdlib.h>
#include <string.h>
struct cell {
int origin_x, origin_y;
int random_seed;
enum cell_type {
CELL_VOID,
CELL_LIVING,
CELL_DEAD
} type;
int timer;
};
#define GET_CELL(A, X, Y) (A[((X + width) % width) + ((Y + height) % height) * width])
const int width = 400, height = 300;
Color cell_get_color(struct cell *cells, int x, int y);
void cell_update(struct cell *cells_old, struct cell *cells, int x, int y);
int main(int argc, char **argv) {
InitWindow(width * 2, height * 2, "sim/cellular_NAME");
SetTargetFPS(60);
struct cell *cells = calloc(width * height, sizeof(struct cell));
struct cell *cells_old = calloc(width * height, sizeof(struct cell));
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
cells[x + y * width].origin_x = x;
cells[x + y * width].origin_y = y;
cells[x + y * width].random_seed = rand();
cells[x + y * width].type = rand() % 100 == 0;
cells[x + y * width].timer = 200;
}
}
Image img_out = GenImageColor(width, height, BLANK);
Texture2D tex_out = LoadTextureFromImage(img_out);
while (!WindowShouldClose()) {
memcpy(cells_old, cells, width * height * sizeof(struct cell));
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
cell_update(cells_old, cells, x, y);
}
}
BeginDrawing();
ClearBackground(BLACK);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
struct cell cell = cells[x + y * width];
ImageDrawPixel(&img_out, x, y, cell_get_color(cells, x, y));
}
}
UpdateTexture(tex_out, img_out.data);
DrawTextureEx(tex_out, (Vector2){ 0, 0 }, 0, 2, WHITE);
DrawFPS(10, 10);
EndDrawing();
}
UnloadTexture(tex_out);
UnloadImage(img_out);
}
Color cell_get_color(struct cell *cells, int x, int y) {
Vector3 color = ColorToHSV(WHITE);
struct cell cell = cells[x + y * width];
switch (cell.type) {
case CELL_VOID: color = ColorToHSV(BLACK); break;
case CELL_LIVING: color = ColorToHSV(DARKGREEN); break;
case CELL_DEAD: color = ColorToHSV(RED); break;
}
color.x += (cell.random_seed % 60) - 30;
color.y *= 1.0 - 0.2 * ((float)(cell.random_seed % 100) / 100.0);
/*color.z *= cell.timer / 200.0;*/
return ColorFromHSV(color.x, color.y, color.z);
}
void cell_update(struct cell *cells_old, struct cell *cells, int x, int y) {
struct cell *old_self = &cells_old[x + y * width];
struct cell *self = &cells[x + y * width];
switch (self->type) {
case CELL_LIVING:
{
for (int oy = -1; oy <= 1; oy++) {
for (int ox = -1; ox <= 1; ox++) {
struct cell old_other = GET_CELL(cells_old, x + ox, y + oy);
struct cell *other = &GET_CELL(cells, x + ox, y + oy);
if (old_other.type == CELL_VOID && rand() % 100 == 0) {
other->type = CELL_LIVING;
other->timer = 200;
} else if (old_other.type == CELL_LIVING && rand() % 90 == 0) {
other->type = CELL_DEAD;
other->timer = rand() % 200;
}
}
}
}
break;
case CELL_DEAD:
self->timer -= rand() % 8;
if (self->timer <= 0) {
self->type = CELL_VOID;
}
default:
break;
}
}