💾 Archived View for thrig.me › blog › 2024 › 03 › 11 › smolpath3.c captured on 2024-05-26 at 15:46:43.
⬅️ Previous capture (2024-03-21)
-=-=-=-=-=-=-
// smolpath III - the search for smell (II was the "waft of khan") #include <assert.h> #include <stdint.h> #include <stdio.h> #define NO_SMELL -1 #define LOW_SMELL 0 #define MAP_LINES 15 #define MAP_COLS 9 #define MAX(a, b) (((a) > (b)) ? (a) : (b)) typedef struct { int xx; // "xx" is easier to find and less common than just "x" int yy; } point; // clang-format off /* *INDENT-OFF* */ // here we "box" the target in static int smell[MAP_LINES][MAP_COLS] = { { 0, 0, 0, 0,-1, 0, 0, 0, 0 }, { 0,-1,-1, 0,-1, 0, 0, 0, 0 }, { 0, 0,-1, 0,-1, 0, 0, 0, 0 }, {-1, 0,-1, 0,-1,-1,-1,-1, 0 }, { 0, 0,-1, 0, 0, 0, 0, 0, 0 }, { 0,-1,-1, 0,-1,-1,-1,-1, 0 }, { 0, 0,-1, 0, 0, 0,-1, 0, 0 }, {-1, 0,-1, 0, 0, 0,-1, 0, 0 }, { 0, 0,-1, 0, 0, 0,-1, 0, 0 }, { 0,-1,-1,-1,-1,-1,-1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, {-1,-1,-1,-1,-1,-1,-1,-1, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, }; /* *INDENT-ON* */ // clang-format on inline static void smell_decrease(void) { for (size_t y = 0; y < MAP_LINES; ++y) { for (size_t x = 0; x < MAP_COLS; ++x) { if (smell[y][x] < LOW_SMELL) continue; smell[y][x] = MAX(smell[y][x] - 1, LOW_SMELL); } } } inline static void tweak_adjacent(size_t y, size_t x) { const int value = MAX(smell[y][x] - 1, LOW_SMELL); size_t newy, newx = x; newy = y - 1; if (newy < SIZE_MAX && smell[newy][newx] >= LOW_SMELL && smell[newy][newx] < value) smell[newy][newx] = value; newy = y + 1; if (newy < MAP_LINES && smell[newy][newx] >= LOW_SMELL && smell[newy][newx] < value) smell[newy][newx] = value; newy = y; newx = x - 1; if (newx < SIZE_MAX && smell[newy][newx] >= LOW_SMELL && smell[newy][newx] < value) smell[newy][newx] = value; newx = x + 1; if (newx < MAP_COLS && smell[newy][newx] >= LOW_SMELL && smell[newy][newx] < value) smell[newy][newx] = value; } inline static void smell_spread(void) { for (size_t y = 0; y < MAP_LINES; ++y) for (size_t x = 0; x < MAP_COLS; ++x) tweak_adjacent(y, x); for (size_t y = MAP_LINES - 1; y < SIZE_MAX; --y) for (size_t x = MAP_COLS - 1; x < SIZE_MAX; --x) tweak_adjacent(y, x); smell_decrease(); } void smell_mark(point *origin, int amount) { assert(smell[origin->yy][origin->xx] >= LOW_SMELL); smell[origin->yy][origin->xx] = amount; smell_spread(); } void smell_show(void) { printf("%d %d\n", MAP_COLS, MAP_LINES); for (size_t y = 0; y < MAP_LINES; ++y) { for (size_t x = 0; x < MAP_COLS; ++x) { printf("% 3d", smell[y][x]); } putchar('\n'); } } static void smell_and_show(point *pos, int amount) { smell_mark(pos, amount); smell_show(); putchar('\n'); } int main(void) { point pos; pos.xx = MAP_COLS / 2; pos.yy = MAP_LINES / 2; int amount = 21; smell_and_show(&pos, amount); // and make some moves to see how moving affects the spread pos.xx--; smell_and_show(&pos, amount); for (size_t x = 0; x < 5; ++x) { pos.yy--; smell_and_show(&pos, amount); } }