1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-06-18 11:19:59 +00:00

simpler multi-connection system

This commit is contained in:
Zeno Rogue 2021-08-17 14:28:27 +02:00
parent 031d6a2c50
commit 631827c657

View File

@ -719,6 +719,7 @@ struct treestate {
int id;
bool known;
vector<int> rules;
vector<int> sub_status; // 1 if DIR_LEFT or DIR_RIGHT and connected to a child
twalker giver;
int sid;
int parent_dir;
@ -891,10 +892,6 @@ struct mismatch_error : rulegen_retry {
mismatch_error() : rulegen_retry("mismatch error") {}
};
struct double_edges: rulegen_surrender {
double_edges() : rulegen_surrender("double edges detected") {}
};
EX int rule_root;
vector<int> gen_rule(twalker cwmain);
@ -907,8 +904,6 @@ vector<tcell*> cq;
#if HDR
/* special codes */
static const int DIR_UNKNOWN = -1;
static const int DIR_MULTI_GO_LEFT = -2;
static const int DIR_MULTI_GO_RIGHT = -3;
static const int DIR_LEFT = -4;
static const int DIR_RIGHT = -5;
static const int DIR_PARENT = -6;
@ -1107,7 +1102,6 @@ struct bad_tree : rulegen_retry {
bool equiv(twalker w1, twalker w2);
inline bool IS_DIR_MULTI(int d) { return among(d, DIR_MULTI_GO_LEFT, DIR_MULTI_GO_RIGHT); }
struct branchdata {
int id;
int dir;
@ -1133,11 +1127,6 @@ struct branchdata {
dir += i;
dir = gmod(dir, isize(treestates[id].rules));
}
void spin_full(int i) {
spin(i);
while(IS_DIR_MULTI(treestates[id].rules[dir]))
spin(i);
}
};
inline void print(hstream& hs, const branchdata& bd) { print(hs, "[", bd.id,":",bd.dir, " ", bd.at, ":", bd.temporary, "]"); }
@ -1145,28 +1134,20 @@ inline void print(hstream& hs, const branchdata& bd) { print(hs, "[", bd.id,":",
/* we need to be careful with multiple edges */
bool paired(twalker w1, twalker w2) {
if(w1 + wstep == w2) return true;
if(w1.cpeek() == w2.at && w2.cpeek() == w1.at) {
return true;
}
return false;
return w1 + wstep == w2;
}
bool equiv(twalker w1, twalker w2) {
if(w1 == w2) return true;
if(w1.at == w2.at && w1.cpeek() == w2.cpeek()) {
return true;
}
return false;
return w1 == w2;
}
void advance(vector<branchdata>& bdata, branchdata at, int dir, bool start_forward, bool stack, int distlimit) {
if(start_forward) {
at.step();
at.spin_full(dir);
at.spin(dir);
}
else {
at.spin_full(dir);
at.spin(dir);
}
vector<branchdata> b;
int steps = 0;
@ -1175,7 +1156,13 @@ void advance(vector<branchdata>& bdata, branchdata at, int dir, bool start_forwa
throw rulegen_failure("max_adv_steps exceeded");
auto& ts = treestates[at.id];
auto r = ts.rules[at.dir];
if(r < 0) {
if(ts.sub_status[at.dir]) {
at.temporary = 0;
b.push_back(at);
b.push_back(at);
at.spin(dir);
}
else if(r < 0) {
at.temporary = 0;
b.push_back(at);
break;
@ -1186,11 +1173,11 @@ void advance(vector<branchdata>& bdata, branchdata at, int dir, bool start_forwa
b.pop_back();
else
advance(b, at, -dir, true, true, distlimit);
at.spin_full(dir);
at.spin(dir);
}
else {
at.step();
if(at.at.at->dist < distlimit || !ts.is_live) at.spin_full(dir);
if(at.at.at->dist < distlimit || !ts.is_live) at.spin(dir);
else {
at.temporary = dir;
b.push_back(at);
@ -1207,7 +1194,8 @@ void advance(vector<branchdata>& bdata, branchdata at, int dir, bool start_forwa
}
void verify_lr(branchdata bd, int dir) {
if(dir) { bd.spin_full(dir); if(bd.dir == 0) bd.dir = bd.at.at->type; }
return;
if(dir) { bd.spin(dir); if(bd.dir == 0) bd.dir = bd.at.at->type; }
auto& r = treestates[bd.id].rules;
for(int i=0; i<isize(r); i++) {
int val = i < bd.dir ? DIR_LEFT : DIR_RIGHT;
@ -1225,25 +1213,26 @@ void examine_branch(int id, int left, int right) {
auto rg = treestates[id].giver;
if(debugflags & DF_GEOM)
println(hlog, "need to examine branches ", tie(left, right), " of ", id, " starting from ", rg);
indenter ind(2);
vector<branchdata> bdata;
int dist_at = rg.at->dist;
do {
/* can be false in case of multi-edges */
if(treestates[id].rules[left] >= 0) {
if(bdata.size() && bdata.back().dir == 0)
bdata.pop_back();
else {
auto bl = branchdata{id, left, rg+left, dist_at+dlbonus};
if(true) {
auto bl = branchdata{id, left, rg+left, dist_at+dlbonus};
bl.temporary = 0;
if(treestates[id].rules[left] >= 0)
advance(bdata, bl, -1, true, true, dist_at+5);
}
else bdata.push_back(bl);
}
left++;
if(left == rg.at->type) left = 0;
if(treestates[id].rules[left] >= 0) {
if(true) {
auto br = branchdata{id, left, rg+left, dist_at+dlbonus};
advance(bdata, br, +1, true, false, dist_at+5);
br.temporary = 0;
if(treestates[id].rules[left] >= 0)
advance(bdata, br, +1, true, false, dist_at+5);
else bdata.push_back(br);
}
}
while(left != right);
@ -1340,6 +1329,23 @@ void find_single_live_branch(twalker at) {
}
}
void find_sub_status() {
for(int id=0; id<isize(treestates); id++)
treestates[id].sub_status.resize(isize(treestates[id].rules), 0);
for(int id=0; id<isize(treestates); id++) {
auto& ts = treestates[id];
for(int im=0; im<isize(ts.rules); im++)
if(ts.rules[im] >= 0 || ts.rules[im] == DIR_PARENT)
for(int i=0; i<isize(ts.rules); i++) if(i != im) {
if((ts.giver+im).peek() == (ts.giver+i).peek()) {
println(hlog, "found multi connection at ", id, ":", i, " equals ", im, ts.rules[im] == DIR_PARENT ? " [parent]" : " [child]");
ts.sub_status[i] = 1;
}
}
}
}
void rules_iteration() {
clear_codes();
@ -1394,25 +1400,15 @@ void rules_iteration() {
}
for(int id=0; id<isize(treestates); id++) {
auto& rg = treestates[id].giver;
auto& r = treestates[id].rules;
for(int p=0; p<2; p++)
for(int it=0; it<isize(r); it++) {
for(int i=0; i<isize(r); i++) {
int i1 = gmod(i+1, isize(r));
if((rg+i).peek() == (rg+i1).peek()) {
if(r[i1] == DIR_UNKNOWN && (r[i] >= (p?DIR_UNKNOWN:0) || r[i] == DIR_PARENT || r[i] == DIR_MULTI_GO_LEFT))
r[i1] = DIR_MULTI_GO_LEFT;
if(r[i] == DIR_UNKNOWN && (r[i1] >= 0 || r[i1] == DIR_PARENT || r[i+1] == DIR_MULTI_GO_RIGHT))
r[i] = DIR_MULTI_GO_RIGHT;
}
}
}
for(int i=0; i<isize(r); i++) if(r[i] == DIR_UNKNOWN) {
int val = treestates[id].code.second[i+1];
if(val < 2 || val >= 8) throw rulegen_failure("wrong code in gen_rule");
if(val < 2 || val >= 8) {
debuglist = { treestates[id].giver };
println(hlog, "id = ", id, " i = ", i, " val = ", val, " code = ", treestates[id].code);
throw rulegen_failure("wrong code in gen_rule");
}
r[i] = ((val & 1) ? DIR_RIGHT : DIR_LEFT);
}
}
@ -1424,6 +1420,8 @@ void rules_iteration() {
int q = isize(single_live_branch_close_to_root);
find_sub_status();
for(int id=0; id<isize(treestates); id++) if(treestates[id].is_live) {
auto& r = treestates[id].rules;
int last_live_branch = -1;