Files
wlgol/pattern.c
T
arek ed6c9c81f3 feat: add 6 more built-in patterns (Beacon, Boat, Tub, Beehive, R-pentomino, Acorn)
Extend pattern module to 10 patterns and map them to digit keys 5-0.
Update config defaults and tests.
2026-11-08 16:18:48 +01:00

98 lines
2.5 KiB
C

#include "pattern.h"
#include <limits.h>
#include <stddef.h>
static const cell_offset_t glider_cells[] = {
{1,0},{2,1},{0,2},{1,2},{2,2}
};
static const cell_offset_t blinker_cells[] = {
{0,0},{1,0},{2,0}
};
static const cell_offset_t block_cells[] = {
{0,0},{1,0},{0,1},{1,1}
};
static const cell_offset_t toad_cells[] = {
{1,0},{2,0},{3,0},{0,1},{1,1},{2,1}
};
static const cell_offset_t beacon_cells[] = {
{0,0},{1,0},{0,1},{1,1},{2,2},{3,2},{2,3},{3,3}
};
static const cell_offset_t boat_cells[] = {
{0,0},{1,0},{0,1},{2,1},{1,2}
};
static const cell_offset_t tub_cells[] = {
{1,0},{0,1},{2,1},{1,2}
};
static const cell_offset_t beehive_cells[] = {
{1,0},{2,0},{0,1},{3,1},{1,2},{2,2}
};
static const cell_offset_t rpent_cells[] = {
{1,0},{2,0},{0,1},{1,1},{1,2}
};
static const cell_offset_t acorn_cells[] = {
{1,0},{3,1},{0,2},{1,2},{2,2},{3,2},{4,2}
};
static const pattern_t patterns[] = {
{"glider", 5, glider_cells},
{"blinker", 3, blinker_cells},
{"block", 4, block_cells},
{"toad", 6, toad_cells},
{"beacon", 8, beacon_cells},
{"boat", 5, boat_cells},
{"tub", 4, tub_cells},
{"beehive", 6, beehive_cells},
{"rpentomino", 5, rpent_cells},
{"acorn", 7, acorn_cells},
};
int pattern_count(void) { return 10; }
const pattern_t *pattern_get(int index) {
if (index < 0 || index >= pattern_count()) return NULL;
return &patterns[index];
}
int pattern_rotated_offsets(int index, int rotation, int *out_dx, int *out_dy) {
const pattern_t *p = pattern_get(index);
if (!p) return 0;
rotation = ((rotation % 4) + 4) % 4;
int minx = INT_MAX, miny = INT_MAX;
int tx[16], ty[16];
for (int i = 0; i < p->count; i++) {
int x = p->cells[i].dx;
int y = p->cells[i].dy;
for (int r = 0; r < rotation; r++) {
int nx = y;
int ny = -x;
x = nx; y = ny;
}
tx[i] = x; ty[i] = y;
if (x < minx) minx = x;
if (y < miny) miny = y;
}
for (int i = 0; i < p->count; i++) {
out_dx[i] = tx[i] - minx;
out_dy[i] = ty[i] - miny;
}
return p->count;
}
void pattern_bounds(int index, int rotation, int *w, int *h) {
int dx[16], dy[16];
int n = pattern_rotated_offsets(index, rotation, dx, dy);
int maxx = 0, maxy = 0;
for (int i = 0; i < n; i++) {
if (dx[i] > maxx) maxx = dx[i];
if (dy[i] > maxy) maxy = dy[i];
}
if (w) *w = maxx + 1;
if (h) *h = maxy + 1;
}