From 90ff8c49dc81e3896d62cb9566ef7099e1797810 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Tue, 10 Apr 2018 08:05:35 +0200 Subject: [PATCH] marked land quality in gp, fixed some bugs --- bigstuff.cpp | 4 ++-- complex.cpp | 2 ++ geom-exp.cpp | 2 +- goldberg.cpp | 30 ++++++++++++++++++++---- graph.cpp | 2 +- hyper.h | 3 +++ landlock.cpp | 65 +++++++++++++++++++++++++++++++++++++++++----------- pattern2.cpp | 50 +++++++++++++++++++++++++++++++++++++--- 8 files changed, 132 insertions(+), 26 deletions(-) diff --git a/bigstuff.cpp b/bigstuff.cpp index 212102b5..f8134976 100644 --- a/bigstuff.cpp +++ b/bigstuff.cpp @@ -726,7 +726,7 @@ void setLandSphere(cell *c) { c->land = laElementalWall, c->barleft = laEEarth, c->barright = laEFire; else if(y < 0) c->land = laElementalWall, c->barleft = laEAir, c->barright = laEWater; - if(c->land == laElementalWall && c->type != 6) + if(c->land == laElementalWall && (c->type != 6 || gp::on)) c->wall = getElementalWall(hrand(2) ? c->barleft : c->barright); } if(!torus) @@ -737,7 +737,7 @@ void setLandSphere(cell *c) { else if(x == 0 || (specialland == laCrossroads3 && getHemisphere(c, 2) == 0)) setland(c, laBarrier), c->wall = waBarrier; else setland(c, specialland); - if(specialland == laCrossroads3 && c->type != 6 && c->master->fiftyval == 1) + if(specialland == laCrossroads3 && c->type != 6 && c->master->fiftyval == 1 && !gp::on) c->wall = waBigTree; } if(specialland == laIvoryTower || specialland == laEndorian || specialland == laDungeon || specialland == laOcean || specialland == laMountain) { diff --git a/complex.cpp b/complex.cpp index e4a5fce3..9223a7a7 100644 --- a/complex.cpp +++ b/complex.cpp @@ -805,6 +805,8 @@ namespace clearing { if(sphere) return; + if(gp::on) return; + if(euclid) { if(torus) return; if(pseudohept(c)) return; diff --git a/geom-exp.cpp b/geom-exp.cpp index 48b71499..dff17231 100644 --- a/geom-exp.cpp +++ b/geom-exp.cpp @@ -384,7 +384,7 @@ void showEuclideanMenu() { char ch; if(i < 26) ch = 'a' + i; else ch = 'A' + (i-26); - string validclasses[4] = {"", " (½)", "", " (!)"}; + string validclasses[4] = {" (X)", " (½)", "", " (!)"}; string s = XLAT1(linf[l].name); if(landvisited[l]) { diff --git a/goldberg.cpp b/goldberg.cpp index 707b1221..c4badaee 100644 --- a/goldberg.cpp +++ b/goldberg.cpp @@ -506,19 +506,39 @@ namespace gp { pushScreen([texture_remap] () { gp::show(texture_remap); }); } + void be_in_triangle2(local_info& li) { // hyperpoint atz(const transmatrix& T, const transmatrix& corners, loc at, int cornerid = 6, ld cf = 3) { + int sp = 0; + auto& at = li.relative; + again: + auto corner = corners * loctoh_ort(at); + if(corner[1] < -1e-6 || corner[2] < -1e-6) { + at = at * eudir(1); + sp++; + goto again; + } + if(sp>3) sp -= 6; + li.last_dir = fix7(li.last_dir - sp); + } + + void be_in_triangle(local_info& li) { + int& i = li.last_dir; + auto& at = li.relative; + + while(at.first < 0 || at.second < 0) { + at = at * eudir(1); + i = fix7(i-1); + } + } + int compute_dist(cell *c, int master_function(cell*)) { auto li = get_local_info(c); + be_in_triangle(li); cell *cm = c->master->c7; int i = li.last_dir; auto at = li.relative; - while(at.first < 0 || at.second < 0) { - at = at * eudir(1); - i = fixdir(i-1, cm); - } - auto dmain = master_function(cm); auto d0 = master_function(createStep(cm->master, i)->c7); auto d1 = master_function(createStep(cm->master, fixdir(i+1, cm))->c7); diff --git a/graph.cpp b/graph.cpp index 785317fc..cf7e8a84 100644 --- a/graph.cpp +++ b/graph.cpp @@ -3669,7 +3669,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { string label = its(c->landparam); queuestr(V, 1 * .2, label, 0xFFFFFFFF, 1); } - + if(viewdists) { int cd = celldistance(c, cwt.c); string label = its(cd); diff --git a/hyper.h b/hyper.h index b4b4ef85..a7ed21cf 100644 --- a/hyper.h +++ b/hyper.h @@ -3006,6 +3006,8 @@ namespace gp { local_info get_local_info(cell *c); const char *disp(loc at); + void be_in_triangle2(local_info& li); + int compute_dist(cell *c, int master_function(cell*)); } @@ -3230,3 +3232,4 @@ int geosupport_graveyard(); bool ishex1(cell *c); namespace fieldpattern { int fieldval_uniq(cell *c); int fieldval_uniq_rand(cell *c, int d); } bool warptype(cell *c); +bool horo_ok(); diff --git a/landlock.cpp b/landlock.cpp index 806151eb..e2d2445d 100644 --- a/landlock.cpp +++ b/landlock.cpp @@ -1032,6 +1032,11 @@ int isLandValid(eLand l) { // not good in Field quotient if(quotient == 2) return 0; + if(weirdhyperbolic) + return 0; + // works nice on a big non-tetrahedron-based sphere + if(sphere && S3 != 3 && gp::on) + return 3; } // does not agree with the pattern @@ -1048,8 +1053,12 @@ int isLandValid(eLand l) { if(l == laStorms && nonbitrunc && S3 == 3) return 0; + + // mirrors do not work in gp + if(among(l, laMirror, laMirrorOld) && gp::on) + return 0; - // available only in weird geometries + // available only in non-standard geometries if(l == laMirrorOld && !geometry) return 0; @@ -1066,8 +1075,8 @@ int isLandValid(eLand l) { if((l == laWildWest || l == laDual) && normalgame) return 0; - // Crystal World is designed for bitrunc geometries - if(l == laDual && nonbitrunc) + // Crystal World is designed for nice_dual geometries + if(l == laDual && !has_nice_dual()) return 0; if(l == laHaunted && chaosmode) @@ -1098,9 +1107,9 @@ int isLandValid(eLand l) { // special Euclidean implementations if(euclid && (l == laIvoryTower || l == laMountain || l == laOcean)) return 2; - // in other geometries, it works, but as circles, not equidistants + // in other geometries, it works if(geometry) - return 1; + return 2; } // equidistant-based lands, but also implemented in Euclidean @@ -1116,7 +1125,7 @@ int isLandValid(eLand l) { // works correctly only in some geometries if(l == laClearing) - if(chaosmode || !(stdeuc || a38 || (a45 && !nonbitrunc) || (a47 && !nonbitrunc))) + if(chaosmode || !(stdeuc || a38 || (a45 && !nonbitrunc) || (a47 && !nonbitrunc)) || gp::on) return 0; // does not work in non-bitrunc a4 @@ -1133,6 +1142,9 @@ int isLandValid(eLand l) { if(chaosmode && isCrossroads(l)) return 0; + + if(gp::on && !horo_ok() && isCyclic(l)) + return 0; // Temple and Hive has a special Chaos Mode variant, but they are still essentially unbounded if((l == laTemple || l == laHive) && bounded) @@ -1142,9 +1154,14 @@ int isLandValid(eLand l) { if((l == laBlizzard || l == laVolcano) && elliptic && S7 < 5) return 0; - // Kraken does not really work in odd non-bitrunc geometries - // (but we do have to allow it in Standard) - if(l == laKraken && nonbitrunc && (S7&1)) { + // ... and it works in gp only partially + if((l == laBlizzard || l == laVolcano) && gp::on) + return 1; + + // Kraken does not really work on odd-sided cells; + // a nice football pattern will solve the problem by forbidding the Kraken to go there + // (but we do have to allow it in non-bitrunc standard) + if(l == laKraken && (S7&1) && !has_nice_dual()) { if(!geometry) return 1; return 0; } @@ -1152,11 +1169,18 @@ int isLandValid(eLand l) { // needs standard/Euclidean (needs vineyard pattern) if(l == laWineyard && !stdeuc) return 0; + + // ... fake wineyard pattern + if(l == laWineyard && gp::on) + return 1; // works in most spheres, Zebra quotient, and stdeuc - if(l == laWhirlwind) + if(l == laWhirlwind) { if(!(stdeuc || quotient == 1 || (S7 == 4 && !nonbitrunc) || (bigsphere && nonbitrunc && !elliptic))) return 0; + if(gp::on) + return 1; + } // needs standard/Euclidean (needs fractal landscape) if(l == laTortoise && !stdeuc) @@ -1182,7 +1206,7 @@ int isLandValid(eLand l) { return geosupport_graveyard(); // Warped Coast does not work on non-bitrunc S3s (except standard heptagonal where we have to keep it) - if(l == laWarpCoast && (S3==3) && nonbitrunc) { + if(l == laWarpCoast && (S3==3) && !has_nice_dual()) { if(!geometry) return 1; return 0; } @@ -1191,6 +1215,9 @@ int isLandValid(eLand l) { if((l == laPower || l == laEmerald || l == laPalace) && !stdeuc && !bigsphere) return 1; + if((l == laPower || l == laEmerald || l == laPalace) && gp::on) + return 1; + if(l == laDragon && !stdeuc) return 1; @@ -1212,6 +1239,9 @@ int isLandValid(eLand l) { if(l == laCrossroads3 && !stdeuc && !bigsphere) return 0; + if(among(l, laCrossroads, laCrossroads2, laCrossroads3, laCrossroads5) && gp::on && hyperbolic) + return 0; + // Crossroads IV is great in weird hyperbolic if(l == laCrossroads4 && weirdhyperbolic) return 3; @@ -1223,11 +1253,15 @@ int isLandValid(eLand l) { if(l == laZebra && !(stdeuc || (a4 && nonbitrunc) || a46 || quotient == 1)) return 0; + if(l == laZebra && gp::on) + return 1; + if(l == laCrossroads3 && euclid) return 1; // because it is not accurate if(l == laPrairie) { - if(stdeuc || (bigsphere && !nonbitrunc && !elliptic) || (quotient == 2)) ; + if(gp::on) return 0; + else if(stdeuc || (bigsphere && !nonbitrunc && !elliptic) || (quotient == 2)) ; else if(!bounded) return 1; else return 0; } @@ -1254,8 +1288,11 @@ int isLandValid(eLand l) { if(l == laSnakeNest) return geosupport_threecolor() >= 2 ? 3 : 0; - if(l == laDocks && !randomPatternsMode) - return a38 ? 3 : 0; + if(l == laDocks && !randomPatternsMode) { + if(a38 && !gp::on) return 3; + if(a38) return 1; + return 0; + } if(l == laStorms && torus) return 3; diff --git a/pattern2.cpp b/pattern2.cpp index fc4b1abb..34e06222 100644 --- a/pattern2.cpp +++ b/pattern2.cpp @@ -379,6 +379,34 @@ pair subval(cell *c, int _subpathid = subpathid, int _subpathorder = s int getHemisphere(cell *c, int which) { if(torus) return 0; + if(which == 0 && gp::on && has_nice_dual()) { + set visited; + vector q; + vector type; + auto visit = [&] (cell *c, int t) { + if(visited.count(c)) return; + visited.insert(c); + q.push_back(c); + type.push_back(t); + }; + + cellwalker cw(currentmap->gamestart(), 0); + int ct = 1; + visit(cw.c, ct); + do { + cw = cw + wstep; + visit(cw.c, -ct); + cw = cw + (2*ct) + wstep + ct; + ct = -ct; + } + while(cw.c != currentmap->gamestart()); + for(int i=0; imaster->fiftyval; if(S7 == 5) { @@ -409,9 +437,25 @@ int getHemisphere(cell *c, int which) { } else { int score = 0; - for(int i=0; i<6; i+=2) - score += getHemisphere(c->mov[i], which) * (c->mirror(i) ? -1 : 1); - return score/3; + if(gp::on) { + auto li = gp::get_local_info(c); + gp::be_in_triangle2(li); + auto corner = gp::corners * gp::loctoh_ort(li.relative); + ld scored = + corner[0] * getHemisphere(c->master->c7, which) + + corner[1] * getHemisphere(c->master->move[li.last_dir]->c7, which) + + corner[2] * getHemisphere(c->master->move[fix7(1+li.last_dir)]->c7, which); + int score = int(scored + 10.5) - 10; + ld error = scored - score; + if(score == 0 && error > .001) score++; + if(score == 0 && error < -.001) score--; + return score; + } + else { + for(int i=0; i<6; i+=2) + score += getHemisphere(c->mov[i], which) * (c->mirror(i) ? -1 : 1); + return score/3; + } } }