From 8d5a358b3884cfe425dec2269763e1deb8e8a104 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Fri, 6 Mar 2020 02:36:11 +0100 Subject: [PATCH] reg3:: added celldistance_534 --- reg3.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/reg3.cpp b/reg3.cpp index 11c0aed5..2c0e9321 100644 --- a/reg3.cpp +++ b/reg3.cpp @@ -1254,10 +1254,55 @@ EX int quotient_count() { return isize(regmap()->quotient_map->allh); } +/** This is a generalization of hyperbolic_celldistance in expansion.cpp to three dimensions. + It still assumes that there are at most 4 cells around every edge, and that distances from + the origin are known, so it works only in {5,3,4}. + */ + +int celldistance_534(cell *c1, cell *c2) { + int d1 = celldist(c1); + int d2 = celldist(c2); + + vector s1 = {c1}; + vector s2 = {c2}; + int best = 99999999; + int d0 = 0; + + auto go_nearer = [&] (vector& v, int& d) { + vector w; + for(cell *c: v) + forCellEx(c1, c) + if(celldist(c1) < d) + w.push_back(c1); + sort(w.begin(), w.end()); + d--; d0++; + auto last = std::unique(w.begin(), w.end()); + w.erase(last, w.end()); + v = w; + }; + + while(d0 < best) { + for(cell *a1: s1) for(cell *a2: s2) { + if(a1 == a2) best = min(best, d0); + else if(isNeighbor(a1, a2)) best = min(best, d0+1); + } + + if(d1 == 0 && d2 == 0) break; + + if(d1 >= d2) go_nearer(s1, d1); + if(d1 < d2) go_nearer(s2, d2); + } + + return best; + } + + EX 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; + + if(geometry == gSpace534) return celldistance_534(c1, c2); auto r = regmap();