mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-11-01 14:32:59 +00:00
string rewriting puzzle
This commit is contained in:
@@ -17,13 +17,14 @@ bool symmetric;
|
|||||||
|
|
||||||
string start;
|
string start;
|
||||||
vector<pair<string, string> > rules;
|
vector<pair<string, string> > rules;
|
||||||
|
set<pair<string, string> > ruleset;
|
||||||
|
|
||||||
set<string> find_matches(string s) {
|
set<pair<string, bool>> find_matches(string s) {
|
||||||
set<string> res;
|
set<pair<string, bool>> res;
|
||||||
for(auto& p: rules) {
|
for(auto& p: rules) {
|
||||||
size_t next = s.find(p.first);
|
size_t next = s.find(p.first);
|
||||||
while(next != string::npos) {
|
while(next != string::npos) {
|
||||||
res.emplace(s.substr(0, next) + p.second + s.substr(next+isize(p.first)));
|
res.emplace(s.substr(0, next) + p.second + s.substr(next+isize(p.first)), ruleset.count({p.second, p.first}));
|
||||||
next = s.find(p.first, next+1);
|
next = s.find(p.first, next+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,15 +38,22 @@ struct hrmap_rewrite : hrmap_hyperbolic {
|
|||||||
|
|
||||||
heptagon *create_step(heptagon *h, int direction) {
|
heptagon *create_step(heptagon *h, int direction) {
|
||||||
if(h->move(direction)) return h->move(direction);
|
if(h->move(direction)) return h->move(direction);
|
||||||
if(asg.empty()) asg[h] = start;
|
if(asg.empty()) { asg[h] = start; h->zebraval = 0; }
|
||||||
|
|
||||||
auto matches = find_matches(asg[h]);
|
auto matches = find_matches(asg[h]);
|
||||||
|
|
||||||
int next = (symmetric || h == getOrigin()) ? 0 : 1;
|
int next = h->zebraval;
|
||||||
|
|
||||||
for(auto& m: matches) {
|
if(matches.empty() && next == 0) {
|
||||||
if(symmetric) {
|
h->c.connect(0, h, 0, false);
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto& msym: matches) {
|
||||||
if(h->move(next)) { next++; continue; }
|
if(h->move(next)) { next++; continue; }
|
||||||
|
bool symmetric = msym.second;
|
||||||
|
const string& m = msym.first;
|
||||||
|
if(symmetric) {
|
||||||
auto matches1 = find_matches(m);
|
auto matches1 = find_matches(m);
|
||||||
heptagon *h1;
|
heptagon *h1;
|
||||||
if(asg_rev[m]) h1 = asg_rev[m];
|
if(asg_rev[m]) h1 = asg_rev[m];
|
||||||
@@ -54,13 +62,14 @@ struct hrmap_rewrite : hrmap_hyperbolic {
|
|||||||
h1->alt = NULL;
|
h1->alt = NULL;
|
||||||
h1->s = hsA;
|
h1->s = hsA;
|
||||||
h1->cdata = NULL;
|
h1->cdata = NULL;
|
||||||
h1->distance = 0;
|
h1->distance = h->distance;
|
||||||
|
h1->zebraval = 0;
|
||||||
h1->c7 = newCell(isize(matches1), h1);
|
h1->c7 = newCell(isize(matches1), h1);
|
||||||
asg[h1] = m;
|
asg[h1] = m;
|
||||||
asg_rev[m] = h1;
|
asg_rev[m] = h1;
|
||||||
}
|
}
|
||||||
int next1 = 0;
|
int next1 = 0;
|
||||||
for(auto& s: matches1) { if(s == asg[h]) break; next1++; }
|
for(auto& s: matches1) { if(s.first == asg[h]) break; next1++; }
|
||||||
h->c.connect(next, h1, next1, false);
|
h->c.connect(next, h1, next1, false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -72,6 +81,7 @@ struct hrmap_rewrite : hrmap_hyperbolic {
|
|||||||
h1->s = hsA;
|
h1->s = hsA;
|
||||||
h1->cdata = NULL;
|
h1->cdata = NULL;
|
||||||
h1->distance = h->distance + 1;
|
h1->distance = h->distance + 1;
|
||||||
|
h1->zebraval = 1;
|
||||||
h1->c7 = newCell(deg, h1);
|
h1->c7 = newCell(deg, h1);
|
||||||
|
|
||||||
asg[h1] = m;
|
asg[h1] = m;
|
||||||
@@ -79,6 +89,8 @@ struct hrmap_rewrite : hrmap_hyperbolic {
|
|||||||
next++;
|
next++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(next != h->type) { println(hlog, "degree error"); exit(1); }
|
||||||
|
|
||||||
return h->move(direction);
|
return h->move(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,42 +100,68 @@ bool labeller(cell* c, const transmatrix& V) {
|
|||||||
auto m = dynamic_cast<hrmap_rewrite*> (currentmap);
|
auto m = dynamic_cast<hrmap_rewrite*> (currentmap);
|
||||||
if(m) {
|
if(m) {
|
||||||
string s = m->asg[c->master];
|
string s = m->asg[c->master];
|
||||||
queuestr(V, 0.5, s, 0xFFFFFF);
|
queuestr(V, 0.5, s, colortables['j'][c->master->distance+1]);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void load_rules(vector<string> vs) {
|
||||||
|
|
||||||
|
stop_game();
|
||||||
|
set_geometry(gInfOrderMixed);
|
||||||
|
ginf[gInfOrderMixed].distlimit = {1, 1};
|
||||||
|
ginf[gInfOrderMixed].flags |= qEXPERIMENTAL;
|
||||||
|
|
||||||
|
start = "";
|
||||||
|
rules.clear();
|
||||||
|
ruleset.clear();
|
||||||
|
for(string line: vs) {
|
||||||
|
if(line == "") continue;
|
||||||
|
|
||||||
|
auto i = line.find("->");
|
||||||
|
if(i != string::npos) {
|
||||||
|
rules.emplace_back(line.substr(0, i), line.substr(i+2));
|
||||||
|
ruleset.emplace(line.substr(0, i), line.substr(i+2));
|
||||||
|
}
|
||||||
|
else start = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
ginf[gInfOrderMixed].sides = isize(find_matches(start));
|
||||||
|
if(!ginf[gInfOrderMixed].sides) ginf[gInfOrderMixed].sides = 1;
|
||||||
|
ginf[gInfOrderMixed].flags |= qANYQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if ISWEB
|
||||||
|
extern "C" {
|
||||||
|
void load_web_rules() {
|
||||||
|
string s = get_value("rules") + '\n';
|
||||||
|
vector<string> split;
|
||||||
|
string cc = "";
|
||||||
|
for(char c: s) if(c == '\n' || c == '\r') split.push_back(cc), cc = ""; else cc += c;
|
||||||
|
load_rules(split);
|
||||||
|
start_game();
|
||||||
|
clearMessages();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
auto hooks =
|
auto hooks =
|
||||||
addHook(hooks_args, 100, [] {
|
addHook(hooks_args, 100, [] {
|
||||||
using namespace arg;
|
using namespace arg;
|
||||||
|
|
||||||
if(0) ;
|
if(0) ;
|
||||||
|
#if ISWEB
|
||||||
|
else if(argis("-rww")) {
|
||||||
|
load_web_rules();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else if(argis("-rwr")) {
|
else if(argis("-rwr")) {
|
||||||
stop_game();
|
|
||||||
set_geometry(gInfOrderMixed);
|
|
||||||
if(PURE) println(hlog, "pure");
|
|
||||||
ginf[gInfOrderMixed].distlimit = {1, 1};
|
|
||||||
ginf[gInfOrderMixed].flags |= qEXPERIMENTAL;
|
|
||||||
shift();
|
shift();
|
||||||
fhstream ss(argcs(), "rt");
|
fhstream ss(argcs(), "rt");
|
||||||
scan(ss, start);
|
vector<string> vs;
|
||||||
string line;
|
string line;
|
||||||
while(scan(ss, line)) {
|
while(scan(ss, line)) vs.push_back(line);
|
||||||
auto i = line.find("-");
|
load_rules(vs);
|
||||||
if(i != string::npos) {
|
|
||||||
rules.emplace_back(line.substr(0, i), line.substr(i+1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
symmetric = true;
|
|
||||||
set<pair<string, string> > 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;
|
else return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user