diff --git a/arbitrile.cpp b/arbitrile.cpp index e411c9b4..c7bf606b 100644 --- a/arbitrile.cpp +++ b/arbitrile.cpp @@ -71,6 +71,7 @@ struct arbi_tiling { int order; bool have_line, have_ph, have_tree; + int yendor_backsteps; vector shapes; string name; @@ -397,6 +398,7 @@ EX void load(const string& fname, bool after_sliding IS(false)) { c.floor_scale = .5; c.have_ph = c.have_line = false; c.have_tree = false; + c.yendor_backsteps = 0; exp_parser ep; ep.s = s; ld angleunit = 1, distunit = 1, angleofs = 0; @@ -511,6 +513,10 @@ EX void load(const string& fname, bool after_sliding IS(false)) { else if(ep.eat("treestate(")) { rulegen::parse_treestate(c, ep); } + else if(ep.eat("yendor_backsteps(")) { + c.yendor_backsteps = ep.iparse(); + ep.force_eat(")"); + } else if(ep.eat("range(")) { c.range = ep.iparse(); ep.force_eat(")"); diff --git a/expansion.cpp b/expansion.cpp index ac1cf7ba..efbfa271 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -144,6 +144,7 @@ void expansion_analyzer::preliminary_grouping() { void expansion_analyzer::reduce_grouping() { if(reg3::in_rule()) return; + if(currentmap->strict_tree_rules()) return; int old_N = N; vector grouping; grouping.resize(N); @@ -208,6 +209,7 @@ bignum& expansion_analyzer::get_descendants(int level) { } bignum& expansion_analyzer::get_descendants(int level, int type) { + if(!N) preliminary_grouping(), reduce_grouping(); auto& pd = descendants; size_upto(pd, level+1); for(int d=0; d<=level; d++) diff --git a/geometry2.cpp b/geometry2.cpp index ea0b0019..bb04af1a 100644 --- a/geometry2.cpp +++ b/geometry2.cpp @@ -872,6 +872,7 @@ EX pathgen generate_random_path(cellwalker start, int length, bool for_yendor, b int t = -1; bignum full_id; bool onlychild = true; + bool launched = false; cellwalker ycw = start; if(for_yendor) setdist(p.path[0], 7, NULL); @@ -901,6 +902,37 @@ EX pathgen generate_random_path(cellwalker start, int length, bool for_yendor, b if(isize(ds)) ycw += ds[hrand(isize(ds))]; } + else if(currentmap->strict_tree_rules()) { + if(for_yendor && i < arb::current.yendor_backsteps) { + println(hlog, i, " < ", arb::current.yendor_backsteps); + ycw.spin = 0; + } + + else { + if(!launched) { + t = ycw.at->master->fieldval; + bignum b = expansion.get_descendants(length-i, t); + p.full_id_0 = full_id = hrand(b); + /* it may happen that the subtree dies out */ + if(!full_id.approx_int()) goto stupid; + launched = true; + } + + ycw.spin = 0; + + auto& r = rulegen::treestates[t]; + for(int ri=0; ri