2026-11-08 14:46:04 +01:00
|
|
|
#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}
|
|
|
|
|
};
|
|
|
|
|
|
2026-11-08 16:18:48 +01:00
|
|
|
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}
|
|
|
|
|
};
|
|
|
|
|
|
2026-11-08 14:46:04 +01:00
|
|
|
static const pattern_t patterns[] = {
|
|
|
|
|
{"glider", 5, glider_cells},
|
|
|
|
|
{"blinker", 3, blinker_cells},
|
|
|
|
|
{"block", 4, block_cells},
|
|
|
|
|
{"toad", 6, toad_cells},
|
2026-11-08 16:18:48 +01:00
|
|
|
{"beacon", 8, beacon_cells},
|
|
|
|
|
{"boat", 5, boat_cells},
|
|
|
|
|
{"tub", 4, tub_cells},
|
|
|
|
|
{"beehive", 6, beehive_cells},
|
|
|
|
|
{"rpentomino", 5, rpent_cells},
|
|
|
|
|
{"acorn", 7, acorn_cells},
|
2026-11-08 14:46:04 +01:00
|
|
|
};
|
|
|
|
|
|
2026-11-08 16:18:48 +01:00
|
|
|
int pattern_count(void) { return 10; }
|
2026-11-08 14:46:04 +01:00
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|