mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-30 15:39:54 +00:00
notknot:: optimized by improved loop recording
This commit is contained in:
parent
693f95f3b4
commit
ade0eb2456
@ -410,7 +410,9 @@ struct hrmap_notknot : hrmap {
|
|||||||
unify.emplace_back(a, b);
|
unify.emplace_back(a, b);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool make_loop(ucover* u, int loopcount, const vector<int>& looplist) {
|
map<heptagon*, vector<vector<int> > > uloops;
|
||||||
|
|
||||||
|
bool collapse_loop(ucover* u, int loopcount, const vector<int>& looplist) {
|
||||||
auto ux = u;
|
auto ux = u;
|
||||||
for(int iter=0; iter<loopcount; iter++)
|
for(int iter=0; iter<loopcount; iter++)
|
||||||
for(int w: looplist) {
|
for(int w: looplist) {
|
||||||
@ -420,9 +422,34 @@ struct hrmap_notknot : hrmap {
|
|||||||
add_to_unify(u, ux);
|
add_to_unify(u, ux);
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool verify_loop(ucover* u, int loopcount, const vector<int>& looplist) {
|
||||||
|
auto ux = u;
|
||||||
|
for(int iter=0; iter<loopcount; iter++)
|
||||||
|
for(int w: looplist) {
|
||||||
|
ux = gen_adj(ux, w);
|
||||||
|
if(ux->iswall()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
set<heptagon*> analyzed;
|
void record_loop(ucover* u, int loopcount, const vector<int>& looplist) {
|
||||||
|
vector<int> repeated;
|
||||||
|
for(int l=0; l<loopcount; l++)
|
||||||
|
for(auto v: looplist) repeated.push_back(v);
|
||||||
|
uloops[u->where].push_back(repeated);
|
||||||
|
};
|
||||||
|
|
||||||
|
void record_loop_if_nowall(ucover* u, int loopcount, const vector<int>& looplist) {
|
||||||
|
if(verify_loop(u, loopcount, looplist))
|
||||||
|
record_loop(u, loopcount, looplist);
|
||||||
|
}
|
||||||
|
|
||||||
|
void record_loop_verify(ucover* u, int loopcount, const vector<int>& looplist, const hr_exception& ex) {
|
||||||
|
if(!verify_loop(u, loopcount, looplist)) throw ex;
|
||||||
|
record_loop(u, loopcount, looplist);
|
||||||
|
}
|
||||||
|
|
||||||
transmatrix adj(ucover *u, int k) {
|
transmatrix adj(ucover *u, int k) {
|
||||||
dynamicval<eGeometry> g(geometry, base);
|
dynamicval<eGeometry> g(geometry, base);
|
||||||
dynamicval<hrmap*> m(currentmap, euc);
|
dynamicval<hrmap*> m(currentmap, euc);
|
||||||
@ -447,15 +474,15 @@ struct hrmap_notknot : hrmap {
|
|||||||
void unify_homotopies(ucover *u) {
|
void unify_homotopies(ucover *u) {
|
||||||
/* unify homotopies */
|
/* unify homotopies */
|
||||||
if(base == gNil) {
|
if(base == gNil) {
|
||||||
make_loop(u, 1, {0, 2, 3, 5});
|
collapse_loop(u, 1, {0, 2, 3, 5});
|
||||||
make_loop(u, 1, {1, 2, 4, 5});
|
collapse_loop(u, 1, {1, 2, 4, 5});
|
||||||
make_loop(u, 1, {0, 1, 3, 4, 2});
|
collapse_loop(u, 1, {0, 1, 3, 4, 2});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(base == gCubeTiling) {
|
if(base == gCubeTiling) {
|
||||||
make_loop(u, 1, {0, 1, 3, 4});
|
collapse_loop(u, 1, {0, 1, 3, 4});
|
||||||
make_loop(u, 1, {0, 2, 3, 5});
|
collapse_loop(u, 1, {0, 2, 3, 5});
|
||||||
make_loop(u, 1, {1, 2, 4, 5});
|
collapse_loop(u, 1, {1, 2, 4, 5});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,16 +519,8 @@ struct hrmap_notknot : hrmap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map<heptagon*, vector<vector<int> > > uloops;
|
|
||||||
|
|
||||||
void unify_loops_general(ucover *u) {
|
void unify_loops_general(ucover *u) {
|
||||||
int t = u->where->type;
|
int t = u->where->type;
|
||||||
if(uloops.count(u->where)) {
|
|
||||||
for(auto& ul: uloops[u->where])
|
|
||||||
make_loop(u, loop, ul);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uloops[u->where] = {};
|
|
||||||
for(int i=0; i<t; i++) {
|
for(int i=0; i<t; i++) {
|
||||||
auto u1 = gen_adj(u, i);
|
auto u1 = gen_adj(u, i);
|
||||||
if(u1->nowall()) continue;
|
if(u1->nowall()) continue;
|
||||||
@ -540,8 +559,7 @@ struct hrmap_notknot : hrmap {
|
|||||||
println(hlog, "path = ", path);
|
println(hlog, "path = ", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
uloops[u->where].push_back(path);
|
record_loop_verify(u, loop, path, hr_exception("wall in loops_general"));
|
||||||
make_loop(u, loop, path);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
camefrom[at->where] = ldir;
|
camefrom[at->where] = ldir;
|
||||||
@ -575,33 +593,22 @@ struct hrmap_notknot : hrmap {
|
|||||||
|
|
||||||
if(base_map == "" && base == gNil) {
|
if(base_map == "" && base == gNil) {
|
||||||
special = true;
|
special = true;
|
||||||
make_loop(u, loop, {0, 0, 2, 2, 2, 3, 3, 5, 5, 5});
|
record_loop_if_nowall(u, loop, {0, 0, 2, 2, 2, 3, 3, 5, 5, 5});
|
||||||
if(u->where->zebraval & 16)
|
|
||||||
for(int dir: {0,1,2}) {
|
if(u->where->zebraval & 16) {
|
||||||
auto ux = u;
|
for(int dir: {0,1,2})
|
||||||
for(int iter=0; iter<nilv::nilperiod[dir]; iter++) {
|
record_loop_verify(u, nilv::nilperiod[dir], {dir}, hr_exception("16 failed"));
|
||||||
ux = gen_adj(ux, dir);
|
|
||||||
if(ux->state != 0) goto next_dir;
|
|
||||||
}
|
|
||||||
println(hlog, "succeeded in direction ", dir);
|
|
||||||
add_to_unify(u, ux);
|
|
||||||
next_dir: ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(base_map == "" && base == gArnoldCat) {
|
if(base_map == "" && base == gArnoldCat) {
|
||||||
if(u->where->zebraval & 16)
|
|
||||||
for(int dir: {0,4,5}) {
|
if(u->where->zebraval & 16) {
|
||||||
auto ux = u;
|
for(int dir: {0,4,5}) {
|
||||||
int steps = dir ? asonov::period_xy : asonov::period_z;
|
int steps = dir ? asonov::period_xy : asonov::period_z;
|
||||||
if(dir) steps *= 2;
|
if(dir) steps *= 2;
|
||||||
for(int iter=0; iter<steps; iter++) {
|
record_loop_verify(u, steps, {dir}, hr_exception("16 failed"));
|
||||||
ux = gen_adj(ux, dir);
|
|
||||||
if(ux->state != 0) goto next_dir_cat;
|
|
||||||
}
|
}
|
||||||
println(hlog, "succeeded in direction ", dir);
|
|
||||||
add_to_unify(u, ux);
|
|
||||||
next_dir_cat: ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(u->where->zebraval & 128) {
|
if(u->where->zebraval & 128) {
|
||||||
@ -633,15 +640,14 @@ struct hrmap_notknot : hrmap {
|
|||||||
add_shift(2-p, 0, -1);
|
add_shift(2-p, 0, -1);
|
||||||
myloop.push_back(0);
|
myloop.push_back(0);
|
||||||
|
|
||||||
if(!make_loop(u, 1, myloop))
|
record_loop_verify(u, 1, myloop, hr_exception("128 failed"));
|
||||||
throw hr_exception("fail");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(base == gCubeTiling) {
|
if(base == gCubeTiling) {
|
||||||
special = true;
|
special = true;
|
||||||
make_loop(u, loop, {0, 0, 1, 1, 3, 3, 4, 4});
|
record_loop_if_nowall(u, loop, {0, 0, 1, 1, 3, 3, 4, 4});
|
||||||
}
|
}
|
||||||
|
|
||||||
if(base == gCell120) {
|
if(base == gCell120) {
|
||||||
@ -656,10 +662,13 @@ struct hrmap_notknot : hrmap {
|
|||||||
auto ucur = u;
|
auto ucur = u;
|
||||||
auto ulast = (ucover*) nullptr;
|
auto ulast = (ucover*) nullptr;
|
||||||
|
|
||||||
for(int step=0; step<5*loop; step++) {
|
vector<int> myloop;
|
||||||
|
|
||||||
|
for(int step=0; step<5; step++) {
|
||||||
for(int i=0; i<t; i++) {
|
for(int i=0; i<t; i++) {
|
||||||
auto ucand = ucur->ptr[i];
|
auto ucand = ucur->ptr[i];
|
||||||
if(ucand && isNeighbor(ucand->where->c7, u1->where->c7) && isNeighbor(ucand->where->c7, u2->where->c7) && ucand != ulast) {
|
if(ucand && isNeighbor(ucand->where->c7, u1->where->c7) && isNeighbor(ucand->where->c7, u2->where->c7) && ucand != ulast) {
|
||||||
|
myloop.push_back(i);
|
||||||
ulast = ucur, ucur = ucand;
|
ulast = ucur, ucur = ucand;
|
||||||
goto next_step;
|
goto next_step;
|
||||||
}
|
}
|
||||||
@ -668,7 +677,7 @@ struct hrmap_notknot : hrmap {
|
|||||||
next_step: ;
|
next_step: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_to_unify(u, ucur);
|
record_loop(u, loop, myloop);
|
||||||
fail: ;
|
fail: ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -677,36 +686,9 @@ struct hrmap_notknot : hrmap {
|
|||||||
unify_loops_general(u);
|
unify_loops_general(u);
|
||||||
|
|
||||||
if(u->where == all[0]->where)
|
if(u->where == all[0]->where)
|
||||||
for(auto& lo: to_unloop)
|
for(auto& lo: to_unloop) {
|
||||||
if(!make_loop(u, 1, lo))
|
record_loop_verify(u, 1, lo, hr_exception("loop-to-unloop goes through a wall"));
|
||||||
throw hr_exception("given loop goes through a wall");
|
|
||||||
|
|
||||||
if(loop_any && u->where == all[0]->where) {
|
|
||||||
auto us = all[0];
|
|
||||||
for(int it=1; it<loop_any; it++) {
|
|
||||||
vector<int> pathback;
|
|
||||||
auto uc = u;
|
|
||||||
while(uc->parentdir != -1) {
|
|
||||||
pathback.push_back(uc->parentdir);
|
|
||||||
us = gen_adj(us, uc->parentdir);
|
|
||||||
uc = uc->ptr[(int) uc->parentdir];
|
|
||||||
}
|
|
||||||
if(it == 1) println(hlog, "pathback = ", pathback);
|
|
||||||
}
|
}
|
||||||
add_to_unify(us, u);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(loop_any < 2 && u->where == all[0]->where) {
|
|
||||||
vector<int> pathback;
|
|
||||||
auto us = all[0];
|
|
||||||
auto uc = u;
|
|
||||||
while(uc->parentdir != -1) {
|
|
||||||
pathback.push_back(uc->parentdir);
|
|
||||||
us = gen_adj(us, uc->parentdir);
|
|
||||||
uc = uc->ptr[(int) uc->parentdir];
|
|
||||||
}
|
|
||||||
println(hlog, "pathback = ", pathback);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map<heptagon*, int> indices;
|
map<heptagon*, int> indices;
|
||||||
@ -792,14 +774,40 @@ struct hrmap_notknot : hrmap {
|
|||||||
if(i > terminate_at) { u->state |= 4; continue; }
|
if(i > terminate_at) { u->state |= 4; continue; }
|
||||||
|
|
||||||
for(int k=0; k<u->where->type; k++) gen_adj(u, k);
|
for(int k=0; k<u->where->type; k++) gen_adj(u, k);
|
||||||
|
|
||||||
if(!analyzed.count(u->where)) {
|
|
||||||
analyzed.insert(u->where);
|
|
||||||
unify_homotopies(u);
|
|
||||||
unify_loops(u);
|
|
||||||
}
|
|
||||||
unify_homotopies(u);
|
unify_homotopies(u);
|
||||||
unify_loops(u);
|
|
||||||
|
if(!uloops.count(u->where)) {
|
||||||
|
uloops[u->where] = {};
|
||||||
|
unify_loops(u);
|
||||||
|
println(hlog, "loops recorded for ", u->where, ": ", isize(uloops[u->where]));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto& myloop: uloops[u->where])
|
||||||
|
if(!collapse_loop(u, 1, myloop))
|
||||||
|
throw hr_exception("invalid loop recorded");
|
||||||
|
|
||||||
|
if(u->where == all[0]->where) {
|
||||||
|
vector<int> pathback;
|
||||||
|
auto uc = u;
|
||||||
|
while(uc->parentdir != -1) {
|
||||||
|
pathback.push_back(uc->parentdir);
|
||||||
|
uc = uc->ptr[(int) uc->parentdir];
|
||||||
|
}
|
||||||
|
println(hlog, "pathback = ", pathback);
|
||||||
|
|
||||||
|
if(loop_any) {
|
||||||
|
auto us = all[0];
|
||||||
|
for(int it=1; it<loop_any; it++) {
|
||||||
|
uc = u;
|
||||||
|
while(uc->parentdir != -1) {
|
||||||
|
us = gen_adj(us, uc->parentdir);
|
||||||
|
uc = uc->ptr[(int) uc->parentdir];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_to_unify(us, u);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make the walls single-colored */
|
/* make the walls single-colored */
|
||||||
|
Loading…
Reference in New Issue
Block a user