mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-29 19:40:35 +00:00
rulegen3:: new features
This commit is contained in:
parent
6bc3dc9d6f
commit
0b4df47964
16
rulegen.cpp
16
rulegen.cpp
@ -86,6 +86,8 @@ static const flagtype w_less_smart_retrace = Flag(22); /*< stop early when exami
|
||||
static const flagtype w_less_smart_advance = Flag(23); /*< stop early when examining smart shortcut advancement */
|
||||
static const flagtype w_no_queued_extensions = Flag(24); /*< consider extensions one by one */
|
||||
static const flagtype w_no_branch_skipping = Flag(24); /*< do not skip branches */
|
||||
static const flagtype w_vertex_edges = Flag(25); /*< in reg3 all_edges, consider vertex adjacency */
|
||||
static const flagtype w_ae_extra_step = Flag(26); /*< in reg3 all_edges, make one extra step */
|
||||
#endif
|
||||
|
||||
EX flagtype flags = 0;
|
||||
@ -186,15 +188,17 @@ twalker addstep(twalker x) {
|
||||
return x + wstep;
|
||||
}
|
||||
|
||||
EX int less_states;
|
||||
|
||||
int number_of_types() {
|
||||
if(arb::in()) return isize(arb::current.shapes);
|
||||
if(WDIM == 3) return reg3::quotient_count_sub();
|
||||
if(WDIM == 3) return gcd(reg3::quotient_count_sub(), less_states);
|
||||
throw hr_exception("unknown number_of_types");
|
||||
}
|
||||
|
||||
int get_id(cell *c) {
|
||||
if(arb::in()) return shvid(c);
|
||||
if(GDIM == 3) return reg3::get_aid(c);
|
||||
if(GDIM == 3) return zgmod(reg3::get_aid(c), less_states);
|
||||
throw hr_exception("unknown get_id");
|
||||
}
|
||||
|
||||
@ -753,7 +757,7 @@ EX void handle_distance_errors() {
|
||||
}
|
||||
|
||||
/** make sure that we know c->dist */
|
||||
void be_solid(tcell *c) {
|
||||
EX void be_solid(tcell *c) {
|
||||
if(c->is_solid) return;
|
||||
if(tcellcount >= max_tcellcount)
|
||||
throw rulegen_surrender("max_tcellcount exceeded");
|
||||
@ -1797,7 +1801,7 @@ bool examine_branch(int id, int left, int right) {
|
||||
|
||||
bool need_clear_codes;
|
||||
|
||||
void clear_codes() {
|
||||
EX void clear_codes() {
|
||||
need_clear_codes = false;
|
||||
for(auto a: all_analyzers) {
|
||||
for(auto tw: a->inhabitants) tw.at->code = MYSTERY_LARGE;
|
||||
@ -2015,6 +2019,10 @@ EX void rules_iteration() {
|
||||
if(isize(important) != N)
|
||||
throw rulegen_retry("need more rules after examine");
|
||||
|
||||
if(WDIM == 3) {
|
||||
check_road_shortcuts();
|
||||
}
|
||||
|
||||
if(skipped_branches.size()) {
|
||||
checks_to_skip.clear();
|
||||
for(auto sb: skipped_branches) sb();
|
||||
|
98
rulegen3.cpp
98
rulegen3.cpp
@ -11,6 +11,78 @@ namespace hr {
|
||||
|
||||
EX namespace rulegen {
|
||||
|
||||
struct road_shortcut_trie_vertex {
|
||||
set<vector<int>> backpaths;
|
||||
map<int, shared_ptr<struct road_shortcut_trie_vertex>> children;
|
||||
};
|
||||
|
||||
EX map<int, shared_ptr<struct road_shortcut_trie_vertex>> road_shortcuts;
|
||||
|
||||
int qroad;
|
||||
|
||||
map<int, int> qroad_for;
|
||||
map<tcell*, int> qroad_memo;
|
||||
|
||||
EX void add_road_shortcut(tcell *s, tcell *t) {
|
||||
shared_ptr<road_shortcut_trie_vertex> u;
|
||||
vector<int> tpath;
|
||||
if(!road_shortcuts.count(s->id)) road_shortcuts[s->id] = make_shared<road_shortcut_trie_vertex>();
|
||||
u = road_shortcuts[s->id];
|
||||
while(true) {
|
||||
// println(hlog, s, " dist=", s->dist, " parent = ", s->parent_dir, " vs ", t, " dist=", t->dist, " parent = ", t->parent_dir);
|
||||
if(s == t) {
|
||||
reverse(tpath.begin(), tpath.end());
|
||||
auto& ba = u->backpaths;
|
||||
if(!ba.count(tpath)) qroad++, qroad_for[s->id]++;
|
||||
ba.insert(tpath);
|
||||
return;
|
||||
}
|
||||
if(s->dist >= t->dist) {
|
||||
twalker sw = s;
|
||||
get_parent_dir(sw);
|
||||
if(s->parent_dir == MYSTERY) throw hr_exception("unknown parent_dir (s) in add_road_shortcut");
|
||||
if(!u->children.count(s->parent_dir)) u->children[s->parent_dir] = make_shared<road_shortcut_trie_vertex>();
|
||||
u = u->children[s->parent_dir];
|
||||
s = s->move(s->parent_dir);
|
||||
}
|
||||
if(t->dist > s->dist) {
|
||||
twalker tw = t;
|
||||
get_parent_dir(tw);
|
||||
if(t->parent_dir == MYSTERY) throw hr_exception("unknown parent_dir (t) in add_road_shortcut");
|
||||
tpath.push_back(t->c.spin(t->parent_dir));
|
||||
t = t->move(t->parent_dir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EX int newcon;
|
||||
|
||||
EX void apply_road_shortcut(tcell *s) {
|
||||
auto& mem = qroad_memo[s];
|
||||
if(mem == qroad_for[s->id]) return;
|
||||
mem = qroad_for[s->id];
|
||||
shared_ptr<road_shortcut_trie_vertex> u;
|
||||
if(!road_shortcuts.count(s->id)) return;
|
||||
u = road_shortcuts[s->id];
|
||||
int q = tcellcount;
|
||||
while(true) {
|
||||
for(auto& v: u->backpaths) {
|
||||
auto s1 = s;
|
||||
for(auto x: v) {
|
||||
s1 = s1->cmove(x);
|
||||
be_solid(s1);
|
||||
}
|
||||
}
|
||||
twalker s0 = s; get_parent_dir(s0);
|
||||
if(!u->children.count(s->parent_dir)) break;
|
||||
u = u->children[s->parent_dir];
|
||||
s = s->move(s->parent_dir);
|
||||
}
|
||||
static int qmax = 0;
|
||||
newcon += tcellcount - q;
|
||||
if(tcellcount > q + qmax) println(hlog, "road shortcuts created ", qmax = tcellcount-q, " new connections");
|
||||
}
|
||||
|
||||
/** next roadsign ID -- they start at -100 and go downwards */
|
||||
int next_roadsign_id = -100;
|
||||
|
||||
@ -20,6 +92,7 @@ EX map<vector<int>, int> roadsign_id;
|
||||
EX int get_roadsign(twalker what) {
|
||||
int dlimit = what.at->dist - 1;
|
||||
tcell *s = what.at, *t = what.peek();
|
||||
apply_road_shortcut(s);
|
||||
vector<int> result;
|
||||
while(s->dist > dlimit) {
|
||||
twalker s0 = s;
|
||||
@ -55,6 +128,7 @@ EX int get_roadsign(twalker what) {
|
||||
visit(c->move(i), c->c.spin(i));
|
||||
}
|
||||
while(t != s) {
|
||||
add_road_shortcut(s, t);
|
||||
int d = visited.at(t);
|
||||
tail.push_back(t->dist - dlimit);
|
||||
tail.push_back(t->c.spin(d));
|
||||
@ -73,6 +147,7 @@ EX vector<pair<int, int>>& check_all_edges(twalker cw, analyzer_state* a, int id
|
||||
if(ae.empty()) {
|
||||
set<tcell*> seen;
|
||||
vector<pair<twalker, transmatrix> > visited;
|
||||
vector<pair<int, int>> ae1;
|
||||
auto visit = [&] (twalker tw, const transmatrix& T, int id, int dir) {
|
||||
if(seen.count(tw.at)) return;
|
||||
seen.insert(tw.at);
|
||||
@ -88,7 +163,12 @@ EX vector<pair<int, int>>& check_all_edges(twalker cw, analyzer_state* a, int id
|
||||
for(auto w: rotated)
|
||||
if(sqhypot_d(MDIM, v-w) < 1e-6)
|
||||
common++;
|
||||
if(common < 2) return;
|
||||
if(flags & w_vertex_edges) {
|
||||
if(common < 1) { ae1.emplace_back(id, dir); return; }
|
||||
}
|
||||
else {
|
||||
if(common < 2) { ae1.emplace_back(id, dir); return; }
|
||||
}
|
||||
visited.emplace_back(tw, T);
|
||||
ae.emplace_back(id, dir);
|
||||
};
|
||||
@ -99,6 +179,7 @@ EX vector<pair<int, int>>& check_all_edges(twalker cw, analyzer_state* a, int id
|
||||
visit(tw + j + wstep, visited[i].second * currentmap->adj(tcell_to_cell[tw.at], (tw+j).spin), i, j);
|
||||
}
|
||||
}
|
||||
if(flags & w_ae_extra_step) for(auto p: ae1) ae.push_back(p);
|
||||
println(hlog, "for ", tie(cw.at->id, cw.spin), " generated all_edges structure: ", ae, " of size ", isize(ae));
|
||||
}
|
||||
return ae;
|
||||
@ -110,6 +191,21 @@ EX void cleanup3() {
|
||||
next_roadsign_id = -100;
|
||||
}
|
||||
|
||||
int last_qroad;
|
||||
|
||||
EX void check_road_shortcuts() {
|
||||
println(hlog, "road shortcuts = ", qroad, " treestates = ", isize(treestates), " roadsigns = ", next_roadsign_id);
|
||||
if(qroad > last_qroad) {
|
||||
println(hlog, "qroad_for = ", qroad_for);
|
||||
println(hlog, "newcon = ", newcon, " tcellcount = ", tcellcount); newcon = 0;
|
||||
clear_codes();
|
||||
last_qroad = qroad;
|
||||
roadsign_id.clear();
|
||||
next_roadsign_id = -100;
|
||||
throw rulegen_retry("new road shortcuts");
|
||||
}
|
||||
}
|
||||
|
||||
void genhoneycomb(string fname) {
|
||||
if(WDIM != 3) throw hr_exception("genhoneycomb not in honeycomb");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user