1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-25 01:20:37 +00:00

choose irregular from the Goldberg menu

This commit is contained in:
Zeno Rogue 2018-07-17 02:29:18 +02:00
parent bb0f482511
commit f597e6bfd7
5 changed files with 119 additions and 34 deletions

View File

@ -285,13 +285,9 @@ void showEuclideanMenu() {
dialog::addBreak(50); dialog::addBreak(50);
if(ts == 6 && tv == 3) if(ts == 6 && tv == 3)
dialog::addSelItem(XLAT("Goldberg"), XLAT("does not matter"), 't'); dialog::addSelItem(XLAT("variations"), XLAT("does not matter"), 't');
else if(S3 != 3) {
dialog::addBoolItem(XLAT("Goldberg") + "/" + XLAT("bitruncated"), nonbitrunc, 't');
dialog::lastItem().value = gp::operation_name();
}
else { else {
dialog::addBoolItem(XLAT("Goldberg"), nonbitrunc, 't'); dialog::addBoolItem(XLAT("variations"), nonbitrunc, 't');
dialog::lastItem().value = gp::operation_name(); dialog::lastItem().value = gp::operation_name();
} }

View File

@ -631,7 +631,8 @@ namespace hr { namespace gp {
string operation_name() { string operation_name() {
if(!gp::on) { if(!gp::on) {
if(nonbitrunc) return XLAT("OFF"); if(irr::on) return XLAT("irregular");
else if(nonbitrunc) return XLAT("OFF");
else return XLAT("bitruncated"); else return XLAT("bitruncated");
} }
else if(param == loc(1, 0)) else if(param == loc(1, 0))
@ -664,6 +665,7 @@ namespace hr { namespace gp {
auto g = screens; auto g = screens;
if(xy.first == 0 && xy.second == 0) xy.first = 1; if(xy.first == 0 && xy.second == 0) xy.first = 1;
if(xy.first == 1 && xy.second == 0) { if(xy.first == 1 && xy.second == 0) {
if(irr::on) stop_game_and_switch_mode(rg::bitrunc);
if(gp::on) stop_game_and_switch_mode(rg::bitrunc); if(gp::on) stop_game_and_switch_mode(rg::bitrunc);
if(!nonbitrunc) stop_game_and_switch_mode(rg::bitrunc); if(!nonbitrunc) stop_game_and_switch_mode(rg::bitrunc);
} }
@ -697,13 +699,13 @@ namespace hr { namespace gp {
void show(bool texture_remap) { void show(bool texture_remap) {
cmode = sm::SIDE; cmode = sm::SIDE;
gamescreen(0); gamescreen(0);
dialog::init(XLAT("Goldberg")); dialog::init(XLAT("variations"));
bool show_nonthree = !(texture_remap && (S7&1)); bool show_nonthree = !(texture_remap && (S7&1));
bool show_bitrunc = !(texture_remap && !(S7&1)); bool show_bitrunc = !(texture_remap && !(S7&1));
if(show_nonthree) { if(show_nonthree) {
dialog::addBoolItem(XLAT("OFF"), param == loc(1,0), 'a'); dialog::addBoolItem(XLAT("OFF"), param == loc(1,0) && !irr::on, 'a');
dialog::lastItem().value = "GP(1,0)"; dialog::lastItem().value = "GP(1,0)";
} }
@ -738,7 +740,12 @@ namespace hr { namespace gp {
else if(config == loc(1,1) && !show_bitrunc) else if(config == loc(1,1) && !show_bitrunc)
dialog::addInfo(XLAT("Select bitruncated from the previous menu")); dialog::addInfo(XLAT("Select bitruncated from the previous menu"));
else else
dialog::addBoolItem(XLAT("select"), param == internal_representation(config), 'f'); dialog::addBoolItem(XLAT("select"), param == internal_representation(config) && !irr::on, 'f');
if(!texture_remap && irr::supports(geometry)) {
dialog::addBoolItem(XLAT("irregular"), irr::on, 'i');
dialog::add_action([] () { if(!irr::on) irr::visual_creator(); });
}
dialog::addBreak(100); dialog::addBreak(100);
dialog::addHelp(); dialog::addHelp();

View File

@ -2561,6 +2561,8 @@ namespace irr {
bool pseudohept(cell*); bool pseudohept(cell*);
array<heptagon*, 3> get_masters(cell *c); array<heptagon*, 3> get_masters(cell *c);
bool ctof(cell* c); bool ctof(cell* c);
bool supports(eGeometry g);
void visual_creator();
} }
extern hrmap *currentmap; extern hrmap *currentmap;

View File

@ -2,7 +2,11 @@ namespace hr { namespace irr {
bool on; bool on;
int sc = 100; ld density = 6;
ld quality = .2;
int rearrange_attempts;
int sc;
struct cellinfo { struct cellinfo {
cell *owner; cell *owner;
@ -82,6 +86,8 @@ void make_cells_of_heptagon() {
} }
} }
string status[5];
hrmap *base; hrmap *base;
bool gridmaking; bool gridmaking;
@ -100,6 +106,7 @@ bool step(int delta) {
cells.clear(); cells.clear();
cells_of_heptagon.clear(); cells_of_heptagon.clear();
cellindex.clear();
if(sc <= isize(all) * 2) { if(sc <= isize(all) * 2) {
for(auto h: all) { for(auto h: all) {
@ -114,7 +121,7 @@ bool step(int delta) {
case 1: { case 1: {
while(isize(cells) < sc) { while(isize(cells) < sc) {
if(SDL_GetTicks() > t + 250) { make_cells_of_heptagon(); return false; } if(SDL_GetTicks() > t + 250) { make_cells_of_heptagon(); status[0] = its(isize(cells)) + " cells"; return false; }
cellinfo s; s.patterndir = -1; cellinfo s; s.patterndir = -1;
ld bestval = 0; ld bestval = 0;
for(int j=0; j<10; j++) { for(int j=0; j<10; j++) {
@ -133,6 +140,7 @@ bool step(int delta) {
} }
make_cells_of_heptagon(); make_cells_of_heptagon();
runlevel++; runlevel++;
status[0] = "all " + its(isize(cells)) + " cells";
break; break;
} }
@ -219,21 +227,34 @@ bool step(int delta) {
case 3: { case 3: {
for(int i=0; i<isize(cells); i++) if(isize(cells[i].vertices) > 8 || isize(cells[i].vertices) < 3) { int errors = 0, toobig = 0;
for(int i=0; i<isize(cells); i++) {
int v = isize(cells[i].vertices);
if(v > 8 || v< 3) {
if(v < 3 || v >= 15)
errors++;
else toobig++;
cells[i] = cells.back(); cells[i] = cells.back();
i--; cells.pop_back(); i--; cells.pop_back();
} }
}
if(errors > 0) status[1] = XLAT("bad cells: %1", its(errors)); else status[1] = " ";
if(toobig > 0) status[2] = XLAT("too many edges: %1", its(toobig)); else status[2] = " ";
if(isize(cells) < sc*3/4) runlevel = 0; if(isize(cells) < sc*3/4) runlevel = 0;
else if(isize(cells) < sc) runlevel = 1; else if(isize(cells) < sc) runlevel = 1;
else runlevel++; else { rearrange_attempts = 20; runlevel++; }
break; break;
} }
case 4: { case 4: {
ld minedge = edgelens[isize(edgelens) / 2] / 5; ld median = edgelens[isize(edgelens) / 2];
ld minedge = median * quality;
status[3] = XLAT("median edge: %1 minimum: %2", fts4(median), fts4(edgelens[0]));
if(edgelens[0] < minedge) { if(edgelens[0] < minedge) {
printf("rearranging\n"); int tooshort = 0;
for(int i=0; i<isize(cells); i++) { for(int i=0; i<isize(cells); i++) {
auto& p1 = cells[i]; auto& p1 = cells[i];
using namespace hyperpoint_vec; using namespace hyperpoint_vec;
@ -241,11 +262,15 @@ bool step(int delta) {
for(auto v: p1.vertices) h = h + v; for(auto v: p1.vertices) h = h + v;
for(int j=0; j<isize(p1.vertices); j++) for(int j=0; j<isize(p1.vertices); j++)
if(hdist(p1.vertices[j], p1.vertices[(j+1) % isize(p1.vertices)]) < minedge) if(hdist(p1.vertices[j], p1.vertices[(j+1) % isize(p1.vertices)]) < minedge) {
tooshort++;
h = h + p1.vertices[j] + p1.vertices[(j+1) % isize(p1.vertices)]; h = h + p1.vertices[j] + p1.vertices[(j+1) % isize(p1.vertices)];
}
cells[i].p = p1.pusher * normalize(h); cells[i].p = p1.pusher * normalize(h);
} }
status[3] += XLAT(" (edges too short: %1)", its(tooshort));
runlevel = 2; runlevel = 2;
rearrange_attempts--; if(rearrange_attempts < 0) runlevel = 0;
break; break;
} }
runlevel++; runlevel++;
@ -270,8 +295,7 @@ bool step(int delta) {
} }
} }
printf("notfound = %d\n", notfound); if(notfound) { status[4] = XLAT("cells badly paired: %1", its(notfound)); runlevel = 0; break; }
if(notfound) { runlevel = 0; break; }
int heptas = 0; int heptas = 0;
for(auto p: cells_of_heptagon) { for(auto p: cells_of_heptagon) {
@ -280,18 +304,27 @@ bool step(int delta) {
} }
if(heptas != isize(all)) { if(heptas != isize(all)) {
status[4] = XLAT("cells not covered: %1", its(isize(all) - heptas));
printf("heptas = %d\n", heptas); printf("heptas = %d\n", heptas);
runlevel = 0; break; runlevel = 0; break;
} }
int faredge = 0;
for(int i=0; i<sc; i++) { for(int i=0; i<sc; i++) {
auto &p1 = cells[i]; auto &p1 = cells[i];
for(int j: p1.neid) { for(int j: p1.neid) {
auto &p2 = cells[j]; auto &p2 = cells[j];
bool ok = p1.owner == p2.owner || isNeighbor(p1.owner, p2.owner); bool ok = p1.owner == p2.owner || isNeighbor(p1.owner, p2.owner);
if(!ok) { printf("far edge\n"); runlevel = 0; return false; } if(!ok) faredge++;
} }
} }
if(faredge) {
status[4] = XLAT("adjacent cells from nonadjacent heptagons: %1", its(faredge));
runlevel = 0; return false;
}
status[4] = XLAT("OK");
runlevel = 10; runlevel = 10;
for(auto& s: cells) s.is_pseudohept = false; for(auto& s: cells) s.is_pseudohept = false;
@ -334,6 +367,8 @@ void compute_geometry() {
crossf *= scale; crossf *= scale;
hepvdist *= scale; hepvdist *= scale;
rhexf *= scale; rhexf *= scale;
base_distlimit = (base_distlimit + log(scale) / log(2.618)) / scale;
if(base_distlimit > 25) base_distlimit = 25;
} }
else scale = 1; else scale = 1;
} }
@ -440,31 +475,68 @@ void link_cell(cell *c, int d) {
tsetspin(c2->spintable, sc.spin[d], d); tsetspin(c2->spintable, sc.spin[d], d);
} }
eGeometry orig_geometry;
void show_gridmaker() { void show_gridmaker() {
cmode = sm::SIDE; cmode = sm::SIDE;
gamescreen(0); gamescreen(0);
dialog::init(XLAT("Irregular grid")); dialog::init(XLAT("Irregular grid"));
dialog::addSelItem(XLAT("activate"), its(runlevel), 'f'); dialog::addSelItem(XLAT("density"), fts(density), 'd');
dialog::display(); dialog::add_action([] {
dialog::editNumber(density, 1, 10, .1, 4, "density", "");
dialog::reaction = [] () {
int s = sc;
if(density < 1) density = 1;
sc = int(isize(currentmap->allcells()) * density + .5);
printf("density = %lf sc = %d\n", double(density), sc);
if(sc > s) runlevel = 1;
if(sc < s) runlevel = 0;
};
});
dialog::addSelItem(XLAT("min edge to median"), fts(quality), 'q');
dialog::add_action([] {
dialog::editNumber(quality, 0, 1, .1, 4, "quality", "");
dialog::reaction = [] () {
printf("quality = %lf\n", double(density));
if(runlevel > 4) runlevel = 4;
};
});
dialog::addBreak(100);
for(int i=0; i<5; i++)
dialog::addInfo(status[i]);
dialog::addBreak(100);
dialog::addSelItem(XLAT("activate"), XLAT(runlevel == 10 ? "ready" : "wait..."), 'f');
if(runlevel == 10) dialog::add_action([] { if(runlevel == 10) dialog::add_action([] {
popScreen(); popScreen();
pop_game();
for(hrmap *& hm : allmaps) if(hm == base) hm = NULL; for(hrmap *& hm : allmaps) if(hm == base) hm = NULL;
stop_game(); stop_game();
geometry = orig_geometry;
irr::on = true; irr::on = true;
nonbitrunc = true; nonbitrunc = true;
gp::on = false;
need_reset_geometry = true; need_reset_geometry = true;
gridmaking = false; gridmaking = false;
start_game(); start_game();
}); });
dialog::addItem(XLAT("cancel"), 'c');
dialog::add_action([] {
gridmaking = false;
stop_game();
geometry = orig_geometry;
need_reset_geometry = true;
start_game();
popScreen();
});
dialog::display();
keyhandler = [] (int sym, int uni) { keyhandler = [] (int sym, int uni) {
dialog::handleNavigation(sym, uni); dialog::handleNavigation(sym, uni);
// no exit // no exit
}; };
} }
void create_map() { void visual_creator() {
push_game(); stop_game();
orig_geometry = geometry;
switch(geometry) { switch(geometry) {
case gNormal: case gNormal:
geometry = gKleinQuartic; geometry = gKleinQuartic;
@ -479,10 +551,12 @@ void create_map() {
} }
nonbitrunc = true; nonbitrunc = true;
gp::on = false;
need_reset_geometry = true; need_reset_geometry = true;
start_game(); start_game();
base = currentmap; base = currentmap;
drawthemap(); drawthemap();
sc = int(isize(base->allcells()) * density + .5);
pushScreen(show_gridmaker); pushScreen(show_gridmaker);
runlevel = 0; runlevel = 0;
gridmaking = true; gridmaking = true;
@ -492,11 +566,11 @@ int readArgs() {
using namespace arg; using namespace arg;
if(0) ; if(0) ;
else if(argis("-irr")) { else if(argis("-irrvis")) {
PHASE(3); PHASE(3);
shift(); sc = argi();
restart_game(); restart_game();
create_map(); visual_creator();
showstartmenu = false;
} }
else return 1; else return 1;
return 0; return 0;
@ -510,6 +584,10 @@ bool ctof(cell* c) {
return cells[cellindex[c]].patterndir == -1; return cells[cellindex[c]].patterndir == -1;
} }
bool supports(eGeometry g) {
return among(g, gNormal, gKleinQuartic, gOctagon, gBolza2, gFieldQuotient, gSphere, gSmallSphere, gTinySphere);
}
array<heptagon*, 3> get_masters(cell *c) { array<heptagon*, 3> get_masters(cell *c) {
int d = cells[cellindex[c]].patterndir; int d = cells[cellindex[c]].patterndir;
heptspin s = periodmap[c->master].base; heptspin s = periodmap[c->master].base;

View File

@ -1029,10 +1029,10 @@ namespace gamestack {
bool pushed() { return isize(gd); } bool pushed() { return isize(gd); }
void push() { void push() {
/* if(geometry) { if(geometry) {
printf("ERROR: push implemented only in non-hyperbolic geometry\n"); printf("ERROR: push implemented only in non-hyperbolic geometry\n");
exit(1); exit(1);
} */ }
gamedata gdn; gamedata gdn;
gdn.hmap = currentmap; gdn.hmap = currentmap;
gdn.cwt = cwt; gdn.cwt = cwt;
@ -1148,7 +1148,8 @@ void switch_game_mode(char switchWhat) {
case rg::tour: case rg::tour:
geometry = gNormal; geometry = gNormal;
yendor::on = tactic::on = princess::challenge = peace::on = inv::on = false; yendor::on = tactic::on = princess::challenge = peace::on = inv::on = false;
chaosmode = nonbitrunc = randomPatternsMode = false; chaosmode = nonbitrunc = randomPatternsMode = irr::on = gp::on = false;
gp::param = gp::loc(1, 1);
shmup::on = false; shmup::on = false;
need_reset_geometry = true; need_reset_geometry = true;
tour::on = !tour::on; tour::on = !tour::on;
@ -1158,7 +1159,7 @@ void switch_game_mode(char switchWhat) {
case rg::bitrunc: case rg::bitrunc:
case rg::gp: case rg::gp:
if(euclid6) geometry = gNormal; if(euclid6) geometry = gNormal;
nonbitrunc = !nonbitrunc; nonbitrunc = !nonbitrunc; irr::on = false;
gp::on = (switchWhat == rg::gp && !gp::on); gp::on = (switchWhat == rg::gp && !gp::on);
need_reset_geometry = true; need_reset_geometry = true;
#if CAP_TEXTURE #if CAP_TEXTURE
@ -1174,6 +1175,7 @@ void switch_game_mode(char switchWhat) {
else geometry = targetgeometry; else geometry = targetgeometry;
if(chaosmode && (euclid || sphere || quotient)) chaosmode = false; if(chaosmode && (euclid || sphere || quotient)) chaosmode = false;
if(nonbitrunc && euclid6) nonbitrunc = false; if(nonbitrunc && euclid6) nonbitrunc = false;
if(irr::on) irr::on = false;
if(gp::on && gp::param == gp::loc(1,1) && S3 == 3) { if(gp::on && gp::param == gp::loc(1,1) && S3 == 3) {
gp::on = false; nonbitrunc = false; gp::on = false; nonbitrunc = false;
} }