diff --git a/archimedean.cpp b/archimedean.cpp index 1d2fd4e3..905c74a7 100644 --- a/archimedean.cpp +++ b/archimedean.cpp @@ -243,6 +243,7 @@ eGeometryClass archimedean_tiling::get_class() { void archimedean_tiling::compute_geometry() { ginf[gArchimedean].cclass = get_class(); + set_flag(ginf[gArchimedean].flags, qBOUNDED, get_class() == gcSphere); SDEBUG( printf("euclidean_angle_sum = %f\n", float(euclidean_angle_sum)); ) diff --git a/cell.cpp b/cell.cpp index bae931ca..3924641c 100644 --- a/cell.cpp +++ b/cell.cpp @@ -346,14 +346,11 @@ namespace torusconfig { ginf[gTorus].vertex = 3, ginf[gTorus].sides = 6; else ginf[gTorus].vertex = 4, ginf[gTorus].sides = 4; - if(tmflags() & TF_KLEIN) - ginf[gTorus].quotientstyle |= qNONOR; - else - ginf[gTorus].quotientstyle &= ~qNONOR; - if(tmflags() & TF_CYL) - ginf[gTorus].quotientstyle &= ~qFULLTORUS; - else - ginf[gTorus].quotientstyle |= qFULLTORUS; + + flagtype& flags = ginf[gTorus].flags; + + set_flag(flags, qNONORIENTABLE, tmflags() & TF_KLEIN); + set_flag(flags, qBOUNDED, !(tmflags() & TF_CYL)); } int dscalar(gp::loc e1, gp::loc e2) { @@ -1738,7 +1735,7 @@ int celldistance(cell *c1, cell *c2) { if(geometry == gFieldQuotient && !GOLDBERG) return currfp.getdist(fieldpattern::fieldval(c1), fieldpattern::fieldval(c2)); - if(sphere || quotient || fulltorus) { + if(bounded) { if(saved_distances.count(make_pair(c1,c2))) return saved_distances[make_pair(c1,c2)]; @@ -1753,7 +1750,7 @@ int celldistance(cell *c1, cell *c2) { return 64; } - if(masterless || archimedean) { + if(masterless || archimedean || quotient) { if(saved_distances.count(make_pair(c1,c2))) return saved_distances[make_pair(c1,c2)]; diff --git a/classes.cpp b/classes.cpp index f686fdda..a5861ebd 100644 --- a/classes.cpp +++ b/classes.cpp @@ -1658,34 +1658,41 @@ vector randlands = { laOvergrown, laWildWest, laWarpCoast, laRuins, laBull, laDragon, laReptile, laDocks }; -static const int qNONOR = qNONORIENTABLE; +static const flagtype qsNONOR = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE; +static const flagtype qsBQ = qANYQ | qSMALL | qBOUNDED; +static const flagtype qsSMALL = qANYQ | qSMALL | qBOUNDED; +static const flagtype qsSMALLN = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE; +static const flagtype qsZEBRA = qANYQ | qSMALL | qBOUNDED | qZEBRA; +static const flagtype qsFIELD = qANYQ | qFIELD | qBOUNDED; +static const flagtype qsDOCKS = qANYQ | qSMALL | qBOUNDED | qDOCKS; +static const flagtype qsSMALLB = qSMALL | qBOUNDED; vector ginf = { - {"standard", "HR", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::bitruncated}, - {"Euclidean", "euclid", 6, 3, 0, gcEuclid, 0, {{7, FORBIDDEN}}, eVariation::bitruncated}, - {"spherical", "sphere", 5, 3, 0, gcSphere, 0, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, - {"elliptic", "elliptic", 5, 3, qNONOR, gcSphere, 0, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, - {"Zebra quotient", "Zebra", 7, 3, qSMALL | qZEBRA, gcHyperbolic, 0x00400, {{7, 5}}, eVariation::bitruncated}, - {"field quotient", "field", 7, 3, qFIELD, gcHyperbolic, 0x00200, {{7, 5}}, eVariation::bitruncated}, - {"torus/Klein bottle", "torus", 6, 3, qEUWRAP | qFULLTORUS, gcEuclid, 0x00600, {{7, 7}}, eVariation::bitruncated}, - {"octagons", "oct", 8, 3, 0, gcHyperbolic, 0x08000, {{6, 4}}, eVariation::bitruncated}, - {"four pentagons", "4x5", 5, 4, 0, gcHyperbolic, 0x08200, {{6, 4}}, eVariation::bitruncated}, - {"four hexagons", "4x6", 6, 4, 0, gcHyperbolic, 0x08400, {{5, 3}}, eVariation::bitruncated}, - {"four heptagons", "4x7", 7, 4, 0, gcHyperbolic, 0x08600, {{4, 3}}, eVariation::bitruncated}, - {"cube", "3x4", 4, 3, 0, gcSphere, 0x10000, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, - {"tetrahedron", "3x3", 3, 3, 0, gcSphere, 0x10200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, - {"square grid", "4x4", 4, 4, 0, gcEuclid, 0x10400, {{7, 7}}, eVariation::bitruncated}, - {"cube/elliptic", "e3x4", 4, 3, qNONOR, gcSphere, 0x10600, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, - {"Klein Quartic", "Klein", 7, 3, qSMALL, gcHyperbolic, 0x18000, {{7, 5}}, eVariation::bitruncated}, - {"Bolza Surface", "Bolza", 8, 3, qSMALL | qDOCKS, gcHyperbolic, 0x18200, {{6, 4}}, eVariation::bitruncated}, - {"Bolza Surface x2", "Bolza2", 8, 3, qSMALL | qDOCKS, gcHyperbolic, 0x18400, {{6, 4}}, eVariation::bitruncated}, - {"minimal quotient", "minimal", 7, 3, qSMALL | qNONOR, gcHyperbolic, 0x18600, {{7, 5}}, eVariation::bitruncated}, - {"binary tiling", "binary", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::pure}, - {"Archimedean", "A", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::pure}, - {"Macbeath surface", "Macbeath", 7, 3, qSMALL, gcHyperbolic, 0x20000, {{7, 5}}, eVariation::bitruncated}, - {"Bring's Surface", "Bring", 5, 4, qSMALL, gcHyperbolic, 0x20200, {{6, 4}}, eVariation::bitruncated}, - {"Schmutz's M(3)", "M3", 12, 3, qSMALL, gcHyperbolic, 0x20400, {{4, 2}}, eVariation::bitruncated}, - {"Schmutz's M(4)", "M4", 12, 3, qSMALL, gcHyperbolic, 0x20600, {{4, 2}}, eVariation::bitruncated}, + {"standard", "HR", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::bitruncated}, + {"Euclidean", "euclid", 6, 3, 0, gcEuclid, 0, {{7, FORBIDDEN}}, eVariation::bitruncated}, + {"spherical", "sphere", 5, 3, qsSMALLB, gcSphere, 0, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, + {"elliptic", "elliptic", 5, 3, qsNONOR, gcSphere, 0, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, + {"Zebra quotient", "Zebra", 7, 3, qsZEBRA, gcHyperbolic, 0x00400, {{7, 5}}, eVariation::bitruncated}, + {"field quotient", "field", 7, 3, qsFIELD, gcHyperbolic, 0x00200, {{7, 5}}, eVariation::bitruncated}, + {"torus/Klein bottle", "torus", 6, 3, qsBQ, gcEuclid, 0x00600, {{7, 7}}, eVariation::bitruncated}, + {"octagons", "oct", 8, 3, 0, gcHyperbolic, 0x08000, {{6, 4}}, eVariation::bitruncated}, + {"four pentagons", "4x5", 5, 4, 0, gcHyperbolic, 0x08200, {{6, 4}}, eVariation::bitruncated}, + {"four hexagons", "4x6", 6, 4, 0, gcHyperbolic, 0x08400, {{5, 3}}, eVariation::bitruncated}, + {"four heptagons", "4x7", 7, 4, 0, gcHyperbolic, 0x08600, {{4, 3}}, eVariation::bitruncated}, + {"cube", "3x4", 4, 3, qsSMALLB, gcSphere, 0x10000, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, + {"tetrahedron", "3x3", 3, 3, qsSMALLB, gcSphere, 0x10200, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, + {"square grid", "4x4", 4, 4, 0, gcEuclid, 0x10400, {{7, 7}}, eVariation::bitruncated}, + {"cube/elliptic", "e3x4", 4, 3, qsNONOR, gcSphere, 0x10600, {{SEE_ALL, SEE_ALL}}, eVariation::bitruncated}, + {"Klein Quartic", "Klein", 7, 3, qsSMALL, gcHyperbolic, 0x18000, {{7, 5}}, eVariation::bitruncated}, + {"Bolza Surface", "Bolza", 8, 3, qsDOCKS, gcHyperbolic, 0x18200, {{6, 4}}, eVariation::bitruncated}, + {"Bolza Surface x2", "Bolza2", 8, 3, qsDOCKS, gcHyperbolic, 0x18400, {{6, 4}}, eVariation::bitruncated}, + {"minimal quotient", "minimal", 7, 3, qsSMALLN, gcHyperbolic, 0x18600, {{7, 5}}, eVariation::bitruncated}, + {"binary tiling", "binary", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::pure}, + {"Archimedean", "A", 7, 3, 0, gcHyperbolic, 0, {{7, 5}}, eVariation::pure}, + {"Macbeath surface", "Macbeath", 7, 3, qsSMALL, gcHyperbolic, 0x20000, {{7, 5}}, eVariation::bitruncated}, + {"Bring's Surface", "Bring", 5, 4, qsSMALL, gcHyperbolic, 0x20200, {{6, 4}}, eVariation::bitruncated}, + {"Schmutz's M(3)", "M3", 12, 3, qsSMALL, gcHyperbolic, 0x20400, {{4, 2}}, eVariation::bitruncated}, + {"Schmutz's M(4)", "M4", 12, 3, qsSMALL, gcHyperbolic, 0x20600, {{4, 2}}, eVariation::bitruncated}, }; // remember to match the following mask when specifying codes for extra geometries: 0x78600 diff --git a/classes.h b/classes.h index c7074d7e..a960f634 100644 --- a/classes.h +++ b/classes.h @@ -2,6 +2,14 @@ namespace hr { typedef unsigned color_t; +typedef unsigned long long flagtype; +#define Flag(i) (flagtype(1ull< distlimit; // bitrunc, non-bitrunc eVariation default_variation; }; -static const int qSMALL = 1; -static const int qFIELD = 2; -static const int qNONORIENTABLE = 4; -static const int qEUWRAP = 8; -static const int qDOCKS = 16; -static const int qZEBRA = 32; -static const int qFULLTORUS = 64; +static const flagtype qBOUNDED = 1; +static const flagtype qANYQ = 2; +static const flagtype qNONORIENTABLE = 4; +static const flagtype qSMALL = 8; + +static const flagtype qFIELD = 16; +static const flagtype qDOCKS = 32; +static const flagtype qZEBRA = 64; // note: dnext assumes that x&7 equals 7 static const int SEE_ALL = 50; diff --git a/geom-exp.cpp b/geom-exp.cpp index 5637f178..4682f1a4 100644 --- a/geom-exp.cpp +++ b/geom-exp.cpp @@ -306,7 +306,7 @@ void showEuclideanMenu() { dialog::init(XLAT("experiment with geometry")); int ts = ginf[geometry].sides; int tv = ginf[geometry].vertex; - int tq = ginf[geometry].quotientstyle; + flagtype gf = ginf[geometry].flags; int nom = (BITRUNCATED ? tv+ts : tv) * 4; int denom = (2*ts + 2*tv - ts * tv); @@ -450,20 +450,20 @@ void showEuclideanMenu() { dialog::addSelItem(XLAT("faces per vertex"), spf, 0); string qstring = "none"; - if(tq & qZEBRA) qstring = "zebra"; - - else if(tq & qFIELD) qstring = "field"; - - else if((tq & qNONORIENTABLE) && sphere) qstring = "elliptic"; - - else if(tq & qFULLTORUS) qstring = "torus"; - else if(tq & qEUWRAP) qstring = "cylinder"; + if(gf & qZEBRA) qstring = "zebra"; + else if(gf & qFIELD) qstring = "field"; + + else if((gf & qNONORIENTABLE) && sphere) qstring = "elliptic"; + + else if(bounded && euclid) qstring = "torus"; + + else if(quotient && euclid) qstring = "cylinder"; - else if(tq & qSMALL) qstring = ginf[geometry].shortname; + else if(smallbounded) qstring = ginf[geometry].shortname; dialog::addSelItem(XLAT("quotient space"), XLAT(qstring), 0); - + if(hyperbolic && IRREGULAR) { nom = isize(irr::cells); // both Klein Quartic and Bolza2 are double the Zebra quotiennt diff --git a/geometry2.cpp b/geometry2.cpp index 5922ac33..a0146c04 100644 --- a/geometry2.cpp +++ b/geometry2.cpp @@ -115,7 +115,7 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hin //transmatrix sol; while(h1 != h2) { - if(quotient & qSMALL) { + if(smallbounded && quotient) { transmatrix T; ld bestdist = 1e9; for(int d=0; dmove(d)) { diff --git a/hyper.h b/hyper.h index 4dcd097a..efebe819 100644 --- a/hyper.h +++ b/hyper.h @@ -97,14 +97,14 @@ void addMessage(string s, char spamtype = 0); #define euclid (cgclass == gcEuclid) #define sphere (cgclass == gcSphere) #define hyperbolic (cgclass == gcHyperbolic) -#define nonorientable (ginf[geometry].quotientstyle & qNONORIENTABLE) +#define nonorientable (ginf[geometry].flags & qNONORIENTABLE) #define elliptic (sphere && nonorientable) -#define quotient (ginf[geometry].quotientstyle & (qSMALL | qFIELD | qDOCKS | qZEBRA)) -#define euwrap (ginf[geometry].quotientstyle & qEUWRAP) -#define fulltorus (ginf[geometry].quotientstyle & qFULLTORUS) -#define doall (ginf[geometry].quotientstyle) -#define smallbounded (sphere || (quotient & qSMALL) || fulltorus) -#define bounded (sphere || quotient || fulltorus) +#define quotient (ginf[geometry].flags & qANYQ) +#define euwrap (quotient && euclid) +#define fulltorus (bounded && euclid) +#define doall (bounded) +#define smallbounded (ginf[geometry].flags & qSMALL) +#define bounded (ginf[geometry].flags & qBOUNDED) #define masterless among(geometry, gEuclid, gEuclidSquare, gTorus) #define sphere_narcm (sphere && !archimedean) @@ -118,8 +118,8 @@ void addMessage(string s, char spamtype = 0); #define a38 (S3 == 3 && S7 == 8) #define sphere4 (sphere && S7 == 4) #define stdeuc (geometry == gNormal || geometry == gEuclid || geometry == gEuclidSquare) -#define smallsphere (S7 < 5) -#define bigsphere (S7 == 5) +#define smallsphere (sphere_narcm && S7 < 5) +#define bigsphere (sphere_narcm && S7 == 5) #define euclid4 (masterless && a4) #define euclid6 (masterless && !a4) @@ -645,8 +645,6 @@ void achievement_pump(); extern vector achievementsReceived; // game forward declarations -typedef unsigned long long flagtype; -#define Flag(i) (flagtype(1ull<= 65) + return hedgehogs; + // laPower and laEmerald and laPalace -> [partial] in quotients and hyperbolic_non37 if((l == laPower || l == laEmerald || l == laPalace || l == laWildWest) && !randomPatternsMode) { if(euclid || bigsphere) ; + else if(old_daily_id <= 65 && a45) ; else if(!hyperbolic_37) return l == laWildWest ? some0 : pattern_not_implemented_random; else if(quotient) return pattern_incompatibility; } @@ -1346,9 +1350,22 @@ land_validity_t& land_validity(eLand l) { if(l == laTrollheim && !stdeuc && !bounded) return some1; - - if(l == laReptile && (a38 || a4 || sphere || !BITRUNCATED || (quotient && geometry != gZebraQuotient))) - return bad_graphics; + + if(l == laReptile) { + if(old_daily_id <= 64) { + if(l == laReptile && (a38 || a4 || sphere || !BITRUNCATED || (quotient && !euwrap && geometry != gZebraQuotient))) + return bad_graphics; + } + else { + bool reptile_good = false; + if(hyperbolic_37 && BITRUNCATED) reptile_good = true; + if(euclid6) reptile_good = true; + if(quotient && geometry != gZebraQuotient && !euwrap) + reptile_good = false; + if(!reptile_good) + return bad_graphics; + } + } if((l == laDragon || l == laReptile) && !stdeuc && !smallbounded && !randomPatternsMode) return no_fractal_landscapes;