simplified and generalized cdata

This commit is contained in:
Zeno Rogue 2019-07-21 22:56:10 +02:00
parent a5dc6d40e6
commit d1fb9f3564
8 changed files with 92 additions and 66 deletions

View File

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

View File

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

133
cell.cpp
View File

@ -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;
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(h == currentmap->gamestart()->master) {
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;
cdata mydata = *getHeptagonCdata(h->cmove(dir));
for(int di=3; di<5; di++) {
heptspin hs(h, di, false);
int signum = +1;
while(true) {
heptspin hstab[15];
hstab[7] = hs;
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;

View File

@ -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",

View File

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

View File

@ -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 {

View File

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

View File

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