From 98825cf7b4441c9a5d2e9c5be93776edb833dad8 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Mon, 30 Oct 2017 12:05:36 +0100 Subject: [PATCH] reworked the geometry experiment menu --- classes.cpp | 26 ++-- hyper.h | 2 + hyperpoint.cpp | 3 +- menus.cpp | 356 +++++++++++++++++++++++++------------------------ 4 files changed, 201 insertions(+), 186 deletions(-) diff --git a/classes.cpp b/classes.cpp index 9c240cb0..920022d1 100644 --- a/classes.cpp +++ b/classes.cpp @@ -1712,18 +1712,18 @@ eLand randlands[RANDLANDS] = { }; geometryinfo ginf[gGUARD] = { - {"hyperbolic", "hyper", 7, 3, 0, 0, {7, 5}}, - {"Euclidean", "euclid", 6, 3, 0, 1, {7, FORBIDDEN}}, - {"spherical", "sphere", 5, 3, 0, 2, {SEE_ALL, SEE_ALL}}, - {"elliptic", "elliptic", 5, 3, qELLIP, 2, {SEE_ALL, SEE_ALL}}, - {"Zebra quotient", "Zebra", 7, 3, qZEBRA, 0, {7, 5}}, - {"field quotient", "field", 7, 3, qFIELD, 0, {7, 5}}, - {"torus", "torus", 6, 3, qTORUS, 1, {7, FORBIDDEN}}, - {"octagons", "oct", 8, 3, 0, 0, {6, 4}}, - {"four pentagons", "4x5", 5, 4, 0, 0, {6, 4}}, - {"four hexagons", "4x6", 6, 4, 0, 0, {5, 3}}, - {"four heptagons", "4x7", 7, 4, 0, 0, {4, 3}}, - {"small sphere", "3x4", 4, 3, 0, 2, {SEE_ALL, SEE_ALL}}, - {"tiny sphere", "3x3", 3, 3, 0, 2, {SEE_ALL, SEE_ALL}}, + {"standard", "HR", 7, 3, 0, 0, {7, 5}}, + {"Euclidean", "euclid", 6, 3, 0, 1, {7, FORBIDDEN}}, + {"spherical", "sphere", 5, 3, 0, 2, {SEE_ALL, SEE_ALL}}, + {"elliptic", "elliptic", 5, 3, qELLIP, 2, {SEE_ALL, SEE_ALL}}, + {"Zebra quotient", "Zebra", 7, 3, qZEBRA, 0, {7, 5}}, + {"field quotient", "field", 7, 3, qFIELD, 0, {7, 5}}, + {"torus", "torus", 6, 3, qTORUS, 1, {7, FORBIDDEN}}, + {"octagons", "oct", 8, 3, 0, 0, {6, 4}}, + {"four pentagons", "4x5", 5, 4, 0, 0, {6, 4}}, + {"four hexagons", "4x6", 6, 4, 0, 0, {5, 3}}, + {"four heptagons", "4x7", 7, 4, 0, 0, {4, 3}}, + {"cube", "3x4", 4, 3, 0, 2, {SEE_ALL, SEE_ALL}}, + {"tetrahedron (buggy)", "3x3", 3, 3, 0, 2, {SEE_ALL, SEE_ALL}}, }; diff --git a/hyper.h b/hyper.h index 65fe1d05..88f16527 100644 --- a/hyper.h +++ b/hyper.h @@ -2094,3 +2094,5 @@ const char *dnameof(eMonster m); const char *dnameof(eLand l); const char *dnameof(eWall w); const char *dnameof(eItem i); + +void runGeometryExperiments(); diff --git a/hyperpoint.cpp b/hyperpoint.cpp index 28fd9102..9b427211 100644 --- a/hyperpoint.cpp +++ b/hyperpoint.cpp @@ -1,8 +1,7 @@ // Hyperbolic Rogue // Copyright (C) 2011-2012 Zeno Rogue, see 'hyper.cpp' for details -eGeometry geometry, targetgeometry = gEuclid; -extern bool targettrunc; +eGeometry geometry, targetgeometry; // for the pure heptagonal grid bool purehepta = false; diff --git a/menus.cpp b/menus.cpp index a416d135..b43d2269 100644 --- a/menus.cpp +++ b/menus.cpp @@ -433,7 +433,6 @@ void showChangeMode() { mouseovers = XLAT("One wrong move and it is game over!"); multi::cpid = 0; - dialog::addBoolItem(XLAT("heptagonal mode"), (purehepta), '7'); dialog::addBoolItem(XLAT("Chaos mode"), (chaosmode), 'C'); dialog::addBoolItem(XLAT("peaceful mode"), peace::on, 'p'); dialog::addBoolItem(XLAT("Orb Strategy mode"), (inv::on), 'i'); @@ -480,10 +479,8 @@ void showChangeMode() { } } - else if(xuni == 'e') { - targettrunc = purehepta; - pushScreen(showEuclideanMenu); - } + else if(xuni == 'e') + runGeometryExperiments(); else if(xuni == 't') { clearMessages(); pushScreen(tactic::showMenu); @@ -494,8 +491,6 @@ void showChangeMode() { pushScreen(yendor::showMenu); else gotoHelp(yendor::chelp); } - else if(xuni == '7') - restartGame('7'); else if(xuni == 'p') pushScreen(peace::showMenu); else if(xuni == 'i') { @@ -593,22 +588,14 @@ eLand land_spheuc[LAND_SPHEUC] = { #else -#define tweirdhyperbolic (targetgeometry == gOctagon || targetgeometry == g45 || targetgeometry == g46 || targetgeometry == g47) - -#define LAND_SPHEUC ((tweirdhyperbolic) ? LAND_OCT : (targetgeometry > 1) ? LAND_SPH : LAND_EUC) -#define land_spheuc ((tweirdhyperbolic) ? land_oct : (targetgeometry > 1) ? land_sph : land_euc) +#define LAND_SPHEUC ((weirdhyperbolic) ? LAND_OCT : (geometry > 1) ? LAND_SPH : LAND_EUC) +#define land_spheuc ((weirdhyperbolic) ? land_oct : (geometry > 1) ? land_sph : land_euc) #endif const char *curvenames[8] = { "0", "1", "2", "extremely hyperbolic", "strongly hyperbolic", "strongly hyperbolic", "moderately hyperbolic", "weakly hyperbolic" }; -void useHyperrogueGeometry() { - targetgeometry = geometry; - restartGame('g'); - if(targettrunc != purehepta) restartGame('7'); - } - string euchelp = "If you want to know how much the gameplay is affected by the " "hyperbolic geometry in HyperRogue, this mode is for you!\n\n" @@ -621,102 +608,24 @@ string euchelp = "with quotient geometries. For example, the elliptic geometry is " "obtained from the sphere by making the antipodes be the same point, " "so you return to the same spot (but as a mirror image) after going there. " - "Halloween is a land specially designed for the 'sphere' geometry; " - "several more tilings can be played on by playing Graveyard or Warped Coast " - "in a truncated tiling. " - "Have fun experimenting! Not all graphics and lands are implemented in " - "all geometries, but lots of them are."; + "Have fun experimenting! " + "Achievements and leaderboards do not work in geometry experiments, " + "except some specific ones.\n\n" + "In standard geometry (truncated or not), you can play the full game, but in other geometries " + "you select a particular land. Lands are unlocked by visiting them in this " + "game, or permanently by collecting 25 treasure. Try Crossroads in Euclidean " + "or chaos mode in non-standard non-quotient hyperbolic to visit many lands. " + "Highlights:\n" + "* Crystal World and Warped Coast can be understood as extra geometries.\n" + "* Halloween is specially designed for spherical geometry.\n" + "* To see the difference, try Hunting Grounds in Euclidean -- it is impossible.\n"; -void showPickGeometry() { - int ts = ginf[targetgeometry].sides; - int tv = ginf[targetgeometry].vertex; - int tq = ginf[targetgeometry].quotientstyle; - int nom = (targettrunc ? tv : tv+ts) * ((tq & qELLIP) ? 2 : 4); - int denom = (2*ts + 2*tv - ts * tv); - - gamescreen(4); - dialog::init(XLAT("select the geometry")); - for(int i=0; i 0 ? "finite (%1)" : - "exponentially infinite (%1)", its(worldsize)), - 0); - - switch(ginf[targetgeometry].cclass) { - case 0: - dialog::addSelItem("curvature", curvenames[ginf[targetgeometry].distlimit[targettrunc]], 0); - break; - - case 1: - dialog::addSelItem("curvature", "flat", 0); - break; - - case 2: - dialog::addSelItem("curvature", "spherical", 0); - break; - } - - dialog::addItem(XLAT("help"), SDLK_F1); - dialog::addItem(XLAT("done"), '0'); - dialog::display(); - - keyhandler = [] (int sym, int uni) { - dialog::handleNavigation(sym, uni); - if(uni >= 'a' && uni < 'a'+gGUARD) - targetgeometry = eGeometry(uni - 'a'); - else if(uni == 't') - targettrunc = !targettrunc; - else if(uni == '2' || sym == SDLK_F1) gotoHelp(euchelp); - else if(doexiton(sym, uni)) { - popScreen(); - if(targetgeometry == gEuclid) targettrunc = false; - if(targetgeometry == gNormal) popScreen(), useHyperrogueGeometry(); - } - }; - } - -bool targettrunc; +int ewhichscreen = 2; void showEuclideanMenu() { - gamescreen(4); + cmode = sm::SIDE; + gamescreen(0); int s = vid.fsize; - vid.fsize = vid.fsize * 4/5; - dialog::init(XLAT("experiment with geometry")); if(cheater) for(int i=0; i= 25) landvisited[i] = true; @@ -733,73 +642,179 @@ void showEuclideanMenu() { landvisited[laCA] = true; // for(int i=2; i= LAND_SPHEUC) { dialog::addBreak(100); break; } - eLand l = land_spheuc[euperpage * eupage + i]; - if(landvisited[l]) { + if(ts == 6 && tv == 3) + dialog::addSelItem("truncated", "does not matter", 't'); + else + dialog::addBoolItem("truncated", !purehepta, 't'); + + dialog::addBreak(50); + + int worldsize = denom ? nom/denom : 0; + if(tq & qTORUS) worldsize = torusconfig::qty; + if(tq & qZEBRA) worldsize = purehepta ? 12 : 40; + if(tq & qFIELD) { + worldsize = size(currfp.matrices) / ts; + if(!purehepta) worldsize = ((ts+tv)*worldsize) / tv; + } + + dialog::addSelItem("sides per face", its(ts), 0); + dialog::addSelItem("faces per vertex", its(tv), 0); + + string qstring = "none"; + if(tq & qZEBRA) qstring = "zebra"; + + else if(tq & qFIELD) qstring = "field"; + + else if(tq & qELLIP) qstring = "torus"; + + else if(tq & qTORUS) qstring = "torus"; + + dialog::addSelItem("quotient space", qstring, 0); + + dialog::addSelItem("size of the world", + XLAT( + worldsize == 0 ? "infinite" : + worldsize > 0 ? "finite (%1)" : + "exponentially infinite (%1)", its(worldsize)), + 0); + + switch(ginf[geometry].cclass) { + case 0: + dialog::addSelItem("curvature", curvenames[getDistLimit()], 0); + break; + + case 1: + dialog::addSelItem("curvature", "flat", 0); + break; + + case 2: + dialog::addSelItem("curvature", "spherical", 0); + break; + } + + if(sphere) + dialog::addBoolItem(XLAT("stereographic/orthogonal"), vid.alpha>10, '1'); + else + dialog::addBoolItem(XLAT("Poincaré/Klein"), vid.alpha>.5, '1'); + dialog::addItem(XLAT("help"), SDLK_F1); + dialog::addItem(XLAT("done"), '0'); + dialog::display(); + + keyhandler = [] (int sym, int uni) { + dialog::handleNavigation(sym, uni); + if(uni >= 'a' && uni < 'a'+gGUARD) { + targetgeometry = eGeometry(uni - 'a'); + restartGame(geometry == targetgeometry ? 0 : 'g'); + pushScreen(showEuclideanMenu); + } + else if(uni == 't') { + if(!euclid) { + restartGame('7'); + pushScreen(showEuclideanMenu); + } + } + else if(uni == '2' || sym == SDLK_F1) gotoHelp(euchelp); + else if(uni == '1' && !euclid) { + if(sphere) { + if(vid.alpha < 10) { vid.alpha = 999; vid.scale = 998; } + else {vid.alpha = 1; vid.scale = .4; } + } + else { + if(vid.alpha > .5) { vid.alpha = 0; vid.scale = 1; } + else {vid.alpha = 1; vid.scale = 1; } + } + } + else if(uni == '5') + ewhichscreen ^= 3; + else if(doexiton(sym, uni)) + popScreen(); + }; + } + else { + dialog::init(XLAT("use this where?")); + string truncatenames[2] = {" (t)", " (n)"}; + + dialog::addSelItem(XLAT("geometry"), XLAT(ginf[geometry].name) + truncatenames[purehepta], '5'); + dialog::addBreak(50); + + for(int i=0; i= LAND_SPHEUC) { dialog::addBreak(100); break; } + eLand l = land_spheuc[euperpage * eupage + i]; char ch; if(i < 26) ch = 'a' + i; else ch = 'A' + (i-26); - dialog::addBoolItem(XLAT1(linf[l].name), l == current, ch); - } - else dialog::addBreak(100); - } - dialog::addBreak(50); - dialog::addItem(XLAT("Return to the hyperbolic world"), '0'); - dialog::addItem(XLAT("next page"), '-'); - - dialog::addBreak(100); - dialog::addHelp( - XLAT("Choose from the lands visited this game.") + " " + - XLAT("Scores and achievements are not") + " " + XLAT("saved in the Euclidean mode!") - ); - - dialog::display(); - - vid.fsize = s; - keyhandler = [] (int sym, int uni) { - dialog::handleNavigation(sym, uni); - int lid; - if(uni >= 'a' && uni <= 'z') lid = uni - 'a'; - else if(uni >= 'A' && uni <= 'Z') lid = 26 + uni - 'A'; - else lid = -1; - - if(lid >= 0) lid += euperpage * eupage; - - if(uni == '0') - useHyperrogueGeometry(); - else if(uni == '5') { - pushScreen(showPickGeometry); - } - else if(uni == '-' || uni == PSEUDOKEY_WHEELUP || uni == PSEUDOKEY_WHEELDOWN) { - eupage++; - if(eupage * euperpage >= LAND_SPHEUC) eupage = 0; - } - else if(lid >= 0 && lid < LAND_SPHEUC) { - specialland = land_spheuc[lid]; - if(landvisited[specialland] && specialland != laOceanWall) { - if(targetgeometry != geometry) - restartGame('g'); - else - restartGame(tactic::on ? 't' : 0); - // switch the truncated if necessary - if(targettrunc != purehepta) - restartGame('7'); - // disable PTM if chosen a land from the Euclidean menu - if(tactic::on) restartGame('t'); + if(landvisited[l]) { + dialog::addBoolItem(XLAT1(linf[l].name), l == specialland, ch); + } + else { + dialog::addSelItem(XLAT1(linf[l].name), XLAT("(locked)"), ch); } - else specialland = laIce; } - else if(uni == '2' || sym == SDLK_F1) gotoHelp(euchelp); - else if(doexiton(sym, uni)) popScreen(); - }; + dialog::addBreak(50); + if(chaosUnlocked && !quotient && !euclid && !sphere) + dialog::addItem(XLAT("Chaos mode"), '1'); + dialog::addItem(XLAT("next page"), '-'); + + dialog::addItem(XLAT("help"), SDLK_F1); + dialog::addItem(XLAT("done"), '0'); + dialog::display(); + + vid.fsize = s; + keyhandler = [] (int sym, int uni) { + dialog::handleNavigation(sym, uni); + int lid; + if(uni >= 'a' && uni <= 'z') lid = uni - 'a'; + else if(uni >= 'A' && uni <= 'Z') lid = 26 + uni - 'A'; + else lid = -1; + + if(lid >= 0) lid += euperpage * eupage; + + if(uni == '5') + ewhichscreen ^= 3; + else if(uni == '-' || uni == PSEUDOKEY_WHEELUP || uni == PSEUDOKEY_WHEELDOWN) { + eupage++; + if(eupage * euperpage >= LAND_SPHEUC) eupage = 0; + } + else if(uni == '1') { + if(chaosUnlocked) { + restartGame('C'); + pushScreen(showEuclideanMenu); + } + } + else if(lid >= 0 && lid < LAND_SPHEUC) { + eLand nland = land_spheuc[lid]; + if(landvisited[nland]) { + specialland = nland; + restartGame(tactic::on ? 't' : 0); + pushScreen(showEuclideanMenu); + } + } + else if(uni == '2' || sym == SDLK_F1) gotoHelp(euchelp); + else if(doexiton(sym, uni)) popScreen(); + }; + } + + } + +void runGeometryExperiments() { + specialland = cwt.c->land; + pushScreen(showEuclideanMenu); } bool showstartmenu; @@ -946,8 +961,7 @@ void setAppropriateOverview() { else if(peace::on) pushScreen(peace::showMenu); else if(geometry != gNormal) { - targettrunc = purehepta; - pushScreen(showEuclideanMenu); + runGeometryExperiments(); } else { mapeditor::infix = "";