1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-26 18:10:35 +00:00

Merge branch 'zenorogue:master' into main

This commit is contained in:
Charlotte Peppers 2022-02-01 09:23:13 -07:00 committed by GitHub
commit 0a9d671bd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 135 additions and 28 deletions

View File

@ -49,7 +49,7 @@ struct shape {
/** list of edge connections */ /** list of edge connections */
vector<connection_t> connections; vector<connection_t> connections;
int size() const { return isize(vertices); } 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<int, int> > sublines;
vector<pair<ld, ld>> stretch_shear; vector<pair<ld, ld>> stretch_shear;
int repeat_value; int repeat_value;
@ -74,7 +74,17 @@ struct slider {
struct arbi_tiling { struct arbi_tiling {
int order; 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; int yendor_backsteps;
vector<shape> shapes; vector<shape> shapes;
@ -187,7 +197,7 @@ void start_poly_debugger(hr_polygon_error& err) {
#endif #endif
} }
void shape::build_from_angles_edges() { void shape::build_from_angles_edges(bool is_comb) {
transmatrix at = Id; transmatrix at = Id;
vertices.clear(); vertices.clear();
int n = isize(angles); int n = isize(angles);
@ -202,6 +212,8 @@ void shape::build_from_angles_edges() {
at = at * xpush(edges[i]) * spin(angles[i]); at = at * xpush(edges[i]) * spin(angles[i]);
} }
matrices.push_back(at); matrices.push_back(at);
if(!legacy) for(auto& a: angles) a -= M_PI;
if(is_comb) return;
if(!eqmatrix(at, Id)) { if(!eqmatrix(at, Id)) {
throw hr_polygon_error(matrices, id, at); 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(debugflags & DF_GEOM) println(hlog, "ctr = ", ctr);
} }
if(!legacy) for(auto& a: angles) a -= M_PI;
ctr = normalize(ctr); ctr = normalize(ctr);
for(auto& v: vertices) v = gpushxto0(ctr) * v; 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 )"); else throw hr_parse_exception("expecting , or )");
} }
try { try {
cc.build_from_angles_edges(); cc.build_from_angles_edges(c.is_combinatorial);
} }
catch(hr_parse_exception& ex) { catch(hr_parse_exception& ex) {
throw hr_parse_exception(ex.s + ep.where()); 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.have_tree = false;
c.yendor_backsteps = 0; c.yendor_backsteps = 0;
c.is_star = false; c.is_star = false;
c.is_combinatorial = false;
exp_parser ep; exp_parser ep;
ep.s = s; ep.s = s;
ld angleunit = 1, distunit = 1, angleofs = 0; 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.")) { else if(ep.eat("star.")) {
c.is_star = true; c.is_star = true;
} }
else if(ep.eat("combinatorial.")) {
c.is_combinatorial = true;
}
else if(ep.eat("option(\"")) { else if(ep.eat("option(\"")) {
next: next:
string s = ""; 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(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, "s1 = ", kz(spintox(rm*vr)), " s2 = ", kz(rspintox(xrm*xvr)));
println(hlog, tie(t, dl), " = ", kz(Res)); println(hlog, tie(t, dl), " = ", kz(Res));
println(hlog, hdist(vl, Res * xvr), " # ", hdist(vr, Res * xvl)); println(hlog, hdist(vl, Res * xvr), " # ", hdist(vr, Res * xvl));

View File

@ -184,6 +184,43 @@ void move_to(twalker dw) {
move_to(cellwalker(m->clone(dw.at)->c7, dw.spin, dw.mirrored)); 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() { void debug_menu() {
cmode = sm::SIDE | sm::MAYDARK; cmode = sm::SIDE | sm::MAYDARK;
gamescreen(0); gamescreen(0);
@ -266,6 +303,33 @@ void debug_menu() {
dialog::addItem("irradiate x10", 'I'); dialog::addItem("irradiate x10", 'I');
dialog::add_action([] { for(int i=0; i<10; i++) irradiate(); }); 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::addItem("name", 'n');
dialog::add_action([m] { println(hlog, "name = ", index_pointer(m->counterpart[cwt.at->master])); }); 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)); auto label = (tc->dist == MYSTERY ? "?" : its(tc->dist));
if(show_codes) { if(show_codes) {
string code = (tc->code == MYSTERY ? "?" : its(tc->code)); int code = tc->code;
if(show_dist) label = label + "/" + code; if(code != MYSTERY_LARGE) code = all_analyzers[code]->dir;
else label = code; 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; 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"); 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) { void test_current(string tesname) {
disable_bigstuff = true; 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 'U': Out("vshapes;vverts;vedges;ushapes;uverts;uedges;xea;xeb;xec", count_uniform());
case 'L': Out("mirror_rules", arb::current.mirror_rules); case 'L': Out("mirror_rules", arb::current.mirror_rules);
case 'B': Out("listshape;listvalence", format("%lld;%lld", get_shapelist(), get_valence_list())); 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 'f': Out("file", tesname);
case 'l': Out("shortcut", longest_shortcut()); 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)"); // 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; if(status != "ACC") treestates = alt_treestates;
/* for(auto& a: analyzers) /* for(auto& a: analyzers)
println(hlog, "analyzer ", a.first, " size is ", isize(a.second.spread)); */ 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) exit(0);
if(forked && id == 1) stop_game(); if(forked && id == 1) stop_game();
} }
while(children) { int pid; wait(&pid); children--; }
} }
void rulecat(string list) { void rulecat(string list) {
@ -1404,6 +1483,10 @@ int testargs() {
} }
} }
else if(argis("-veb")) {
view_examine_branch = true;
}
else if(argis("-dseek")) { else if(argis("-dseek")) {
shift(); shift();
int i = argi(); int i = argi();

View File

@ -50,7 +50,7 @@ struct hpcshape {
#define SIDE_BSHA 12 #define SIDE_BSHA 12
#define SIDEPARS 13 #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 #ifndef GOLDBERG_BITS
#define GOLDBERG_BITS 5 #define GOLDBERG_BITS 5

View File

@ -1171,10 +1171,12 @@ EX void apply_other_model(shiftpoint H_orig, hyperpoint& ret, eModel md) {
// 4 pi / 2pi = M_PI // 4 pi / 2pi = M_PI
if(pmodel == mdEquivolume) if(md == mdEquivolume)
d = pow(volume_auto(d), 1/3.) * pow(M_PI / 2, 1/3.); 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 = sqrt(2*(1 - cos(d))) * M_PI / 2;
//d = sin((d+90*degree)/2);
}
else if(pmodel == mdEquiarea && hyperbolic) else if(pmodel == mdEquiarea && hyperbolic)
d = sqrt(2*(cosh(d) - 1)) / 1.5; d = sqrt(2*(cosh(d) - 1)) / 1.5;

View File

@ -1551,7 +1551,7 @@ EX map<char, colortable> colortables = {
0xFFFF80, 0xC040C0, 0xFFD500, 0x000080, 0xFFFF80, 0xC040C0, 0xFFD500, 0x000080,
0x404040, 0x606060, 0x808080 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 }}, {'e', {0x404040, 0x1800000, 0x1008000, 0x000080 }},
{'b', {0x404040, 0x1800000, 0x1008000, 0x000080 }}, {'b', {0x404040, 0x1800000, 0x1008000, 0x000080 }},
{'z', {0x1C0C0C0, 0x1E0E0E0, 0x404040, 0x606060 }}, {'z', {0x1C0C0C0, 0x1E0E0E0, 0x404040, 0x606060 }},

View File

@ -19,6 +19,8 @@ EX int max_examine_branch = 5040;
EX int max_bdata = 1000; EX int max_bdata = 1000;
EX int max_getside = 10000; EX int max_getside = 10000;
EX int rulegen_timeout = 60; EX int rulegen_timeout = 60;
EX int max_shortcut_length = 1200;
EX int first_restart_on = 512;
#if HDR #if HDR
/** exception thrown by this algoritm in case of any problems */ /** 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) 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); 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 }; debuglist = { c };
throw rulegen_failure("shortcut too long"); throw rulegen_failure("shortcut too long");
} }
@ -1215,10 +1217,11 @@ int get_side(twalker what) {
bool gl = wl.at->dist <= wr.at->dist; bool gl = wl.at->dist <= wr.at->dist;
bool gr = wl.at->dist >= wr.at->dist; bool gr = wl.at->dist >= wr.at->dist;
if(gl) { if(gl) {
if(get_sidecache(wl) == 1) wl += wstep; if(side && get_sidecache(wl) == 1) wl += wstep;
treewalk(wl, -1); treewalk(wl, -1);
if(wl == to_what) { res = 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(lstack.back(), 1);
set_sidecache(wl, -1); set_sidecache(wl, -1);
lstack.pop_back(); 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); else if(wl.at->parent_dir != wl.spin && (wl+wstep).at->parent_dir != (wl+wstep).spin) lstack.push_back(wl);
} }
if(gr) { if(gr) {
if(get_sidecache(wr) == -1) wr += wstep; if(side && get_sidecache(wr) == -1) wr += wstep;
treewalk(wr, +1); treewalk(wr, +1);
if(wr == to_what) {res = -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(rstack.back(), -1);
set_sidecache(wr, +1); set_sidecache(wr, +1);
rstack.pop_back(); rstack.pop_back();
@ -1243,7 +1247,7 @@ int get_side(twalker what) {
return res; return res;
} }
int move_code(twalker cs) { EX int move_code(twalker cs) {
bool child = false; bool child = false;
if(cs.at->dist) { if(cs.at->dist) {
auto csd = get_parent_dir(cs); auto csd = get_parent_dir(cs);
@ -1631,6 +1635,8 @@ void verified_treewalk(twalker& tw, int id, int dir) {
treewalk(tw, dir); treewalk(tw, dir);
} }
EX bool view_examine_branch = false;
bool 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;
@ -1672,7 +1678,7 @@ bool examine_branch(int id, int left, int right) {
auto rl = get_rule(wl, tsl); auto rl = get_rule(wl, tsl);
auto rr = get_rule(wr, tsr); 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); 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()) { 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); push_deadstack(hash, wl, tsl, -1);
hash.emplace_back(-1, wl.at->dist - wr.at->dist); hash.emplace_back(-1, wl.at->dist - wr.at->dist);
push_deadstack(hash, wr, tsr, +1); 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); println(hlog, "got hash: ", hash);
if(verified_branches.count(hash)) { if(verified_branches.count(hash)) {
return true; return true;
@ -1866,8 +1872,6 @@ EX void rules_iteration() {
println(hlog, "deadend states found: ", new_deadends); println(hlog, "deadend states found: ", new_deadends);
} }
// print_rules();
handle_distance_errors(); handle_distance_errors();
verified_branches.clear(); verified_branches.clear();
@ -2020,9 +2024,9 @@ EX void generate_rules() {
treestates.clear(); treestates.clear();
hard_parents = single_live_branches = double_live_branches = all_solid_errors = solid_errors = 0; hard_parents = single_live_branches = double_live_branches = all_solid_errors = solid_errors = 0;
next_distance_warning = 512; next_distance_warning = first_restart_on;
current_getside = 512; current_getside = first_restart_on;
current_examine_branch = 512; current_examine_branch = first_restart_on;
int NS = isize(arb::current.shapes); int NS = isize(arb::current.shapes);
shortcuts.resize(NS); shortcuts.resize(NS);
@ -2033,6 +2037,7 @@ EX void generate_rules() {
cell_to_tcell.clear(); cell_to_tcell.clear();
tcell_to_cell.clear(); tcell_to_cell.clear();
branch_conflicts_seen.clear(); branch_conflicts_seen.clear();
sidecaches_to_clear.clear();
clear_sidecache_and_codes(); clear_sidecache_and_codes();
fix_queue = queue<reaction_t>();; in_fixing = false; 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_examine_branch, "max_examine_branch");
param_i(max_getside, "max_getside"); param_i(max_getside, "max_getside");
param_i(max_bdata, "max_bdata"); param_i(max_bdata, "max_bdata");
param_i(max_shortcut_length, "max_shortcut_length");
param_i(rulegen_timeout, "rulegen_timeout"); 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) { EX void parse_treestate(arb::arbi_tiling& c, exp_parser& ep) {

View File

@ -2998,7 +2998,7 @@ bool celldrawer::draw_shmup_monster() {
bool ths = subscreens::is_current_player(m->pid); bool ths = subscreens::is_current_player(m->pid);
if(!ths || !h) { if(!ths || !h) {
drawPlayerEffects(view, c, true); drawPlayerEffects(view, c, m->type);
if(WDIM == 3) { if(WDIM == 3) {
if(prod) { if(prod) {
hyperpoint h = m->ori * C0; // ztangent(1) hyperpoint h = m->ori * C0; // ztangent(1)