mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-21 16:05:44 -07:00
hat-test: alternative data output mode to write Python.
This mode emits a sequence of calls to an imaginary Python function. Should be useful to anyone wanting to post-process the tiling in any way.
This commit is contained in:
118
hat.c
118
hat.c
@ -1256,43 +1256,83 @@ static inline void psbbox_add(psbbox *bbox, pspoint p)
|
|||||||
bbox->started = true;
|
bbox->started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void header(psbbox *bbox)
|
typedef enum OutFmt { OF_POSTSCRIPT, OF_PYTHON } OutFmt;
|
||||||
{
|
|
||||||
float xext = bbox->tr.x - bbox->bl.x, yext = bbox->tr.y - bbox->bl.y;
|
|
||||||
float ext = (xext > yext ? xext : yext);
|
|
||||||
float scale = 500 / ext;
|
|
||||||
float ox = 287 - scale * (bbox->bl.x + bbox->tr.x) / 2;
|
|
||||||
float oy = 421 - scale * (bbox->bl.y + bbox->tr.y) / 2;
|
|
||||||
|
|
||||||
printf("%%!PS-Adobe-2.0\n%%%%Creator: hat-test from Simon Tatham's "
|
typedef struct drawctx {
|
||||||
"Portable Puzzle Collection\n%%%%Pages: 1\n"
|
OutFmt outfmt;
|
||||||
"%%%%BoundingBox: %f %f %f %f\n"
|
psbbox *bbox;
|
||||||
"%%%%EndComments\n%%%%Page: 1 1\n",
|
} drawctx;
|
||||||
ox + scale * bbox->bl.x - 20, oy + scale * bbox->bl.y - 20,
|
|
||||||
ox + scale * bbox->tr.x + 20, oy + scale * bbox->tr.y + 20);
|
|
||||||
|
|
||||||
printf("%f %f translate %f dup scale\n", ox, oy, scale);
|
|
||||||
printf("%f setlinewidth\n", scale * 0.03);
|
|
||||||
printf("0 setgray 1 setlinejoin 1 setlinecap\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void bbox_add_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
|
static void bbox_add_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
|
||||||
{
|
{
|
||||||
psbbox *bbox = (psbbox *)vctx;
|
drawctx *ctx = (drawctx *)vctx;
|
||||||
pspoint p;
|
pspoint p;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < 14; i++) {
|
for (i = 0; i < 14; i++) {
|
||||||
p.x = coords[2*i] * 1.5;
|
p.x = coords[2*i] * 1.5;
|
||||||
p.y = coords[2*i+1] * sqrt(0.75);
|
p.y = coords[2*i+1] * sqrt(0.75);
|
||||||
psbbox_add(bbox, p);
|
psbbox_add(ctx->bbox, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void header(drawctx *ctx)
|
||||||
|
{
|
||||||
|
switch (ctx->outfmt) {
|
||||||
|
case OF_POSTSCRIPT: {
|
||||||
|
float xext = ctx->bbox->tr.x - ctx->bbox->bl.x;
|
||||||
|
float yext = ctx->bbox->tr.y - ctx->bbox->bl.y;
|
||||||
|
float ext = (xext > yext ? xext : yext);
|
||||||
|
float scale = 500 / ext;
|
||||||
|
float ox = 287 - scale * (ctx->bbox->bl.x + ctx->bbox->tr.x) / 2;
|
||||||
|
float oy = 421 - scale * (ctx->bbox->bl.y + ctx->bbox->tr.y) / 2;
|
||||||
|
|
||||||
|
printf("%%!PS-Adobe-2.0\n%%%%Creator: hat-test from Simon Tatham's "
|
||||||
|
"Portable Puzzle Collection\n%%%%Pages: 1\n"
|
||||||
|
"%%%%BoundingBox: %f %f %f %f\n"
|
||||||
|
"%%%%EndComments\n%%%%Page: 1 1\n",
|
||||||
|
ox + scale * ctx->bbox->bl.x - 20,
|
||||||
|
oy + scale * ctx->bbox->bl.y - 20,
|
||||||
|
ox + scale * ctx->bbox->tr.x + 20,
|
||||||
|
oy + scale * ctx->bbox->tr.y + 20);
|
||||||
|
|
||||||
|
printf("%f %f translate %f dup scale\n", ox, oy, scale);
|
||||||
|
printf("%f setlinewidth\n", scale * 0.03);
|
||||||
|
printf("0 setgray 1 setlinejoin 1 setlinecap\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void draw_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
|
static void draw_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
|
||||||
{
|
{
|
||||||
|
drawctx *ctx = (drawctx *)vctx;
|
||||||
pspoint p;
|
pspoint p;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int orientation;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determine an index for the hat's orientation, based on the axis
|
||||||
|
* of symmetry of its kite #0.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
int dx = kite0.outer.x - kite0.centre.x;
|
||||||
|
int dy = kite0.outer.y - kite0.centre.y;
|
||||||
|
orientation = 0;
|
||||||
|
while (dx < 0 || dy < 0) {
|
||||||
|
int newdx = dx + dy;
|
||||||
|
int newdy = -dx;
|
||||||
|
dx = newdx;
|
||||||
|
dy = newdy;
|
||||||
|
orientation++;
|
||||||
|
assert(orientation < 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ctx->outfmt) {
|
||||||
|
case OF_POSTSCRIPT: {
|
||||||
const char *colour;
|
const char *colour;
|
||||||
|
|
||||||
printf("newpath");
|
printf("newpath");
|
||||||
@ -1312,13 +1352,31 @@ static void draw_hat(void *vctx, Kite kite0, HatCoords *hc, int *coords)
|
|||||||
}
|
}
|
||||||
printf(" %s fill grestore", colour);
|
printf(" %s fill grestore", colour);
|
||||||
printf(" stroke\n");
|
printf(" stroke\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case OF_PYTHON: {
|
||||||
|
printf("hat('%c', %d, %d, [", "HTPF"[hc->c[2].type], hc->c[1].index,
|
||||||
|
orientation);
|
||||||
|
for (i = 0; i < 14; i++)
|
||||||
|
printf("%s(%d,%d)", i ? ", " : "", coords[2*i], coords[2*i+1]);
|
||||||
|
printf("])\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void trailer(void)
|
static void trailer(drawctx *dctx)
|
||||||
{
|
{
|
||||||
|
switch (dctx->outfmt) {
|
||||||
|
case OF_POSTSCRIPT: {
|
||||||
printf("showpage\n");
|
printf("showpage\n");
|
||||||
printf("%%%%Trailer\n");
|
printf("%%%%Trailer\n");
|
||||||
printf("%%%%EOF\n");
|
printf("%%%%EOF\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
@ -1331,6 +1389,9 @@ int main(int argc, char **argv)
|
|||||||
int w = 10, h = 10;
|
int w = 10, h = 10;
|
||||||
int argpos = 0;
|
int argpos = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
drawctx dctx[1];
|
||||||
|
|
||||||
|
dctx->outfmt = OF_POSTSCRIPT;
|
||||||
|
|
||||||
while (--argc > 0) {
|
while (--argc > 0) {
|
||||||
const char *arg = *++argv;
|
const char *arg = *++argv;
|
||||||
@ -1340,6 +1401,8 @@ int main(int argc, char **argv)
|
|||||||
return 0;
|
return 0;
|
||||||
} else if (!strcmp(arg, "--test")) {
|
} else if (!strcmp(arg, "--test")) {
|
||||||
return unit_tests() ? 0 : 1;
|
return unit_tests() ? 0 : 1;
|
||||||
|
} else if (!strcmp(arg, "--python")) {
|
||||||
|
dctx->outfmt = OF_PYTHON;
|
||||||
} else if (arg[0] == '-') {
|
} else if (arg[0] == '-') {
|
||||||
fprintf(stderr, "unrecognised option '%s'\n", arg);
|
fprintf(stderr, "unrecognised option '%s'\n", arg);
|
||||||
return 1;
|
return 1;
|
||||||
@ -1364,42 +1427,43 @@ int main(int argc, char **argv)
|
|||||||
init_coords_random(ctx, rs);
|
init_coords_random(ctx, rs);
|
||||||
|
|
||||||
bbox->started = false;
|
bbox->started = false;
|
||||||
|
dctx->bbox = bbox;
|
||||||
|
|
||||||
first_kite(s, w, h);
|
first_kite(s, w, h);
|
||||||
coords[s->curr_index] = initial_coords(ctx);
|
coords[s->curr_index] = initial_coords(ctx);
|
||||||
maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
|
maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
|
||||||
bbox_add_hat, bbox);
|
bbox_add_hat, dctx);
|
||||||
while (next_kite(s)) {
|
while (next_kite(s)) {
|
||||||
hc_free(coords[s->curr_index]);
|
hc_free(coords[s->curr_index]);
|
||||||
coords[s->curr_index] = step_coords(
|
coords[s->curr_index] = step_coords(
|
||||||
ctx, coords[s->last_index], s->last_step);
|
ctx, coords[s->last_index], s->last_step);
|
||||||
maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
|
maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
|
||||||
bbox_add_hat, bbox);
|
bbox_add_hat, dctx);
|
||||||
}
|
}
|
||||||
for (i = 0; i < lenof(coords); i++) {
|
for (i = 0; i < lenof(coords); i++) {
|
||||||
hc_free(coords[i]);
|
hc_free(coords[i]);
|
||||||
coords[i] = NULL;
|
coords[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
header(bbox);
|
header(dctx);
|
||||||
|
|
||||||
first_kite(s, w, h);
|
first_kite(s, w, h);
|
||||||
coords[s->curr_index] = initial_coords(ctx);
|
coords[s->curr_index] = initial_coords(ctx);
|
||||||
maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
|
maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
|
||||||
draw_hat, NULL);
|
draw_hat, dctx);
|
||||||
while (next_kite(s)) {
|
while (next_kite(s)) {
|
||||||
hc_free(coords[s->curr_index]);
|
hc_free(coords[s->curr_index]);
|
||||||
coords[s->curr_index] = step_coords(
|
coords[s->curr_index] = step_coords(
|
||||||
ctx, coords[s->last_index], s->last_step);
|
ctx, coords[s->last_index], s->last_step);
|
||||||
maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
|
maybe_report_hat(w, h, *s->curr, coords[s->curr_index],
|
||||||
draw_hat, NULL);
|
draw_hat, dctx);
|
||||||
}
|
}
|
||||||
for (i = 0; i < lenof(coords); i++) {
|
for (i = 0; i < lenof(coords); i++) {
|
||||||
hc_free(coords[i]);
|
hc_free(coords[i]);
|
||||||
coords[i] = NULL;
|
coords[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
trailer();
|
trailer(dctx);
|
||||||
|
|
||||||
cleanup_coords(ctx);
|
cleanup_coords(ctx);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user