]> git.mcshandy.xyz Git - barrow_crawler/commitdiff
More proper grid size management
authorRandy McShandy <randy@mcshandy.xyz>
Sun, 28 Apr 2024 16:11:49 +0000 (11:11 -0500)
committerRandy McShandy <randy@mcshandy.xyz>
Sun, 28 Apr 2024 16:11:49 +0000 (11:11 -0500)
main.c
structs.c
structs.h
utils.c

diff --git a/main.c b/main.c
index 7397f42d3a02d206f762ac66e75939c89c57d349..9af3a997a31a25ca8563a1d741367c6f1f46aa62 100755 (executable)
--- a/main.c
+++ b/main.c
@@ -1,22 +1,19 @@
 #include <stdio.h>
+#include <stdlib.h>
 #include "structs.h"
 
 int main(int argc, char** argv)
 {
-       RD_Opts barrow_circ =
-       {
-               .max_iterations = 1e4,
-               .diff_a = 0.8f,
-               .diff_b = 0.3f,
-               .feed = 0.058f,
-               .kill = 0.066f,
-               .delta_t = 0.6f,
 
-               .name = "puffer",
-               .shape = eCircle
-       };
+       IVec2 grid_size = {.x = GRID_X * 1.5, .y = GRID_Y * 1.5};
+       FVec2 **grid = NULL;
+       grid = (FVec2**)malloc(grid_size.x * sizeof(FVec2*));
+       for (int n = 0; n < grid_size.x; n++)
+       {
+               grid[n] = (FVec2*)malloc(grid_size.y * sizeof(FVec2));
+       }
 
-       generate_rd(8, barrow);
+       generate_rd(8, barrow, grid, grid_size);
 
        return 0;
 }
index 3cc769c97eda2e9670c1c7bd43e640da76860cee..0997ca3caeaedf0b833d0649433c58948d4637f3 100644 (file)
--- a/structs.c
+++ b/structs.c
@@ -19,14 +19,14 @@ RD_Opts puffer =
 // diff values influence tightness, delta between them shouldn't get wider than ~0.5 or narrower than ~0.4
 RD_Opts barrow =
 {
-       .max_iterations = 1e4,
+       .max_iterations = 1e4 * 1.0f,
        .diff_a = 0.8f,
        .diff_b = 0.3f,
        .feed = 0.055f,
        .kill = 0.062f,
        .delta_t = 0.6f,
 
-       .name = "puffer",
+       .name = "barrow",
        .shape = eBarrow
 };
 
index 0673129211255ca6f32fc88b4a9faceb0047e97d..a239fd00d75f7e74d415d43e504467d849fbbc08 100644 (file)
--- a/structs.h
+++ b/structs.h
@@ -26,6 +26,12 @@ typedef struct
        float c;
 } FVec2;
 
+typedef struct
+{
+       int x;
+       int y;
+} IVec2;
+
 typedef struct
 {
        int max_iterations;
@@ -62,6 +68,6 @@ extern RD_Opts worms;
 extern RD_Opts meiosis;
 extern const Mat3 laplacian_kernel;
 
-int generate_rd(int worker_count, RD_Opts opts);
+int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 pgrid_size);
 #endif //__RD_STRUCTS__
 
diff --git a/utils.c b/utils.c
index c58bda4ede6808745f194e036425968496514649..c898a4bd0bae51b3fae12c128c07b6121618c015 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <math.h>
+
 #include "structs.h"
 #define STB_IMAGE_WRITE_IMPLEMENTATION
 #include "stb_image_write.h"
@@ -22,6 +23,7 @@ pthread_barrier_t barrier;
 FVec2 ** grid;
 FVec2 ** grid_prime;
 FVec2 ** grid_temp;
+IVec2 grid_size;
 
 float kernel_sum(Mat3 kernel, Mat3 source) {
   float result = 0.0f;
@@ -41,8 +43,8 @@ float rd_a_prime(FVec2 **source_grid, RD_Opts opts, int x, int y, Mat3 kernel,
   float a_prime = 1.0f;
   int x_less = (x - 1 < 0) ? x : x - 1;
   int y_less = (y - 1 < 0) ? y : y - 1;
-  int x_more = (x + 1 == GRID_X) ? x : x + 1;
-  int y_more = (y + 1 == GRID_Y) ? y : y + 1;
+  int x_more = (x + 1 == grid_size.x) ? x : x + 1;
+  int y_more = (y + 1 == grid_size.y) ? y : y + 1;
 
   // Use species A in the convolution, b_prime will need B
   // For now we won't iterate over edge rows and columns to avoid special case
@@ -65,8 +67,8 @@ float rd_b_prime(FVec2** source_grid, RD_Opts opts, int x, int y, Mat3 kernel, f
        float b_prime = 1.0f;
        int x_less = (x-1 < 0) ? x : x-1;
        int y_less = (y-1 < 0) ? y : y-1;
-       int x_more = (x+1 == GRID_X) ? x : x+1;
-       int y_more = (y+1 == GRID_Y) ? y : y+1;
+       int x_more = (x+1 == grid_size.x) ? x : x+1;
+       int y_more = (y+1 == grid_size.y) ? y : y+1;
 
        // Use species A in the convolution, b_prime will need B
        Mat3 source =
@@ -95,13 +97,16 @@ void* iterator(void* _arg)
        for (warg->iterations = 0; warg->iterations < warg->max_iterations; warg->iterations++)
        {
                printf("worker %d: work unit %d/%d\n", warg->worker_id, warg->iterations, warg->max_iterations);
-               for (int x = start_x; x < w + start_x && x < GRID_X; x++)
+               for (int x = start_x; x < w + start_x && x < grid_size.x; x++)
                {
-                       for (int y = start_y; y < h + start_y && y < GRID_Y; y++)
+                       for (int y = start_y; y < h + start_y && y < grid_size.y; y++)
                        {
                                FVec2 each = grid[x][y];
                                if (each.c >= 0.5f)
+                               {
                                        each.b = 1.0f;
+                                       each.c -= 5.0f/((float)(opts.max_iterations/100.0f));
+                               }
                                grid_prime[x][y].a = rd_a_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b);
                                grid_prime[x][y].b = rd_b_prime(grid, opts, x, y, laplacian_kernel, each.a, each.b);
                        }
@@ -115,20 +120,6 @@ void* iterator(void* _arg)
                        grid_prime = grid_temp;
                        waiting_workers = 0;
                        printf("worker-boss %d: completing report\n", warg->worker_id);
-                       if ((warg->iterations % 100 == 0))
-                       {
-                               char buffer[GRID_X][GRID_Y];
-                               for (int x = 0; x < GRID_X; x++)
-                               {
-                                       for (int y = 0; y < GRID_Y; y++)
-                                       {
-                                               buffer[x][y] = (uint8_t)(255.0f * grid[x][y].a);
-                                       }
-                               }
-                               char name[64] = {0};
-                               sprintf(name, "img/%s/%d.png", opts.name, warg->iterations);
-                               stbi_write_png(name, GRID_X, GRID_Y, 1, buffer, GRID_X * sizeof(uint8_t));
-                       }
                }
                pthread_mutex_unlock(&mutex);
                pthread_barrier_wait(&barrier);
@@ -145,26 +136,20 @@ void* iterator(void* _arg)
 
 int initialize(int worker_count, RD_Opts active_opt)
 {
-       grid = (FVec2**)malloc(GRID_X * sizeof(FVec2*));
-       for (int n = 0; n < GRID_X; n++)
-       {
-               grid[n] = (FVec2*)malloc(GRID_Y * sizeof(FVec2));
-       }
-
-       grid_prime = (FVec2**)malloc(GRID_X * sizeof(FVec2*));
-       for (int n = 0; n < GRID_X; n++)
+       grid_prime = (FVec2**)malloc(grid_size.x * sizeof(FVec2*));
+       for (int n = 0; n < grid_size.x; n++)
        {
-               grid_prime[n] = (FVec2*)malloc(GRID_Y * sizeof(FVec2));
+               grid_prime[n] = (FVec2*)malloc(grid_size.y * sizeof(FVec2));
        }
 
        srand(time(NULL));
 
-       float radius = GRID_X/2.1f;
-       int center_x = GRID_X/2;
-       int center_y = GRID_Y/2;
-       for (int x = 0; x < GRID_X; x++)
+       float radius = grid_size.x/2.1f;
+       int center_x = grid_size.x/2;
+       int center_y = grid_size.y/2;
+       for (int x = 0; x < grid_size.x; x++)
        {
-               for (int y = 0; y < GRID_Y; y++)
+               for (int y = 0; y < grid_size.y; y++)
                {
                        grid[x][y].a = 1.0f;
                        grid[x][y].b = 0.0f;
@@ -200,19 +185,29 @@ int initialize(int worker_count, RD_Opts active_opt)
 
                                        // Slap in an entrance or something here
                                        // or add support for post-processing
+                                       if (abs(x-center_x) < 3 && (y <= (5 * (grid_size.y/8))))
+                                       {
+                                               grid[x][y].c = 1.0f;
+                                       }
+
+                                       if (abs(y-center_y) < 8 && (x <= (6 * (grid_size.x/8))) && (x >= (2 * (grid_size.x/8))))
+                                       {
+                                               grid[x][y].c = 1.0f;
+                                       }
 
                                } break;
                        }
                }
        }
 
-       const int seed_count = sqrt(GRID_X) * 1;
-       const int width = 4 * (GRID_X/128);
+       /* Big seeds good for rooms */
+       const int seed_count = sqrt(grid_size.x) * 2;
+       const int width = 12 * (grid_size.x/128);
        const int height = width * 1;
        for (int n = 0; n < seed_count; n++)
        {
-               int rand_x = rand() % GRID_X;
-               int rand_y = rand() % GRID_Y;
+               int rand_x = rand() % grid_size.x;
+               int rand_y = rand() % grid_size.y;
                grid[rand_x][rand_y].b = 1.0f;
                grid[rand_x][rand_y].c = 0.0f;
 
@@ -220,7 +215,7 @@ int initialize(int worker_count, RD_Opts active_opt)
                {
                        for (int y = rand_y-(height/2); y < rand_y+(height/2); y++)
                        {
-                               if (y >= GRID_Y || x >= GRID_X || y < 0 || x < 0)
+                               if (y >= grid_size.y || x >= grid_size.x || y < 0 || x < 0)
                                        continue;
                                // Third parameter for permanent presence of B chemicals (black)
                                grid[x][y].c = 1.0f;
@@ -230,7 +225,7 @@ int initialize(int worker_count, RD_Opts active_opt)
 
        warg = (worker_arg){
                active_opt, grid, grid_prime,
-               0, 0, (GRID_X), (GRID_Y),
+               0, 0, (grid_size.x), (grid_size.y),
                .worker_count = worker_count,
                .max_iterations = active_opt.max_iterations
        };
@@ -245,7 +240,7 @@ int initialize(int worker_count, RD_Opts active_opt)
        {
                wargs[t]                                                = warg;
                wargs[t].worker_id      = t;
-               wargs[t].width                  = (GRID_X/worker_count) + ((t == worker_count-1) ? 0 : 4);
+               wargs[t].width                  = (grid_size.x/worker_count) + ((t == worker_count-1) ? 0 : 4);
                wargs[t].start_x                = (wargs[t].width * t);
                printf("worker %d x_span %d, %d\n", t, wargs[t].start_x, wargs[t].width);
                pthread_create(&threads[t], NULL, iterator, &wargs[t]);
@@ -268,14 +263,29 @@ int cleanup()
        return 0;
 }
 
-int generate_rd(int worker_count, RD_Opts active_opt)
+int generate_rd(int worker_count, RD_Opts active_opt, FVec2 **grid_buffer, IVec2 pgrid_size)
 {
+       grid = grid_buffer;
+       grid_size = pgrid_size;
+
        initialize(worker_count, active_opt);
 
        while(!should_quit) {}
 
        printf("Opts: {\nIterations: %d\nTime delta: %f\nDiffA: %f\nDiffB: %f\nFeed: %f\nKill: %f\n\n}\n", active_opt.max_iterations, active_opt.delta_t, active_opt.diff_a, active_opt.diff_b, active_opt.feed, active_opt.kill);
 
+       char buffer[pgrid_size.x][pgrid_size.y];
+       for (int x = 0; x < pgrid_size.x; x++)
+       {
+               for (int y = 0; y < pgrid_size.y; y++)
+               {
+                       buffer[x][y] = (uint8_t)(255.0f * grid_buffer[x][y].a);
+               }
+       }
+       char name[64] = {0};
+       sprintf(name, "./%s.png", active_opt.name);
+       stbi_write_png(name, pgrid_size.x, pgrid_size.y, 1, buffer, pgrid_size.x * sizeof(uint8_t));
+
        cleanup();
        return 0;
 }