commit b612ef736b986ac1918ae580b5b422ac64c206de
parent 38fb4a5bfce0be5fd2df2c982051794c8f62c0ea
Author: Robert Russell <robert@rr3.xyz>
Date: Mon, 26 Aug 2024 04:16:38 -0700
Add executable for generating sandpiles by piling sand in rectangles
Diffstat:
| M | src/spgen.c | | | 85 | +++++++++++++++++++++++++++++++++++++++++++++++-------------------------------- |
1 file changed, 51 insertions(+), 34 deletions(-)
diff --git a/src/spgen.c b/src/spgen.c
@@ -1,13 +1,12 @@
#include <rcx/all.h>
#include <stdio.h>
-#include <string.h>
+#include <stdlib.h>
#include "common.h"
-/*
-#define USAGE "usage: %s WIDTH HEIGHT RECTS..."
-
-#define SAND(x, y) sand[((y) + 1) * (w + 2) + ((x) + 1)]
+#define USAGE \
+ "usage: %s WIDTH HEIGHT RECT...\n" \
+ "where RECT ::= X,Y:W,H:S\n"
typedef struct rect Rect;
@@ -18,50 +17,68 @@ struct rect {
};
void
-parse_rect(Rect *r, char *s) {
- RStr a[2];
- if (r_rstr_split(&a, s, ":", 2) != 2) // panic
+parse_rect(usize i, Rect *r, char *s) {
+ char **xy_wh_s = (char*[3]){};
+ if (r_str_split(&xy_wh_s, s, ":", 3) != 3)
+ r_fatalf("rectangle %zu malformed", i);
- char *colon = strchr(s, ':');
- if (!colon)
-}
+ char **x_y = (char*[2]){};
+ if (r_str_split(&x_y, xy_wh_s[0], ",", 2) != 2)
+ r_fatalf("rectangle %zu malformed", i);
-void
-usage(char *argv0) {
- fprintf(stderr, USAGE, argv0);
- exit(1);
+ char **w_h = (char*[2]){};
+ if (r_str_split(&w_h, xy_wh_s[1], ",", 2) != 2)
+ r_fatalf("rectangle %zu malformed", i);
+
+ if (r_conv_zstr_to_u32(&r->x, x_y[0], 0) < 0)
+ r_fatalf("invalid x position in rectangle %zu", i);
+
+ if (r_conv_zstr_to_u32(&r->y, x_y[1], 0) < 0)
+ r_fatalf("invalid y position in rectangle %zu", i);
+
+ if (r_conv_zstr_to_u32(&r->w, w_h[0], 0) < 0)
+ r_fatalf("invalid width in rectangle %zu", i);
+
+ if (r_conv_zstr_to_u32(&r->h, w_h[1], 0) < 0)
+ r_fatalf("invalid height in rectangle %zu", i);
+
+ if (r_conv_zstr_to_u32(&r->s, xy_wh_s[2], 0) < 0)
+ r_fatalf("invalid sand in rectangle %zu", i);
}
-*/
int
main(int argc, char **argv) {
- printf("spgen\n");
- /*
CHECK_FOR_HELP_OPTION(USAGE, argc, argv);
- if (argc < 3) usage(argv[0]);
+ if (argc < 3) {
+ fprintf(stderr, USAGE, argv[0]);
+ exit(1);
+ }
u32 w, h;
- if (r_conv_zstr_to_u32(&w, argv[1], 0) < 0) usage(argv[0]);
- if (r_conv_zstr_to_u32(&h, argv[2], 0) < 0) usage(argv[0]);
+ if (r_conv_zstr_to_u32(&w, argv[1], 0) < 0) r_fatalf("invalid width");
+ if (r_conv_zstr_to_u32(&h, argv[2], 0) < 0) r_fatalf("invalid height");
+
+ u32 *sand = r_eallocz((w + 2) * (h + 2) * sizeof(u32));
+ Sandpile sp = { .w = w, .h = h, .sand = sand };
+#define SAND(x, y) sand[((y) + 1) * (w + 2) + ((x) + 1)]
usize nrects = argc - 3;
- Rect *rects = r_eallocn(nrects, sizeof *rects);
for (usize i = 0; i < nrects; i++) {
- parse_rect()
- rects[i] =
- }
+ Rect r;
+ parse_rect(i, &r, argv[3+i]);
- usize w = 32;
- usize h = 32;
- u32 *sand = r_eallocz((w + 2) * (h + 2) * sizeof(u32));
- Sandpile sp = { .w = w, .h = h, .sand = sand };
+ usize xmin = r.x;
+ usize xmax = MIN(w, r.x + r.w);
- SAND(15, 15) = 420;
- SAND(15, 16) = 420;
- SAND(16, 15) = 420;
- SAND(16, 16) = 420;
+ usize ymin = r.y;
+ usize ymax = MIN(h, r.y + r.h);
+
+ for (usize y = ymin; y < ymax; y++) {
+ for (usize x = xmin; x < xmax; x++)
+ SAND(x, y) += r.s;
+ }
+ }
sp_fwrite(stdout, sp);
- */
}