1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-02-03 12:49:17 +00:00

product:: cspin is now validated

This commit is contained in:
Zeno Rogue 2019-11-30 12:45:54 +01:00
parent 42a41835dc
commit 1518d406b5

View File

@ -1039,7 +1039,7 @@ EX namespace hybrid {
hrmap *underlying_map; hrmap *underlying_map;
int space_spin; bool twisted;
map<cell*, pair<cellwalker, cellwalker>> spins; map<cell*, pair<cellwalker, cellwalker>> spins;
map<pair<cell*, int>, cell*> at; map<pair<cell*, int>, cell*> at;
@ -1058,7 +1058,7 @@ EX namespace hybrid {
} }
cell *getCell(cell *u, int h) { cell *getCell(cell *u, int h) {
if(space_spin) { if(twisted) {
if(!spins.count(u)) if(!spins.count(u))
println(hlog, "link missing: ", u); println(hlog, "link missing: ", u);
else { else {
@ -1075,7 +1075,7 @@ EX namespace hybrid {
cell* gamestart() override { return getCell(underlying_map->gamestart(), 0); } cell* gamestart() override { return getCell(underlying_map->gamestart(), 0); }
hrmap_hybrid() { hrmap_hybrid() {
space_spin = 0; twisted = false;
in_underlying([this] { initcells(); underlying_map = currentmap; }); in_underlying([this] { initcells(); underlying_map = currentmap; });
for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL; for(hrmap*& m: allmaps) if(m == underlying_map) m = NULL;
} }
@ -1214,7 +1214,7 @@ EX namespace hybrid {
vector<cell*> to_link; vector<cell*> to_link;
EX void will_link(cell *c) { if(pmap && ((hrmap_hybrid*) pmap)->space_spin) to_link.push_back(c); } EX void will_link(cell *c) { if(pmap && ((hrmap_hybrid*) pmap)->twisted) to_link.push_back(c); }
EX void link() { EX void link() {
auto pm = (hrmap_hybrid*) pmap; auto pm = (hrmap_hybrid*) pmap;
@ -1250,14 +1250,14 @@ EX namespace product {
} }
transmatrix adj(cell *c, int i) override { transmatrix adj(cell *c, int i) override {
if(space_spin && i == c->type-1 && where[c].second == cgi.steps-1) { if(twisted && i == c->type-1 && where[c].second == cgi.steps-1) {
auto b = spins[where[c].first].first; auto b = spins[where[c].first].first;
transmatrix T = mscale(Id, cgi.plevel); transmatrix T = mscale(Id, cgi.plevel);
T = T * spin(2 * M_PI * b.spin / b.at->type); T = T * spin(2 * M_PI * b.spin / b.at->type);
if(b.mirrored) T = T * Mirror; if(b.mirrored) T = T * Mirror;
return T; return T;
} }
if(space_spin && i == c->type-2 && where[c].second == 0) { if(twisted && i == c->type-2 && where[c].second == 0) {
auto b = spins[where[c].first].second; auto b = spins[where[c].first].second;
transmatrix T = mscale(Id, -cgi.plevel); transmatrix T = mscale(Id, -cgi.plevel);
T = T * spin(2 * M_PI * b.spin / b.at->type); T = T * spin(2 * M_PI * b.spin / b.at->type);
@ -1279,20 +1279,22 @@ EX namespace product {
} }
hrmap_product() { hrmap_product() {
current_spin_invalid = false;
if(cspin) { if(cspin) {
space_spin = cspin;
in_underlying([&] { in_underlying([&] {
twisted = validate_spin();
if(!twisted) { current_spin_invalid = true; return; }
auto ugs = currentmap->gamestart(); auto ugs = currentmap->gamestart();
spins[ugs] = make_pair( spins[ugs] = make_pair(
cellwalker(ugs, gmod(+space_spin, ugs->type)), cellwalker(ugs, gmod(+cspin, ugs->type)),
cellwalker(ugs, gmod(-space_spin, ugs->type)) cellwalker(ugs, gmod(-cspin, ugs->type))
); );
manual_celllister cl; manual_celllister cl;
cl.add(ugs); cl.add(ugs);
for(int i=0; i<isize(cl.lst); i++) { for(int i=0; i<isize(cl.lst); i++) {
cell *c = cl.lst[i]; cell *c = cl.lst[i];
hybrid::will_link(c); hybrid::will_link(c);
forCellIdEx(c2, i, c) cl.add(c2); forCellEx(c2, c) cl.add(c2);
} }
hybrid::link(); hybrid::link();
}); });
@ -1300,6 +1302,8 @@ EX namespace product {
} }
}; };
EX bool current_spin_invalid;
EX int cwall_offset, cwall_mask, actual_view_level, csteps, cspin; EX int cwall_offset, cwall_mask, actual_view_level, csteps, cspin;
EX void drawcell_stack(cellwalker cw, transmatrix V) { EX void drawcell_stack(cellwalker cw, transmatrix V) {
@ -1329,7 +1333,7 @@ EX namespace product {
int z1 = z0; int z1 = z0;
auto V0 = V; auto V0 = V;
for(int z=0; z<=max_z; z++) { for(int z=0; z<=max_z; z++) {
if(((hybrid::hrmap_hybrid*)currentmap)->space_spin) cwall_mask = -1; if(((hybrid::hrmap_hybrid*)currentmap)->twisted) cwall_mask = -1;
cwall_mask &= ~(3<<c->type); cwall_mask &= ~(3<<c->type);
if(z1 > actual_view_level) cwall_mask |= (1<<c->type); if(z1 > actual_view_level) cwall_mask |= (1<<c->type);
if(z1 < actual_view_level) cwall_mask |= (2<<c->type); if(z1 < actual_view_level) cwall_mask |= (2<<c->type);
@ -1375,6 +1379,28 @@ EX namespace product {
return zshift(res, h[2]); return zshift(res, h[2]);
} }
EX bool validate_spin() {
if(prod) return hybrid::in_underlying_geometry(validate_spin);
if(penrose) return false;
if(!quotient && !archimedean) return true;
map<cell*, cellwalker> cws;
manual_celllister cl;
cell *start = currentmap->gamestart();
cl.add(start);
cws[start] = cellwalker(start, cspin);
for(int i=0; i<isize(cl.lst); i++) {
cell *c = cl.lst[i];
cellwalker cwc = cws.at(c);
forCellIdEx(c2, j, c) {
cellwalker cwc2 = cwc + j + wstep - c->c.spin(j);
if(!cws.count(c2)) cws[c2] = cwc2;
else if(cws[c2] != cwc2) return false;
cl.add(c2);
}
}
return true;
}
EX void show_config() { EX void show_config() {
cmode = sm::SIDE | sm::MAYDARK; cmode = sm::SIDE | sm::MAYDARK;
gamescreen(1); gamescreen(1);
@ -1407,6 +1433,10 @@ EX namespace product {
start_game(); start_game();
}; };
}); });
if(current_spin_invalid)
dialog::addInfo("the current rotation is invalid");
else
dialog::addBreak(100);
dialog::addBreak(50); dialog::addBreak(50);
dialog::addBack(); dialog::addBack();