💾 Archived View for thrig.me › blog › 2024 › 03 › 11 › smolpath.c captured on 2024-05-12 at 15:49:09.

View Raw

More Information

⬅️ Previous capture (2024-03-21)

-=-=-=-=-=-=-

// smolpath - small example of bespoke pathfinding

#include <stdint.h>
#include <stdio.h>

#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;

// this should be allocated, but that's more complicated
static int smell[MAP_LINES][MAP_COLS];

// presumably the smell goes away over time
inline static void
smell_decrease(void)
{
	for (size_t y = 0; y < MAP_LINES; ++y)
		for (size_t x = 0; x < MAP_COLS; ++x)
			smell[y][x] = MAX(smell[y][x] - 1, 0);
}

// make adjacent smells one less than the current cell, if not higher
inline static void
tweak_adjacent(size_t y, size_t x)
{
	const int value = MAX(smell[y][x] - 1, 0);
	size_t newy, newx = x;
	newy = y - 1;
	if (newy < SIZE_MAX && smell[newy][newx] < value)
		smell[newy][newx] = value;
	newy = y + 1;
	if (newy < MAP_LINES && smell[newy][newx] < value)
		smell[newy][newx] = value;
	newy = y;
	newx = x - 1;
	if (newx < SIZE_MAX && smell[newy][newx] < value)
		smell[newy][newx] = value;
	newx = x + 1;
	if (newx < MAP_COLS && smell[newy][newx] < value)
		smell[newy][newx] = value;
}

// spread it around...
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);
	// and let any weak spots fade out
	smell_decrease();
}

// put a smell somewhere
void
smell_mark(point *origin, int amount)
{
	smell[origin->yy][origin->xx] = amount;
	smell_spread();
}

void
smell_show(void)
{
	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');
	}
}

int
main(void)
{
	smell_mark(&(point){.xx = MAP_COLS / 2, .yy = MAP_LINES / 2}, 9);
	smell_show();
}