1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-20 15:40:26 +00:00

rulegen:: skipping branches which seem good

This commit is contained in:
Zeno Rogue 2021-12-27 23:09:37 +01:00
parent a5d24e0ff7
commit 468873da29

View File

@ -1045,6 +1045,7 @@ struct treestate {
twalker giver; twalker giver;
int sid; int sid;
int parent_dir; int parent_dir;
int astate;
twalker where_seen; twalker where_seen;
bool is_live; bool is_live;
bool is_possible_parent; bool is_possible_parent;
@ -1254,6 +1255,7 @@ EX pair<int, int> get_treestate_id(twalker& cw) {
nts.where_seen = cw; nts.where_seen = cw;
nts.known = false; nts.known = false;
nts.is_live = true; nts.is_live = true;
nts.astate = co.second;
} }
co.second = v->dir; co.second = v->dir;
return co; return co;
@ -1543,7 +1545,7 @@ void verified_treewalk(twalker& tw, int id, int dir) {
treewalk(tw, dir); treewalk(tw, dir);
} }
void examine_branch(int id, int left, int right) { bool examine_branch(int id, int left, int right) {
auto rg = treestates[id].giver; auto rg = treestates[id].giver;
if(debugflags & DF_GEOM) if(debugflags & DF_GEOM)
@ -1587,7 +1589,7 @@ void examine_branch(int id, int left, int right) {
if(0) if(debugflags & DF_GEOM) if(0) if(debugflags & DF_GEOM)
println(hlog, "got hash: ", hash); println(hlog, "got hash: ", hash);
if(verified_branches.count(hash)) { if(verified_branches.count(hash)) {
return; return true;
} }
verified_branches.insert(hash); verified_branches.insert(hash);
@ -1626,6 +1628,7 @@ void examine_branch(int id, int left, int right) {
} }
catch(verify_advance_failed&) { catch(verify_advance_failed&) {
if(flags & w_examine_once) throw rulegen_retry("advance failed"); if(flags & w_examine_once) throw rulegen_retry("advance failed");
return false;
} }
} }
@ -1707,6 +1710,9 @@ void clear_treestates() {
if(a->id == MYSTERY) a->dir = MYSTERY; if(a->id == MYSTERY) a->dir = MYSTERY;
} }
using branch_check = tuple<int, int, int>;
set<branch_check> checks_to_skip;
EX void rules_iteration() { EX void rules_iteration() {
try_count++; try_count++;
debuglist = {}; debuglist = {};
@ -1795,6 +1801,17 @@ EX void rules_iteration() {
handle_queued_extensions(); handle_queued_extensions();
vector<reaction_t> skipped_branches;
auto examine_or_skip_branch = [&] (int id, int fb, int sb) {
auto b = branch_check{treestates[id].astate, fb, sb};
if(checks_to_skip.count(b)) {
skipped_branches.emplace_back([id, fb, sb] { examine_branch(id, fb, sb); });
return;
}
if(examine_branch(id, fb, sb)) checks_to_skip.insert(b);
};
for(int id=0; id<isize(treestates); id++) if(treestates[id].is_live) { for(int id=0; id<isize(treestates); id++) if(treestates[id].is_live) {
auto r = treestates[id].rules; /* no & because treestates might have moved */ auto r = treestates[id].rules; /* no & because treestates might have moved */
if(r.empty()) continue; if(r.empty()) continue;
@ -1805,7 +1822,7 @@ EX void rules_iteration() {
if(r[i] >= 0 && treestates[r[i]].is_live) { if(r[i] >= 0 && treestates[r[i]].is_live) {
if(first_live_branch == -1) first_live_branch = i; if(first_live_branch == -1) first_live_branch = i;
if(last_live_branch >= 0) if(last_live_branch >= 0)
examine_branch(id, last_live_branch, i); examine_or_skip_branch(id, last_live_branch, i);
last_live_branch = i; last_live_branch = i;
qbranches++; qbranches++;
} }
@ -1827,9 +1844,11 @@ EX void rules_iteration() {
clear_sidecache_and_codes(); clear_sidecache_and_codes();
throw rulegen_retry("single live branch"); throw rulegen_retry("single live branch");
} }
if(treestates[id].is_root) examine_branch(id, last_live_branch, first_live_branch); if(treestates[id].is_root)
examine_or_skip_branch(id, last_live_branch, first_live_branch);
} }
after_branches:
for(int id=0; id<isize(treestates); id++) if(!treestates[id].giver.at) { for(int id=0; id<isize(treestates); id++) if(!treestates[id].giver.at) {
important.push_back(treestates[id].where_seen); important.push_back(treestates[id].where_seen);
} }
@ -1839,6 +1858,13 @@ EX void rules_iteration() {
if(isize(important) != N) if(isize(important) != N)
throw rulegen_retry("need more rules after examine"); throw rulegen_retry("need more rules after examine");
if(skipped_branches.size()) {
checks_to_skip.clear();
for(auto sb: skipped_branches) sb();
skipped_branches.clear();
goto after_branches;
}
minimize_rules(); minimize_rules();
find_possible_parents(); find_possible_parents();