117 lines
3.3 KiB
C
117 lines
3.3 KiB
C
// 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;
|
|
}
|
|
}
|