mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-27 14:37:16 +00:00
simplified and generalized cdata
This commit is contained in:
parent
a5dc6d40e6
commit
d1fb9f3564
@ -364,6 +364,7 @@ void connectHeptagons(heptspin hi, heptspin hs);
|
||||
transmatrix adjcell_matrix(heptagon *h, int d);
|
||||
|
||||
struct hrmap_archimedean : hrmap {
|
||||
map<int, struct cdata> eucdata;
|
||||
heptagon *origin;
|
||||
heptagon *getOrigin() { return origin; }
|
||||
|
||||
@ -441,6 +442,10 @@ struct hrmap_archimedean : hrmap {
|
||||
}
|
||||
|
||||
~hrmap_archimedean() {
|
||||
if(hyperbolic) for(auto& p: archimedean_gmatrix) if(p.second.first->cdata) {
|
||||
delete p.second.first->cdata;
|
||||
p.second.first->cdata = NULL;
|
||||
}
|
||||
clearfrom(origin);
|
||||
altmap.clear();
|
||||
archimedean_gmatrix.clear();
|
||||
|
@ -90,8 +90,9 @@ namespace binary {
|
||||
ld horohex_scale = 0.6;
|
||||
|
||||
heptagon *build(heptagon *parent, int d, int d1, int t, int side, int delta) {
|
||||
auto h = buildHeptagon1(tailored_alloc<heptagon> (t), parent, d, hsOrigin, d1);
|
||||
auto h = buildHeptagon1(tailored_alloc<heptagon> (t), parent, d, hsA, d1);
|
||||
h->distance = parent->distance + delta;
|
||||
h->dm4 = parent->dm4 + delta;
|
||||
h->c7 = NULL;
|
||||
if(parent->c7) h->c7 = newCell(t, h);
|
||||
h->cdata = NULL;
|
||||
|
131
cell.cpp
131
cell.cpp
@ -29,11 +29,6 @@ cell *newCell(int type, heptagon *master) {
|
||||
return c;
|
||||
}
|
||||
|
||||
struct cdata {
|
||||
int val[4];
|
||||
int bits;
|
||||
};
|
||||
|
||||
// -- hrmap ---
|
||||
|
||||
hrmap *currentmap;
|
||||
@ -603,6 +598,10 @@ bool randpatternMajority(cell *c, int ival, int iterations) {
|
||||
|
||||
cdata orig_cdata;
|
||||
|
||||
bool geometry_supports_cdata() {
|
||||
return among(geometry, gEuclid, gEuclidSquare, gNormal, gOctagon, g45, g46, g47, gBinaryTiling) || (archimedean && !sphere);
|
||||
}
|
||||
|
||||
void affect(cdata& d, short rv, signed char signum) {
|
||||
if(rv&1) d.val[0]+=signum; else d.val[0]-=signum;
|
||||
if(rv&2) d.val[1]+=signum; else d.val[1]-=signum;
|
||||
@ -620,12 +619,20 @@ void setHeptagonRval(heptagon *h) {
|
||||
}
|
||||
}
|
||||
|
||||
bool dmeq(int a, int b) { return (a&3) == (b&3); }
|
||||
|
||||
cdata *getHeptagonCdata(heptagon *h) {
|
||||
if(h->cdata) return h->cdata;
|
||||
|
||||
if(sphere || quotient) h = currentmap->gamestart()->master;
|
||||
|
||||
if(h == currentmap->gamestart()->master) {
|
||||
bool starting = h->s == hsOrigin;
|
||||
if(binarytiling) {
|
||||
if(binary::mapside(h) == 0) starting = true;
|
||||
for(int i=0; i<h->type; i++) if(binary::mapside(h->cmove(i)) == 0) starting = true;
|
||||
}
|
||||
|
||||
if(starting) {
|
||||
h->cdata = new cdata(orig_cdata);
|
||||
for(int& v: h->cdata->val) v = 0;
|
||||
h->cdata->bits = reptilecheat ? (1 << 21) - 1 : 0;
|
||||
@ -633,56 +640,32 @@ cdata *getHeptagonCdata(heptagon *h) {
|
||||
return h->cdata;
|
||||
}
|
||||
|
||||
cdata mydata = *getHeptagonCdata(h->move(0));
|
||||
int dir = binarytiling ? 5 : 0;
|
||||
|
||||
for(int di=3; di<5; di++) {
|
||||
heptspin hs(h, di, false);
|
||||
int signum = +1;
|
||||
while(true) {
|
||||
heptspin hstab[15];
|
||||
hstab[7] = hs;
|
||||
cdata mydata = *getHeptagonCdata(h->cmove(dir));
|
||||
|
||||
for(int i=8; i<12; i++) {
|
||||
hstab[i] = hstab[i-1];
|
||||
hstab[i] += ((i&1) ? 4 : 3);
|
||||
hstab[i] += wstep;
|
||||
hstab[i] += ((i&1) ? 3 : 4);
|
||||
}
|
||||
|
||||
for(int i=6; i>=3; i--) {
|
||||
hstab[i] = hstab[i+1];
|
||||
hstab[i] += ((i&1) ? 3 : 4);
|
||||
hstab[i] += wstep;
|
||||
hstab[i] += ((i&1) ? 4 : 3);
|
||||
}
|
||||
|
||||
if(hstab[3].at->distance < hstab[7].at->distance) {
|
||||
hs = hstab[3]; continue;
|
||||
}
|
||||
|
||||
if(hstab[11].at->distance < hstab[7].at->distance) {
|
||||
hs = hstab[11]; continue;
|
||||
}
|
||||
|
||||
int jj = 7;
|
||||
for(int k=3; k<12; k++) if(hstab[k].at->distance < hstab[jj].at->distance) jj = k;
|
||||
|
||||
int ties = 0, tiespos = 0;
|
||||
for(int k=3; k<12; k++) if(hstab[k].at->distance == hstab[jj].at->distance)
|
||||
ties++, tiespos += (k-jj);
|
||||
|
||||
// printf("ties=%d tiespos=%d jj=%d\n", ties, tiespos, jj);
|
||||
if(ties == 2) jj += tiespos/2;
|
||||
|
||||
if(jj&1) signum = -1;
|
||||
hs = hstab[jj];
|
||||
|
||||
break;
|
||||
}
|
||||
hs = hs + 3 + wstep;
|
||||
if(S3 == 4) {
|
||||
heptspin hs(h, 0);
|
||||
while(dmeq((hs+1).cpeek()->dm4, (hs.at->dm4 - 1))) hs = hs + 1 + wstep + 1;
|
||||
while(dmeq((hs-1).cpeek()->dm4, (hs.at->dm4 - 1))) hs = hs - 1 + wstep - 1;
|
||||
setHeptagonRval(hs.at);
|
||||
|
||||
affect(mydata, hs.spin ? hs.at->rval0 : hs.at->rval1, signum);
|
||||
affect(mydata, hs.at->rval0, 1);
|
||||
}
|
||||
else for(int di: {0,1}) {
|
||||
heptspin hs(h, dir, false);
|
||||
hs -= di;
|
||||
while(true) {
|
||||
heptspin hs2 = hs + wstep + 1 + wstep - 1;
|
||||
if(dmeq(hs2.at->dm4, hs.at->dm4 + 1)) break;
|
||||
hs = hs2;
|
||||
}
|
||||
while(true) {
|
||||
heptspin hs2 = hs + 1 + wstep - 1 + wstep;
|
||||
if(dmeq(hs2.at->dm4, hs.at->dm4 + 1)) break;
|
||||
hs = hs2;
|
||||
}
|
||||
setHeptagonRval(hs.at);
|
||||
affect(mydata, hs.spin == dir ? hs.at->rval0 : hs.at->rval1, 1);
|
||||
}
|
||||
|
||||
return h->cdata = new cdata(mydata);
|
||||
@ -696,8 +679,12 @@ cdata *getEuclidCdata(int h) {
|
||||
}
|
||||
|
||||
int x, y;
|
||||
hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap);
|
||||
if(euc->eucdata.count(h)) return &(euc->eucdata[h]);
|
||||
auto& data =
|
||||
archimedean ? ((arcm::hrmap_archimedean*) (currentmap))->eucdata :
|
||||
((hrmap_euclidean*) (currentmap))->eucdata;
|
||||
|
||||
// hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap);
|
||||
if(data.count(h)) return &(data[h]);
|
||||
|
||||
tie(x,y) = vec_to_pair(h);
|
||||
|
||||
@ -705,7 +692,7 @@ cdata *getEuclidCdata(int h) {
|
||||
cdata xx;
|
||||
for(int i=0; i<4; i++) xx.val[i] = 0;
|
||||
xx.bits = 0;
|
||||
return &(euc->eucdata[h] = xx);
|
||||
return &(data[h] = xx);
|
||||
}
|
||||
int ord = 1, bid = 0;
|
||||
while(!((x|y)&ord)) ord <<= 1, bid++;
|
||||
@ -737,16 +724,36 @@ cdata *getEuclidCdata(int h) {
|
||||
if(gbit) xx.bits |= (1<<b);
|
||||
}
|
||||
|
||||
return &(euc->eucdata[h] = xx);
|
||||
return &(data[h] = xx);
|
||||
}
|
||||
|
||||
// impossible!
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ld_to_int(ld x) {
|
||||
return int(x + 1000000.5) - 1000000;
|
||||
}
|
||||
|
||||
int pseudocoords(cell *c) {
|
||||
transmatrix T = arcm::archimedean_gmatrix[c->master].second;
|
||||
return pair_to_vec(ld_to_int(T[0][GDIM]), ld_to_int((spin(60*degree) * T)[0][GDIM]));
|
||||
}
|
||||
|
||||
cdata *arcmCdata(cell *c) {
|
||||
heptagon *h2 = arcm::archimedean_gmatrix[c->master].first;
|
||||
dynamicval<eGeometry> g(geometry, gNormal);
|
||||
dynamicval<hrmap*> cm(currentmap, arcm::current_altmap);
|
||||
return getHeptagonCdata(h2);
|
||||
}
|
||||
|
||||
int getCdata(cell *c, int j) {
|
||||
if(masterless) return getEuclidCdata(decodeId(c->master))->val[j];
|
||||
else if(geometry) return 0;
|
||||
else if(archimedean && euclid)
|
||||
return getEuclidCdata(pseudocoords(c))->val[j];
|
||||
else if(archimedean && hyperbolic)
|
||||
return arcmCdata(c)->val[j]*3;
|
||||
else if(!geometry_supports_cdata()) return 0;
|
||||
else if(ctof(c)) return getHeptagonCdata(c->master)->val[j]*3;
|
||||
else {
|
||||
int jj = 0;
|
||||
@ -759,8 +766,12 @@ int getCdata(cell *c, int j) {
|
||||
|
||||
int getBits(cell *c) {
|
||||
if(masterless) return getEuclidCdata(decodeId(c->master))->bits;
|
||||
else if(geometry) return 0;
|
||||
else if(c->type != 6) return getHeptagonCdata(c->master)->bits;
|
||||
else if(archimedean && euclid)
|
||||
return getEuclidCdata(pseudocoords(c))->bits;
|
||||
else if(archimedean && hyperbolic)
|
||||
return arcmCdata(c)->bits;
|
||||
else if(!geometry_supports_cdata()) return 0;
|
||||
else if(c == c->master->c7) return getHeptagonCdata(c->master)->bits;
|
||||
else {
|
||||
auto ar = gp::get_masters(c);
|
||||
int b0 = getHeptagonCdata(ar[0])->bits;
|
||||
|
@ -352,6 +352,8 @@ struct debugScreen {
|
||||
"Extra value that is important in some lands. The specific meaning depends on the land."); });
|
||||
dialog::addSelItem("land param (hex)", itsh8(what->landparam), 0);
|
||||
dialog::addSelItem("land param (heat)", fts(HEAT(what)), 't');
|
||||
dialog::addSelItem("cdata",
|
||||
its(getCdata(what, 0))+"/"+its(getCdata(what,1))+"/"+its(getCdata(what,2))+"/"+its(getCdata(what,3))+"/"+itsh(getBits(what)), 't');
|
||||
dialog::add_action([what] () {
|
||||
static ld d = HEAT(what);
|
||||
dialog::editNumber(d, -2, 2, 0.1, d, "landparam",
|
||||
|
5
hyper.h
5
hyper.h
@ -685,6 +685,11 @@ enum hstate { hsOrigin, hsA, hsB, hsError, hsA0, hsA1, hsB0, hsB1, hsC };
|
||||
struct cell *createMov(struct cell *c, int d);
|
||||
struct heptagon *createStep(struct heptagon *c, int d);
|
||||
|
||||
struct cdata {
|
||||
int val[4];
|
||||
int bits;
|
||||
};
|
||||
|
||||
// in bitruncated/irregular/Goldberg geometries, heptagons form the
|
||||
// underlying regular tiling (not necessarily heptagonal); in pure
|
||||
// geometries, they correspond 1-1 to tiles; in 'masterless' geometries
|
||||
|
@ -83,7 +83,7 @@ bool blizzard_no_escape(cell *c) {
|
||||
bool out_ruin(cell *c) {
|
||||
if(sphere)
|
||||
return getHemisphere(c, 0) > 0;
|
||||
else if(stdhyperbolic) {
|
||||
else if(geometry_supports_cdata()) {
|
||||
int cd = getCdata(c, 3);
|
||||
cd &= 31;
|
||||
return cd >= 16;
|
||||
@ -686,7 +686,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
else {
|
||||
int i = archimedean ? hrand(50) : zebra40(c);
|
||||
if(i < 40) {
|
||||
int cd = hyperbolic_37 ? getCdata(c, 3) : hrand(16);
|
||||
int cd = geometry_supports_cdata() ? getCdata(c, 3) : hrand(16);
|
||||
cd &= 15;
|
||||
if(cd >= 4 && cd < 12) c->wall = waChasm;
|
||||
else {
|
||||
|
@ -647,6 +647,8 @@ namespace lv {
|
||||
|
||||
int old_daily_id = 1000000;
|
||||
|
||||
const int landscapes_when = 1000;
|
||||
|
||||
// check if the given land should appear in lists
|
||||
land_validity_t& land_validity(eLand l) {
|
||||
|
||||
@ -909,7 +911,7 @@ land_validity_t& land_validity(eLand l) {
|
||||
}
|
||||
|
||||
// needs standard/Euclidean (needs fractal landscape)
|
||||
if(among(l, laTortoise, laVariant) && !stdeuc)
|
||||
if(among(l, laTortoise, laVariant) && !(old_daily_id < landscapes_when ? stdeuc : geometry_supports_cdata()))
|
||||
return not_implemented;
|
||||
|
||||
// technical lands do not count
|
||||
|
@ -1546,7 +1546,7 @@ namespace patterns {
|
||||
dialog::addItem(XLAT("random colors"), 'r');
|
||||
dialog::addItem(XLAT("distance from origin"), 'M');
|
||||
|
||||
if(stdeuc) {
|
||||
if(geometry_supports_cdata()) {
|
||||
dialog::addItem(XLAT("rainbow landscape"), 'l');
|
||||
dialog::addItem(XLAT("dark rainbow landscape"), 'd');
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user