mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-25 01:20:37 +00:00
Merge branch 'zenorogue:master' into main
This commit is contained in:
commit
0a9d671bd3
@ -49,7 +49,7 @@ struct shape {
|
||||
/** list of edge connections */
|
||||
vector<connection_t> connections;
|
||||
int size() const { return isize(vertices); }
|
||||
void build_from_angles_edges();
|
||||
void build_from_angles_edges(bool is_comb);
|
||||
vector<pair<int, int> > sublines;
|
||||
vector<pair<ld, ld>> stretch_shear;
|
||||
int repeat_value;
|
||||
@ -74,7 +74,17 @@ struct slider {
|
||||
struct arbi_tiling {
|
||||
|
||||
int order;
|
||||
bool have_line, have_ph, have_tree, is_star;
|
||||
/* have_line and have_ph: line and ph flags have been marked for tiles */
|
||||
bool have_line, have_ph;
|
||||
/* is the tree structure given in the tes file */
|
||||
bool have_tree;
|
||||
/* use "star." if the tessellation includs star polygons */
|
||||
bool is_star;
|
||||
/* use "combinatorial." for combinatorial tessellations; vertex valences computed based on their angles. Currently only rulegen works for combinatorial tessellations */
|
||||
bool is_combinatorial;
|
||||
/* reserved for future flags */
|
||||
bool res0, res1, res2, res3;
|
||||
|
||||
int yendor_backsteps;
|
||||
|
||||
vector<shape> shapes;
|
||||
@ -187,7 +197,7 @@ void start_poly_debugger(hr_polygon_error& err) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void shape::build_from_angles_edges() {
|
||||
void shape::build_from_angles_edges(bool is_comb) {
|
||||
transmatrix at = Id;
|
||||
vertices.clear();
|
||||
int n = isize(angles);
|
||||
@ -202,6 +212,8 @@ void shape::build_from_angles_edges() {
|
||||
at = at * xpush(edges[i]) * spin(angles[i]);
|
||||
}
|
||||
matrices.push_back(at);
|
||||
if(!legacy) for(auto& a: angles) a -= M_PI;
|
||||
if(is_comb) return;
|
||||
if(!eqmatrix(at, Id)) {
|
||||
throw hr_polygon_error(matrices, id, at);
|
||||
}
|
||||
@ -215,7 +227,6 @@ void shape::build_from_angles_edges() {
|
||||
}
|
||||
if(debugflags & DF_GEOM) println(hlog, "ctr = ", ctr);
|
||||
}
|
||||
if(!legacy) for(auto& a: angles) a -= M_PI;
|
||||
ctr = normalize(ctr);
|
||||
for(auto& v: vertices) v = gpushxto0(ctr) * v;
|
||||
}
|
||||
@ -247,7 +258,7 @@ EX void load_tile(exp_parser& ep, arbi_tiling& c, bool unit) {
|
||||
else throw hr_parse_exception("expecting , or )");
|
||||
}
|
||||
try {
|
||||
cc.build_from_angles_edges();
|
||||
cc.build_from_angles_edges(c.is_combinatorial);
|
||||
}
|
||||
catch(hr_parse_exception& ex) {
|
||||
throw hr_parse_exception(ex.s + ep.where());
|
||||
@ -423,6 +434,7 @@ EX void load(const string& fname, bool after_sliding IS(false)) {
|
||||
c.have_tree = false;
|
||||
c.yendor_backsteps = 0;
|
||||
c.is_star = false;
|
||||
c.is_combinatorial = false;
|
||||
exp_parser ep;
|
||||
ep.s = s;
|
||||
ld angleunit = 1, distunit = 1, angleofs = 0;
|
||||
@ -490,6 +502,9 @@ EX void load(const string& fname, bool after_sliding IS(false)) {
|
||||
else if(ep.eat("star.")) {
|
||||
c.is_star = true;
|
||||
}
|
||||
else if(ep.eat("combinatorial.")) {
|
||||
c.is_combinatorial = true;
|
||||
}
|
||||
else if(ep.eat("option(\"")) {
|
||||
next:
|
||||
string s = "";
|
||||
@ -841,7 +856,7 @@ EX transmatrix get_adj(arbi_tiling& c, int t, int dl, int t1, int xdl) {
|
||||
|
||||
if(co.mirror) swap(vl, vr);
|
||||
|
||||
if(hdist(vl, Res*xvr) + hdist(vr, Res*xvl) > .1) {
|
||||
if(hdist(vl, Res*xvr) + hdist(vr, Res*xvl) > .1 && !c.is_combinatorial) {
|
||||
println(hlog, "s1 = ", kz(spintox(rm*vr)), " s2 = ", kz(rspintox(xrm*xvr)));
|
||||
println(hlog, tie(t, dl), " = ", kz(Res));
|
||||
println(hlog, hdist(vl, Res * xvr), " # ", hdist(vr, Res * xvl));
|
||||
|
@ -184,6 +184,43 @@ void move_to(twalker dw) {
|
||||
move_to(cellwalker(m->clone(dw.at)->c7, dw.spin, dw.mirrored));
|
||||
}
|
||||
|
||||
vector<twalker> old_givers;
|
||||
|
||||
void try_sprawling(tcell *c) {
|
||||
twalker cw = c;
|
||||
cw = get_parent_dir(cw);
|
||||
ufind(cw);
|
||||
auto aid = get_aid(cw);
|
||||
auto a_ptr = &(analyzers[aid.first][aid.second]);
|
||||
vector<twalker> sprawl = { cw };
|
||||
vector<analyzer_state*> states = { nullptr };
|
||||
|
||||
while(true) {
|
||||
auto& a = *a_ptr;
|
||||
if(!a) {
|
||||
println(hlog, "analyzer not allocated");
|
||||
return;
|
||||
}
|
||||
states.push_back(a);
|
||||
if(isize(sprawl) <= cw.at->type) {
|
||||
a->id = 0, a->dir = isize(sprawl)-1;
|
||||
}
|
||||
if(a->id == MYSTERY) {
|
||||
println(hlog, "reached codeid ", a->analyzer_id, " which is state ", a->dir);
|
||||
return;
|
||||
}
|
||||
auto t = sprawl[a->id];
|
||||
twalker tw = t + a->dir;
|
||||
ufind(tw);
|
||||
tw.cpeek();
|
||||
ufind(tw);
|
||||
int mc = move_code(tw + wstep);
|
||||
sprawl.push_back(tw + wstep);
|
||||
println(hlog, "codeid ", a->analyzer_id, ": going from ", tw, " in direction ", a->dir, " reaching ", sprawl.back(), " of movecode ", mc);
|
||||
a_ptr = &(a->substates[mc]);
|
||||
}
|
||||
}
|
||||
|
||||
void debug_menu() {
|
||||
cmode = sm::SIDE | sm::MAYDARK;
|
||||
gamescreen(0);
|
||||
@ -266,6 +303,33 @@ void debug_menu() {
|
||||
dialog::addItem("irradiate x10", 'I');
|
||||
dialog::add_action([] { for(int i=0; i<10; i++) irradiate(); });
|
||||
|
||||
dialog::addItem("record givers", 'g');
|
||||
dialog::add_action([] {
|
||||
old_givers.clear();
|
||||
for(int i=0; i<isize(treestates); i++) old_givers.push_back(treestates[i].giver);
|
||||
println(hlog, "old_givers = ", old_givers);
|
||||
debuglist = old_givers;
|
||||
});
|
||||
|
||||
dialog::addItem("compare givers", 'G');
|
||||
dialog::add_action([] {
|
||||
int Q = isize(old_givers);
|
||||
debuglist = {};
|
||||
for(int i=0; i<Q; i++)
|
||||
for(int j=0; j<i; j++) {
|
||||
auto c1 = get_treestate_id(old_givers[i]);
|
||||
auto c2 = get_treestate_id(old_givers[j]);
|
||||
if(c1.second == c2.second) {
|
||||
println(hlog, "old state ", i, " at ", old_givers[i], " and old state ", j, " at ", old_givers[j], " have now code ", c1);
|
||||
debuglist.push_back(old_givers[i]);
|
||||
debuglist.push_back(old_givers[j]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
dialog::addItem("sprawl", 's');
|
||||
dialog::add_action([m] { try_sprawling(m->counterpart[cwt.at->master]); });
|
||||
|
||||
dialog::addItem("name", 'n');
|
||||
dialog::add_action([m] { println(hlog, "name = ", index_pointer(m->counterpart[cwt.at->master])); });
|
||||
|
||||
@ -287,9 +351,12 @@ void view_debug() {
|
||||
auto label = (tc->dist == MYSTERY ? "?" : its(tc->dist));
|
||||
|
||||
if(show_codes) {
|
||||
string code = (tc->code == MYSTERY ? "?" : its(tc->code));
|
||||
if(show_dist) label = label + "/" + code;
|
||||
else label = code;
|
||||
int code = tc->code;
|
||||
if(code != MYSTERY_LARGE) code = all_analyzers[code]->dir;
|
||||
else code = MYSTERY;
|
||||
string codestr = (code == MYSTERY ? "?" : its(code));
|
||||
if(show_dist) label = label + "/" + codestr;
|
||||
else label = codestr;
|
||||
}
|
||||
|
||||
color_t col = label_color == 1 ? 0xFFFFFF + 0x512960 * tc->code : label_color;
|
||||
@ -743,6 +810,16 @@ void setup_fork(int m, string fname) {
|
||||
test_out = new fhstream(fname, "wt");
|
||||
}
|
||||
|
||||
int max_dist() {
|
||||
int result = -1;
|
||||
tcell* c1 = first_tcell;
|
||||
while(c1) {
|
||||
if(c1->dist != MYSTERY && c1->dist > result) result = c1->dist;
|
||||
c1 = c1->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void test_current(string tesname) {
|
||||
|
||||
disable_bigstuff = true;
|
||||
@ -968,6 +1045,7 @@ void test_current(string tesname) {
|
||||
case 'U': Out("vshapes;vverts;vedges;ushapes;uverts;uedges;xea;xeb;xec", count_uniform());
|
||||
case 'L': Out("mirror_rules", arb::current.mirror_rules);
|
||||
case 'B': Out("listshape;listvalence", format("%lld;%lld", get_shapelist(), get_valence_list()));
|
||||
case 'F': Out("maxdist", max_dist());
|
||||
|
||||
case 'f': Out("file", tesname);
|
||||
case 'l': Out("shortcut", longest_shortcut());
|
||||
@ -986,7 +1064,7 @@ void test_current(string tesname) {
|
||||
|
||||
// for(auto& sh: shortcuts) println(hlog, sh.first, " : ", isize(sh.second), " shortcuts (CSV)");
|
||||
|
||||
/*if(status == "ACC")*/ print_rules();
|
||||
if(status == "ACC" && !forked) print_rules();
|
||||
if(status != "ACC") treestates = alt_treestates;
|
||||
/* for(auto& a: analyzers)
|
||||
println(hlog, "analyzer ", a.first, " size is ", isize(a.second.spread)); */
|
||||
@ -1156,6 +1234,7 @@ void test_from_file(string list) {
|
||||
if(forked && id > 1) exit(0);
|
||||
if(forked && id == 1) stop_game();
|
||||
}
|
||||
while(children) { int pid; wait(&pid); children--; }
|
||||
}
|
||||
|
||||
void rulecat(string list) {
|
||||
@ -1403,6 +1482,10 @@ int testargs() {
|
||||
println(hlog, "failed to convert ", s);
|
||||
}
|
||||
}
|
||||
|
||||
else if(argis("-veb")) {
|
||||
view_examine_branch = true;
|
||||
}
|
||||
|
||||
else if(argis("-dseek")) {
|
||||
shift();
|
||||
|
@ -50,7 +50,7 @@ struct hpcshape {
|
||||
#define SIDE_BSHA 12
|
||||
#define SIDEPARS 13
|
||||
|
||||
/** GOLDBERG_BITS controls the size of tables for Goldberg: 2*(x+y) should be below (1<<GOLDBERG_BITS) */
|
||||
/** GOLDBERG_BITS controls the size of tables for Goldberg. see gp::check_limits */
|
||||
|
||||
#ifndef GOLDBERG_BITS
|
||||
#define GOLDBERG_BITS 5
|
||||
|
@ -1171,10 +1171,12 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) {
|
||||
|
||||
// 4 pi / 2pi = M_PI
|
||||
|
||||
if(pmodel == mdEquivolume)
|
||||
if(md == mdEquivolume)
|
||||
d = pow(volume_auto(d), 1/3.) * pow(M_PI / 2, 1/3.);
|
||||
else if(pmodel == mdEquiarea && sphere)
|
||||
else if(md == mdEquiarea && sphere) {
|
||||
d = sqrt(2*(1 - cos(d))) * M_PI / 2;
|
||||
//d = sin((d+90*degree)/2);
|
||||
}
|
||||
else if(pmodel == mdEquiarea && hyperbolic)
|
||||
d = sqrt(2*(cosh(d) - 1)) / 1.5;
|
||||
|
||||
|
@ -1551,7 +1551,7 @@ EX map<char, colortable> colortables = {
|
||||
0xFFFF80, 0xC040C0, 0xFFD500, 0x000080,
|
||||
0x404040, 0x606060, 0x808080
|
||||
}},
|
||||
{'a', {0x800000, 0x503000, 0x206000, 0x007010, 0x004040, 0x001070, 0x200060, 0x500030}},
|
||||
{'a', {0x800000, 0x503000, 0x206000, 0x202020, 0x004040, 0x001070, 0x606060, 0x500030}},
|
||||
{'e', {0x404040, 0x1800000, 0x1008000, 0x000080 }},
|
||||
{'b', {0x404040, 0x1800000, 0x1008000, 0x000080 }},
|
||||
{'z', {0x1C0C0C0, 0x1E0E0E0, 0x404040, 0x606060 }},
|
||||
|
33
rulegen.cpp
33
rulegen.cpp
@ -19,6 +19,8 @@ EX int max_examine_branch = 5040;
|
||||
EX int max_bdata = 1000;
|
||||
EX int max_getside = 10000;
|
||||
EX int rulegen_timeout = 60;
|
||||
EX int max_shortcut_length = 1200;
|
||||
EX int first_restart_on = 512;
|
||||
|
||||
#if HDR
|
||||
/** exception thrown by this algoritm in case of any problems */
|
||||
@ -502,7 +504,7 @@ EX void shortcut_found(tcell *c, tcell *alt, vector<twalker> &walkers, vector<tw
|
||||
if(debugflags & DF_GEOM)
|
||||
println(hlog, "new shortcut found, pre = ", pre, " post = ", post, " pre reaches ", walkers[wpos], " post reaches ", walkers2.back(), " of type ", walkers[wpos].at->id, " sample = ", c);
|
||||
|
||||
if(isize(pre) > 500) {
|
||||
if(isize(pre) > max_shortcut_length) {
|
||||
debuglist = { c };
|
||||
throw rulegen_failure("shortcut too long");
|
||||
}
|
||||
@ -1215,10 +1217,11 @@ int get_side(twalker what) {
|
||||
bool gl = wl.at->dist <= wr.at->dist;
|
||||
bool gr = wl.at->dist >= wr.at->dist;
|
||||
if(gl) {
|
||||
if(get_sidecache(wl) == 1) wl += wstep;
|
||||
if(side && get_sidecache(wl) == 1) wl += wstep;
|
||||
treewalk(wl, -1);
|
||||
if(wl == to_what) { res = 1; }
|
||||
if(lstack.back() == wl+wstep) {
|
||||
if(!side) ;
|
||||
else if(lstack.back() == wl+wstep) {
|
||||
set_sidecache(lstack.back(), 1);
|
||||
set_sidecache(wl, -1);
|
||||
lstack.pop_back();
|
||||
@ -1226,10 +1229,11 @@ int get_side(twalker what) {
|
||||
else if(wl.at->parent_dir != wl.spin && (wl+wstep).at->parent_dir != (wl+wstep).spin) lstack.push_back(wl);
|
||||
}
|
||||
if(gr) {
|
||||
if(get_sidecache(wr) == -1) wr += wstep;
|
||||
if(side && get_sidecache(wr) == -1) wr += wstep;
|
||||
treewalk(wr, +1);
|
||||
if(wr == to_what) {res = -1; }
|
||||
if(rstack.back() == wr+wstep) {
|
||||
if(!side) ;
|
||||
else if(rstack.back() == wr+wstep) {
|
||||
set_sidecache(rstack.back(), -1);
|
||||
set_sidecache(wr, +1);
|
||||
rstack.pop_back();
|
||||
@ -1243,7 +1247,7 @@ int get_side(twalker what) {
|
||||
return res;
|
||||
}
|
||||
|
||||
int move_code(twalker cs) {
|
||||
EX int move_code(twalker cs) {
|
||||
bool child = false;
|
||||
if(cs.at->dist) {
|
||||
auto csd = get_parent_dir(cs);
|
||||
@ -1631,6 +1635,8 @@ void verified_treewalk(twalker& tw, int id, int dir) {
|
||||
treewalk(tw, dir);
|
||||
}
|
||||
|
||||
EX bool view_examine_branch = false;
|
||||
|
||||
bool examine_branch(int id, int left, int right) {
|
||||
auto rg = treestates[id].giver;
|
||||
|
||||
@ -1672,7 +1678,7 @@ bool examine_branch(int id, int left, int right) {
|
||||
auto rl = get_rule(wl, tsl);
|
||||
auto rr = get_rule(wr, tsr);
|
||||
|
||||
if(0) if(debugflags & DF_GEOM)
|
||||
if(view_examine_branch) if(debugflags & DF_GEOM)
|
||||
println(hlog, "wl = ", wl, " -> ", wl+wstep, " R", rl, " wr = ", wr, " -> ", wr+wstep, " R", rr, " lstack = ", lstack, " rstack = ", rstack);
|
||||
|
||||
if(rl == DIR_RIGHT && rr == DIR_LEFT && lstack.empty() && rstack.empty()) {
|
||||
@ -1680,7 +1686,7 @@ bool examine_branch(int id, int left, int right) {
|
||||
push_deadstack(hash, wl, tsl, -1);
|
||||
hash.emplace_back(-1, wl.at->dist - wr.at->dist);
|
||||
push_deadstack(hash, wr, tsr, +1);
|
||||
if(0) if(debugflags & DF_GEOM)
|
||||
if(view_examine_branch) if(debugflags & DF_GEOM)
|
||||
println(hlog, "got hash: ", hash);
|
||||
if(verified_branches.count(hash)) {
|
||||
return true;
|
||||
@ -1866,8 +1872,6 @@ EX void rules_iteration() {
|
||||
println(hlog, "deadend states found: ", new_deadends);
|
||||
}
|
||||
|
||||
// print_rules();
|
||||
|
||||
handle_distance_errors();
|
||||
verified_branches.clear();
|
||||
|
||||
@ -2020,9 +2024,9 @@ EX void generate_rules() {
|
||||
treestates.clear();
|
||||
hard_parents = single_live_branches = double_live_branches = all_solid_errors = solid_errors = 0;
|
||||
|
||||
next_distance_warning = 512;
|
||||
current_getside = 512;
|
||||
current_examine_branch = 512;
|
||||
next_distance_warning = first_restart_on;
|
||||
current_getside = first_restart_on;
|
||||
current_examine_branch = first_restart_on;
|
||||
|
||||
int NS = isize(arb::current.shapes);
|
||||
shortcuts.resize(NS);
|
||||
@ -2033,6 +2037,7 @@ EX void generate_rules() {
|
||||
cell_to_tcell.clear();
|
||||
tcell_to_cell.clear();
|
||||
branch_conflicts_seen.clear();
|
||||
sidecaches_to_clear.clear();
|
||||
clear_sidecache_and_codes();
|
||||
fix_queue = queue<reaction_t>();; in_fixing = false;
|
||||
|
||||
@ -2374,7 +2379,9 @@ auto hooks = addHook(hooks_configfile, 100, [] {
|
||||
param_i(max_examine_branch, "max_examine_branch");
|
||||
param_i(max_getside, "max_getside");
|
||||
param_i(max_bdata, "max_bdata");
|
||||
param_i(max_shortcut_length, "max_shortcut_length");
|
||||
param_i(rulegen_timeout, "rulegen_timeout");
|
||||
param_i(first_restart_on, "first_restart_on");
|
||||
});
|
||||
|
||||
EX void parse_treestate(arb::arbi_tiling& c, exp_parser& ep) {
|
||||
|
Loading…
Reference in New Issue
Block a user