1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-19 19:54:47 +00:00

3d:: reg3:: distances and alt-distances

This commit is contained in:
Zeno Rogue 2019-03-09 01:00:46 +01:00
parent 6d72bd820b
commit 497f7f6c0f
5 changed files with 88 additions and 15 deletions

View File

@ -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<cell *> cx(rad+1);
for(int i=0; i<rad; i++) {
cx[i] = bf.at;
@ -230,6 +231,7 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) {
alt->alt = 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);

View File

@ -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);

View File

@ -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<hyperpoint> cellshape;
int celldistance(cell *c1, cell *c2);
bool pseudohept(cell *c);
inline short& altdist(heptagon *h) { return h->emeraldval; }
}
#endif

View File

@ -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);

View File

@ -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<heptagon*> 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; i<isize(to_fix); i++) {
h = to_fix[i];
for(int j=0; j<S7; j++) fix_pair(h, h->move(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<heptagon> (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<eGeometry> g(geometry, gBinary3);
// delete binary_map;
}
clearfrom(origin);
}
void generateAlts(heptagon* h) {
map<heptagon*, int> 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; i<S7; i++) {
auto h2 = h->cmove(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