shithub: puzzles

Download patch

ref: 68a1e8413c500f62f81c5a283de47bf404346edc
parent: 86466959e8dc127513c1dc5c702492c8107c4b20
author: Simon Tatham <anakin@pobox.com>
date: Sun Jun 18 05:18:58 EDT 2023

spectre.c: expose a couple more internal functions.

spectre-test will want to use these for an additional generation mode.

--- a/spectre-internal.h
+++ b/spectre-internal.h
@@ -103,6 +103,9 @@
 /* Fill in all the coordinates of a Spectre starting from any single edge */
 void spectre_place(Spectre *spec, Point u, Point v, int index_of_u);
 
+/* Free a Spectre and its contained coordinates */
+void spectre_free(Spectre *spec);
+
 /*
  * A Point is really a complex number, so we can add, subtract and
  * multiply them.
@@ -236,6 +239,12 @@
 void spectrectx_step_hex(SpectreContext *ctx, SpectreCoords *sc,
                          size_t depth, unsigned edge, unsigned *outedge);
 
+/* Subroutines that step around the tiling specified by a SpectreCtx,
+ * delivering both plane and combinatorial coordinates as they go */
+Spectre *spectre_initial(SpectreContext *ctx);
+Spectre *spectre_adjacent(SpectreContext *ctx, const Spectre *src_spec,
+                          unsigned src_edge);
+
 /* For extracting the point coordinates */
 typedef struct Coord {
     int c1, cr3;      /* coefficients of 1 and sqrt(3) respectively */
@@ -268,10 +277,51 @@
         return x.cr3 < 0 ? -1 : +1;
 }
 
-static inline int coord_cmp(Coord a, Coord b)
+static inline Coord coord_construct(int c1, int cr3)
 {
+    Coord c = { c1, cr3 };
+    return c;
+}
+
+static inline Coord coord_integer(int c1)
+{
+    return coord_construct(c1, 0);
+}
+
+static inline Coord coord_add(Coord a, Coord b)
+{
+    Coord sum;
+    sum.c1 = a.c1 + b.c1;
+    sum.cr3 = a.cr3 + b.cr3;
+    return sum;
+}
+
+static inline Coord coord_sub(Coord a, Coord b)
+{
     Coord diff;
     diff.c1 = a.c1 - b.c1;
     diff.cr3 = a.cr3 - b.cr3;
-    return coord_sign(diff);
+    return diff;
+}
+
+static inline Coord coord_mul(Coord a, Coord b)
+{
+    Coord prod;
+    prod.c1 = a.c1 * b.c1 + 3 * a.cr3 * b.cr3;
+    prod.cr3 = a.c1 * b.cr3 + a.cr3 * b.c1;
+    return prod;
+}
+
+static inline Coord coord_abs(Coord a)
+{
+    int sign = coord_sign(a);
+    Coord abs;
+    abs.c1 = a.c1 * sign;
+    abs.cr3 = a.cr3 * sign;
+    return abs;
+}
+
+static inline int coord_cmp(Coord a, Coord b)
+{
+    return coord_sign(coord_sub(a, b));
 }
--- a/spectre.c
+++ b/spectre.c
@@ -145,17 +145,16 @@
     }
 }
 
-static Spectre *spectre_initial(Point u, Point v, int index_of_u,
-                                SpectreCoords *sc)
+Spectre *spectre_initial(SpectreContext *ctx)
 {
     Spectre *spec = snew(Spectre);
-    spectre_place(spec, u, v, index_of_u);
-    spec->sc = spectre_coords_copy(sc);
+    spectre_place(spec, ctx->start_vertices[0], ctx->start_vertices[1], 0);
+    spec->sc = spectre_coords_copy(ctx->prototype);
     return spec;
 }
 
-static Spectre *spectre_adjacent(
-    SpectreContext *ctx, const Spectre *src_spec, unsigned src_edge)
+Spectre *spectre_adjacent(SpectreContext *ctx, const Spectre *src_spec,
+                          unsigned src_edge)
 {
     unsigned dst_edge;
     Spectre *dst_spec = snew(Spectre);
@@ -186,7 +185,7 @@
     return 0;
 }
 
-static void spectre_free(Spectre *spec)
+void spectre_free(Spectre *spec)
 {
     spectre_coords_free(spec->sc);
     sfree(spec);
@@ -438,10 +437,7 @@
     Spectre *qhead = NULL, *qtail = NULL;
 
     {
-        SpectreCoords *sc = spectrectx_initial_coords(ctx);
-        Spectre *spec = spectre_initial(ctx->start_vertices[0],
-                                        ctx->start_vertices[1], 0, sc);
-        spectre_coords_free(sc);
+        Spectre *spec = spectre_initial(ctx);
 
         add234(placed, spec);