mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-07-21 02:12:49 +00:00
arb/rulegen:: trees can now be defined in tes files
This commit is contained in:
parent
0559fce5fb
commit
fa03033c99
@ -70,7 +70,7 @@ struct slider {
|
|||||||
struct arbi_tiling {
|
struct arbi_tiling {
|
||||||
|
|
||||||
int order;
|
int order;
|
||||||
bool have_line, have_ph;
|
bool have_line, have_ph, have_tree;
|
||||||
|
|
||||||
vector<shape> shapes;
|
vector<shape> shapes;
|
||||||
string name;
|
string name;
|
||||||
@ -212,7 +212,7 @@ void shape::build_from_angles_edges() {
|
|||||||
for(auto& v: vertices) v = gpushxto0(ctr) * v;
|
for(auto& v: vertices) v = gpushxto0(ctr) * v;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool correct_index(int index, int size) { return index >= 0 && index < size; }
|
EX bool correct_index(int index, int size) { return index >= 0 && index < size; }
|
||||||
template<class T> bool correct_index(int index, const T& v) { return correct_index(index, isize(v)); }
|
template<class T> bool correct_index(int index, const T& v) { return correct_index(index, isize(v)); }
|
||||||
|
|
||||||
template<class T> void verify_index(int index, const T& v, exp_parser& ep) { if(!correct_index(index, v)) throw hr_parse_exception("bad index: " + its(index) + " at " + ep.where()); }
|
template<class T> void verify_index(int index, const T& v, exp_parser& ep) { if(!correct_index(index, v)) throw hr_parse_exception("bad index: " + its(index) + " at " + ep.where()); }
|
||||||
@ -395,6 +395,8 @@ EX void load(const string& fname, bool after_sliding IS(false)) {
|
|||||||
c.range = 0;
|
c.range = 0;
|
||||||
c.boundary_ratio = 1;
|
c.boundary_ratio = 1;
|
||||||
c.floor_scale = .5;
|
c.floor_scale = .5;
|
||||||
|
c.have_ph = c.have_line = false;
|
||||||
|
c.have_tree = 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;
|
||||||
@ -506,6 +508,9 @@ EX void load(const string& fname, bool after_sliding IS(false)) {
|
|||||||
c.cscale = ep.rparse();
|
c.cscale = ep.rparse();
|
||||||
ep.force_eat(")");
|
ep.force_eat(")");
|
||||||
}
|
}
|
||||||
|
else if(ep.eat("treestate(")) {
|
||||||
|
rulegen::parse_treestate(c, ep);
|
||||||
|
}
|
||||||
else if(ep.eat("range(")) {
|
else if(ep.eat("range(")) {
|
||||||
c.range = ep.iparse();
|
c.range = ep.iparse();
|
||||||
ep.force_eat(")");
|
ep.force_eat(")");
|
||||||
@ -639,8 +644,10 @@ EX void load(const string& fname, bool after_sliding IS(false)) {
|
|||||||
|
|
||||||
if(do_unmirror) {
|
if(do_unmirror) {
|
||||||
unmirror();
|
unmirror();
|
||||||
compute_vertex_valence();
|
|
||||||
}
|
}
|
||||||
|
if(!c.have_tree) compute_vertex_valence();
|
||||||
|
|
||||||
|
if(c.have_tree) rulegen::verify_parsed_treestates();
|
||||||
|
|
||||||
if(!after_sliding) slided = current;
|
if(!after_sliding) slided = current;
|
||||||
}
|
}
|
||||||
@ -708,7 +715,7 @@ void connection_debugger() {
|
|||||||
|
|
||||||
dialog::add_action([k, last, con] {
|
dialog::add_action([k, last, con] {
|
||||||
if(euclid) cgflags |= qAFFINE;
|
if(euclid) cgflags |= qAFFINE;
|
||||||
debug_polys.emplace_back(last.first * get_adj(debugged, last.second, k, -1), con.sid);
|
debug_polys.emplace_back(last.first * get_adj(debugged, last.second, k, -1, -1), con.sid);
|
||||||
if(euclid) cgflags &= ~qAFFINE;
|
if(euclid) cgflags &= ~qAFFINE;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -742,7 +749,7 @@ EX hrmap *current_altmap;
|
|||||||
|
|
||||||
heptagon *build_child(heptspin p, pair<int, int> adj);
|
heptagon *build_child(heptspin p, pair<int, int> adj);
|
||||||
|
|
||||||
EX transmatrix get_adj(arbi_tiling& c, int t, int dl, int xdl) {
|
EX transmatrix get_adj(arbi_tiling& c, int t, int dl, int t1, int xdl) {
|
||||||
|
|
||||||
auto& sh = c.shapes[t];
|
auto& sh = c.shapes[t];
|
||||||
|
|
||||||
@ -751,7 +758,9 @@ EX transmatrix get_adj(arbi_tiling& c, int t, int dl, int xdl) {
|
|||||||
auto& co = sh.connections[dl];
|
auto& co = sh.connections[dl];
|
||||||
if(xdl == -1) xdl = co.eid;
|
if(xdl == -1) xdl = co.eid;
|
||||||
|
|
||||||
auto& xsh = c.shapes[co.sid];
|
if(t1 == -1) t1 = co.sid;
|
||||||
|
|
||||||
|
auto& xsh = c.shapes[t1];
|
||||||
int xdr = gmod(xdl+1, xsh.size());
|
int xdr = gmod(xdl+1, xsh.size());
|
||||||
|
|
||||||
hyperpoint vl = sh.vertices[dl];
|
hyperpoint vl = sh.vertices[dl];
|
||||||
@ -836,7 +845,7 @@ struct hrmap_arbi : hrmap {
|
|||||||
void verify() override { }
|
void verify() override { }
|
||||||
|
|
||||||
transmatrix adj(heptagon *h, int dl) override {
|
transmatrix adj(heptagon *h, int dl) override {
|
||||||
return get_adj(current_or_slided(), id_of(h), dl, h->c.move(dl) ? h->c.spin(dl) : -1);
|
return get_adj(current_or_slided(), id_of(h), dl, -1, h->c.move(dl) ? h->c.spin(dl) : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
heptagon *create_step(heptagon *h, int d) override {
|
heptagon *create_step(heptagon *h, int d) override {
|
||||||
|
@ -68,7 +68,7 @@ struct hrmap_testproto : hrmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
transmatrix adj(heptagon *h, int dir) override {
|
transmatrix adj(heptagon *h, int dir) override {
|
||||||
return arb::get_adj(arb::current_or_slided(), shvid(h->c7), dir, h->c.move(dir) ? h->c.spin(dir) : -1);
|
return arb::get_adj(arb::current_or_slided(), shvid(h->c7), dir, -1, h->c.move(dir) ? h->c.spin(dir) : -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int shvid(cell *c) override {
|
int shvid(cell *c) override {
|
||||||
|
52
rulegen.cpp
52
rulegen.cpp
@ -299,6 +299,7 @@ void calc_distances(tcell *c) {
|
|||||||
|
|
||||||
void prepare_around(tcell *c) {
|
void prepare_around(tcell *c) {
|
||||||
vector<tcell*> q;
|
vector<tcell*> q;
|
||||||
|
|
||||||
set<tcell*> visited;
|
set<tcell*> visited;
|
||||||
auto visit = [&] (tcell *x) {
|
auto visit = [&] (tcell *x) {
|
||||||
if(visited.count(x)) return;
|
if(visited.count(x)) return;
|
||||||
@ -1433,19 +1434,21 @@ struct hrmap_rulegen : hrmap {
|
|||||||
|
|
||||||
transmatrix adj(heptagon *h, int dir) override {
|
transmatrix adj(heptagon *h, int dir) override {
|
||||||
if(h->fieldval == -1)
|
if(h->fieldval == -1)
|
||||||
return arb::get_adj(arb::current_or_slided(), h->zebraval, dir, -1);
|
return arb::get_adj(arb::current_or_slided(), h->zebraval, dir, -1, -1);
|
||||||
|
|
||||||
int s = h->fieldval;
|
int s = h->fieldval;
|
||||||
int dir0 = get_arb_dir(s, dir);
|
int dir0 = get_arb_dir(s, dir);
|
||||||
|
|
||||||
int dir1 = -1;
|
int dir1 = -1;
|
||||||
|
int sid1 = -1;
|
||||||
|
|
||||||
if(h->c.move(dir)) {
|
if(h->c.move(dir)) {
|
||||||
int s1 = h->c.move(dir)->fieldval;
|
auto s1 = h->c.move(dir)->fieldval;
|
||||||
dir1 = get_arb_dir(s1, h->c.spin(dir));
|
dir1 = get_arb_dir(s1, h->c.spin(dir));
|
||||||
|
sid1 = treestates[s1].sid;
|
||||||
}
|
}
|
||||||
|
|
||||||
return arb::get_adj(arb::current_or_slided(), treestates[s].sid, dir0, dir1);
|
return arb::get_adj(arb::current_or_slided(), treestates[s].sid, dir0, sid1, dir1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int shvid(cell *c) override {
|
int shvid(cell *c) override {
|
||||||
@ -1526,7 +1529,7 @@ string rules_known_for = "unknown";
|
|||||||
string rule_status;
|
string rule_status;
|
||||||
|
|
||||||
EX bool known() {
|
EX bool known() {
|
||||||
return rules_known_for == arb::current.name;
|
return arb::current.have_tree || rules_known_for == arb::current.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX bool prepare_rules() {
|
EX bool prepare_rules() {
|
||||||
@ -1583,5 +1586,46 @@ auto hooks =
|
|||||||
param_i(dlbonus, "dlbonus");
|
param_i(dlbonus, "dlbonus");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
EX void parse_treestate(arb::arbi_tiling& c, exp_parser& ep) {
|
||||||
|
if(!c.have_tree) {
|
||||||
|
c.have_tree = true;
|
||||||
|
treestates.clear();
|
||||||
|
rule_root = 0;
|
||||||
|
}
|
||||||
|
treestates.emplace_back();
|
||||||
|
auto& ts = treestates.back();
|
||||||
|
ts.id = isize(treestates) - 1;
|
||||||
|
|
||||||
|
ts.sid = ep.iparse();
|
||||||
|
ts.parent_dir = 0;
|
||||||
|
if(!arb::correct_index(ts.sid, isize(c.shapes)))
|
||||||
|
throw hr_parse_exception("incorrect treestate index at " + ep.where());
|
||||||
|
|
||||||
|
int N = c.shapes[ts.sid].size();
|
||||||
|
for(int i=0; i<N; i++) {
|
||||||
|
ep.force_eat(","); ep.skip_white();
|
||||||
|
if(ep.eat("PARENT")) ts.rules.push_back(DIR_PARENT);
|
||||||
|
else if(ep.eat("LEFT")) ts.rules.push_back(DIR_LEFT);
|
||||||
|
else if(ep.eat("RIGHT")) ts.rules.push_back(DIR_RIGHT);
|
||||||
|
else { int i = ep.iparse(); ts.rules.push_back(i); }
|
||||||
|
}
|
||||||
|
ep.force_eat(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
EX void verify_parsed_treestates() {
|
||||||
|
println(hlog, arb::current.shapes[0].connections);
|
||||||
|
println(hlog, arb::current.shapes[1].connections);
|
||||||
|
println(hlog, arb::current.shapes[0].stretch_shear);
|
||||||
|
for(auto& ts: treestates) println(hlog, ts.rules);
|
||||||
|
for(auto& ts: treestates) for(auto& r: ts.rules) {
|
||||||
|
if(r < 0 && !among(r, DIR_PARENT, DIR_LEFT, DIR_RIGHT))
|
||||||
|
throw hr_parse_exception("negative number in treestates");
|
||||||
|
if(r > isize(treestates))
|
||||||
|
throw hr_parse_exception("undefined treestate");
|
||||||
|
}
|
||||||
|
for(auto& sh: arb::current.shapes) sh.cycle_length = sh.size();
|
||||||
|
find_possible_parents();
|
||||||
|
}
|
||||||
|
|
||||||
EX }
|
EX }
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user