From 497f7f6c0fcb9b8747fdd442cae1e867c9383893 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sat, 9 Mar 2019 01:00:46 +0100 Subject: [PATCH] 3d:: reg3:: distances and alt-distances --- bigstuff.cpp | 17 ++++++++---- cell.cpp | 2 +- hyper.h | 4 ++- landgen.cpp | 2 +- reg3.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++++----- 5 files changed, 88 insertions(+), 15 deletions(-) diff --git a/bigstuff.cpp b/bigstuff.cpp index e32907d9..ee8a9ab4 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -197,6 +197,7 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) { // okay, let's go then! cellwalker bf(c, gdir); + if(PURE) bf += rev; std::vector cx(rad+1); for(int i=0; ialt = alt; h->alt = alt; alt->cdata = (cdata*) h; + currentmap->link_alt(bf); for(int d=rad; d>=0; d--) { currentmap->generateAlts(cx[d]->master); @@ -1294,6 +1296,11 @@ void buildCamelot(cell *c) { } } +int masterAlt(cell *c) { + if(DIM == 3 && hyperbolic) return reg3::altdist(c->master); + return c->master->alt->distance; + } + void moreBigStuff(cell *c) { if((bearsCamelot(c->land) && !euclid && !quotient) || c->land == laCamelot) @@ -1312,7 +1319,7 @@ void moreBigStuff(cell *c) { if(c->land == laStorms) if(!eubinary && !quotient && !sphere) { - if(c->master->alt && c->master->alt->distance <= 2) { + if(c->master->alt && masterAlt(c) <= 2) { currentmap->generateAlts(c->master); preventbarriers(c); int d = celldistAlt(c); @@ -1335,7 +1342,7 @@ void moreBigStuff(cell *c) { } else if((c->land == laRlyeh && !euclid) || c->land == laTemple) if(!(binarytiling && specialland != laTemple)) { - if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) { + if(eubinary || (c->master->alt && (tactic::on || masterAlt(c) <= 2))) { if(!eubinary && !chaosmode) currentmap->generateAlts(c->master); preventbarriers(c); int d = celldistAlt(c); @@ -1365,7 +1372,7 @@ void moreBigStuff(cell *c) { } if((c->land == laOvergrown && !euclid) || c->land == laClearing) if(!(binarytiling && specialland != laClearing)) { - if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) { + if(eubinary || (c->master->alt && (tactic::on || masterAlt(c) <= 2))) { if(!eubinary) currentmap->generateAlts(c->master); preventbarriers(c); int d = celldistAlt(c); @@ -1378,7 +1385,7 @@ void moreBigStuff(cell *c) { } if((c->land == laJungle && !euclid) || c->land == laMountain) if(!(binarytiling && specialland != laMountain)) { - if(eubinary || (c->master->alt && (tactic::on || c->master->alt->distance <= 2))) { + if(eubinary || (c->master->alt && (tactic::on || masterAlt(c) <= 2))) { if(!eubinary) currentmap->generateAlts(c->master); preventbarriers(c); int d = celldistAlt(c); @@ -1394,7 +1401,7 @@ void moreBigStuff(cell *c) { fullwhirlpool = true; if(yendor::on && yendor::clev().l == laWhirlpool) fullwhirlpool = true; - if(eubinary || (c->master->alt && (fullwhirlpool || c->master->alt->distance <= 2))) { + if(eubinary || (c->master->alt && (fullwhirlpool || masterAlt(c) <= 2))) { if(!eubinary) currentmap->generateAlts(c->master); preventbarriers(c); int dd = celldistAlt(c); diff --git a/cell.cpp b/cell.cpp index 18d70c94..cf75457d 100644 --- a/cell.cpp +++ b/cell.cpp @@ -439,7 +439,7 @@ int celldistAlt(cell *c) { #if MAXMDIM == 4 if(euclid && DIM == 3) return euclid3::dist_alt(c); #endif - if(hyperbolic && DIM == 3) return reg3::dist_alt(c); + if(hyperbolic && DIM == 3) return reg3::altdist(c->master); if(!c->master->alt) return 0; #if CAP_IRR if(IRREGULAR) return irr::celldist(c, true); diff --git a/hyper.h b/hyper.h index 36e1a21d..4e1e7b1a 100644 --- a/hyper.h +++ b/hyper.h @@ -96,7 +96,7 @@ void addMessage(string s, char spamtype = 0); #define binarytiling (geometry == gBinaryTiling || geometry == gBinary3 || geometry == gHoroTris) #define archimedean (geometry == gArchimedean) -#define eubinary (euclid || binarytiling || geometry == gCrystal || (DIM == 3 && hyperbolic)) +#define eubinary (euclid || binarytiling || geometry == gCrystal) #define cgclass (ginf[geometry].cclass) #define euclid (cgclass == gcEuclid) @@ -2939,6 +2939,7 @@ extern string s0; extern int anthraxBonus; int celldistAlt(cell *c); int celldist(cell *c); +int masterAlt(cell *c); int getHemisphere(cell *c, int which); namespace tactic { @@ -4301,6 +4302,7 @@ namespace reg3 { extern vector cellshape; int celldistance(cell *c1, cell *c2); bool pseudohept(cell *c); + inline short& altdist(heptagon *h) { return h->emeraldval; } } #endif diff --git a/landgen.cpp b/landgen.cpp index 4430a799..4cd51b5f 100644 --- a/landgen.cpp +++ b/landgen.cpp @@ -1513,7 +1513,7 @@ void giantLandSwitch(cell *c, int d, cell *from) { case laCaribbean: if(fargen) { if(!eubinary) { - if(c->master->alt && c->master->alt->distance <= 2) { + if(c->master->alt && masterAlt(c) <= 2) { if(!eubinary) currentmap->generateAlts(c->master); preventbarriers(c); int d = celldistAlt(c); diff --git a/reg3.cpp b/reg3.cpp index 8db3e440..dc2451a1 100644 --- a/reg3.cpp +++ b/reg3.cpp @@ -196,6 +196,7 @@ namespace reg3 { alt->distance = 0; alt->alt = alt; alt->cdata = NULL; + alt->c7 = NULL; binary_map = binary::new_alt_map(alt); T = xpush(.01241) * spin(1.4117) * xpush(0.1241) * cspin(0, 2, 1.1249) * xpush(0.07) * Id; } @@ -217,6 +218,40 @@ namespace reg3 { return origin; } + void fix_distances(heptagon *h, heptagon *h2) { + vector to_fix; + + auto fix_pair = [&] (heptagon *h, heptagon *h2) { + if(!h2) return; + if(h->distance > h2->distance+1) { + h->distance = h2->distance + 1; + to_fix.push_back(h); + } + else if(h2->distance > h->distance+1) { + h2->distance = h->distance + 1; + to_fix.push_back(h2); + } + if(h->alt && h->alt == h2->alt) { + if(altdist(h) > altdist(h2) + 1) { + altdist(h) = altdist(h2) + 1; + to_fix.push_back(h); + } + else if (altdist(h2) > altdist(h) + 1) { + altdist(h2) = altdist(h) + 1; + to_fix.push_back(h2); + } + } + }; + + if(!h2) to_fix = {h}; + else fix_pair(h, h2); + + for(int i=0; imove(j)); + } + } + #define DEB 0 heptagon *create_step(heptagon *parent, int d) { @@ -252,6 +287,7 @@ namespace reg3 { if(err > worst_error2) println(hlog, format("worst_error2 = %lg", double(worst_error2 = err))); if(p2.first->move(d2)) println(hlog, "error: repeated edge"); p2.first->c.connect(d2, parent, d, false); + fix_distances(p2.first, parent); fb++; } } @@ -271,7 +307,9 @@ namespace reg3 { heptagon *created = tailored_alloc (S7); created->c7 = newCell(S7, created); created->alt = NULL; + created->cdata = NULL; created->zebraval = hrand(10); + created->distance = parent->distance + 1; fixmatrix(T); reg_gmatrix[created] = make_pair(alt, T); altmap[alt].emplace_back(created, T); @@ -280,11 +318,39 @@ namespace reg3 { } ~hrmap_reg3() { - if(binary_map) delete binary_map; + if(binary_map) { + dynamicval g(geometry, gBinary3); + // delete binary_map; + } clearfrom(origin); } - void generateAlts(heptagon* h) { + map reducers; + + void link_alt(const cellwalker& hs) override { + auto h = hs.at->master; + altdist(h) = 0; + if(h->alt->s != hsOrigin) reducers[h] = hs.spin; + } + + void generateAlts(heptagon* h, int levs, bool link_cdata) override { + if(reducers.count(h)) { + heptspin hs(h, reducers[h]); + reducers.erase(h); + hs += wstep; + hs += rev; + altdist(hs.at) = altdist(h) - 1; + hs.at->alt = h->alt; + reducers[hs.at] = hs.spin; + } + for(int i=0; icmove(i); + if(h2->alt == NULL) { + h2->alt = h->alt; + altdist(h2) = altdist(h) + 1; + fix_distances(h2, NULL); + } + } } void draw() { @@ -338,6 +404,8 @@ hrmap_reg3* regmap() { int celldistance(cell *c1, cell *c2) { if(c1 == c2) return 0; + if(c1 == currentmap->gamestart()) return c2->master->distance; + if(c2 == currentmap->gamestart()) return c1->master->distance; auto r = regmap(); @@ -370,15 +438,11 @@ bool pseudohept(cell *c) { return abs(h[3]) > .99 || abs(h[0]) > .99 || abs(h[1]) > .99 || abs(h[2]) > .99; } if(hyperbolic) { - heptagon *h = regmap()->reg_gmatrix[c->master].first; + heptagon *h = m->reg_gmatrix[c->master].first; return (h->zebraval == 1) && (h->distance & 1); } return false; } - -int dist_alt(cell *c) { - return regmap()->reg_gmatrix[c->master].first->distance; - } #endif #if 0