From e925f6e93ca358896bd4c2d7a73979d5fadb6d45 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Sun, 19 Jan 2020 00:34:38 +0100 Subject: [PATCH] added rewriting to RogueViz --- rogueviz/rewriting.cpp | 140 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 rogueviz/rewriting.cpp diff --git a/rogueviz/rewriting.cpp b/rogueviz/rewriting.cpp new file mode 100644 index 00000000..ff705e3b --- /dev/null +++ b/rogueviz/rewriting.cpp @@ -0,0 +1,140 @@ +// Hyperbolic Rogue -- infinite-order tessellations +// Copyright (C) 2011-2019 Zeno Rogue, see 'hyper.cpp' for details + +/** \file inforder3.cpp + * \brief infinite-order tessellations + * + * very simple + */ + +#include "../hyper.h" + +namespace hr { + +namespace rewriting { + +bool symmetric; + +string start; +vector > rules; + +set find_matches(string s) { + set res; + for(auto& p: rules) { + size_t next = s.find(p.first); + while(next != string::npos) { + res.emplace(s.substr(0, next) + p.second + s.substr(next+isize(p.first))); + next = s.find(p.first, next+1); + } + } + return res; + } + +struct hrmap_rewrite : hrmap_hyperbolic { + + map asg; + map asg_rev; + + heptagon *create_step(heptagon *h, int direction) { + if(h->move(direction)) return h->move(direction); + if(asg.empty()) asg[h] = start; + + auto matches = find_matches(asg[h]); + + int next = (symmetric || h == getOrigin()) ? 0 : 1; + + for(auto& m: matches) { + if(symmetric) { + if(h->move(next)) { next++; continue; } + auto matches1 = find_matches(m); + heptagon *h1; + if(asg_rev[m]) h1 = asg_rev[m]; + else { + h1 = tailored_alloc (isize(matches1)); + h1->alt = NULL; + h1->s = hsA; + h1->cdata = NULL; + h1->distance = 0; + h1->c7 = newCell(isize(matches1), h1); + asg[h1] = m; + asg_rev[m] = h1; + } + int next1 = 0; + for(auto& s: matches1) { if(s == asg[h]) break; next1++; } + h->c.connect(next, h1, next1, false); + } + else { + int deg = 1 + isize(find_matches(m)); + auto h1 = tailored_alloc (deg); + h->c.connect(next, h1, 0, false); + + h1->alt = NULL; + h1->s = hsA; + h1->cdata = NULL; + h1->distance = h->distance + 1; + h1->c7 = newCell(deg, h1); + + asg[h1] = m; + } + next++; + } + + return h->move(direction); + } + + }; + +bool labeller(cell* c, const transmatrix& V) { + auto m = dynamic_cast (currentmap); + if(m) { + string s = m->asg[c->master]; + queuestr(V, 0.5, s, 0xFFFFFF); + } + return false; + } + + +auto hooks = + addHook(hooks_args, 100, [] { + using namespace arg; + + if(0) ; + else if(argis("-rwr")) { + stop_game(); + set_geometry(gInfOrderMixed); + if(PURE) println(hlog, "pure"); + ginf[gInfOrderMixed].distlimit = {1, 1}; + ginf[gInfOrderMixed].flags |= qEXPERIMENTAL; + shift(); + fhstream ss(argcs(), "rt"); + scan(ss, start); + string line; + while(scan(ss, line)) { + auto i = line.find("-"); + if(i != string::npos) { + rules.emplace_back(line.substr(0, i), line.substr(i+1)); + } + } + symmetric = true; + set > checker; + for(auto r: rules) checker.insert(r); + for(auto r: rules) if(!checker.count({r.second, r.first})) { + if(symmetric) println(hlog, "asymmetric rule: ", r); + symmetric = false; + } + ginf[gInfOrderMixed].sides = isize(find_matches(start)); + ginf[gInfOrderMixed].flags |= qANYQ; + } + else return 1; + return 0; + }) + + + addHook(hooks_newmap, 100, [] { + if(geometry == gInfOrderMixed && !rules.empty()) return (hrmap*) new hrmap_rewrite; + return (hrmap*) nullptr; + }) + + + addHook(hooks_drawcell, 100, labeller); + +} +} \ No newline at end of file