mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-30 05:23:00 +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) {  | ||||||
|  |       h->c.connect(0, h, 0, false); | ||||||
|  |       return h; | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |     for(auto& msym: matches) { | ||||||
|  |       if(h->move(next)) { next++; continue; } | ||||||
|  |       bool symmetric = msym.second; | ||||||
|  |       const string& m = msym.first; | ||||||
|       if(symmetric) { |       if(symmetric) { | ||||||
|         if(h->move(next)) { next++; continue; } |  | ||||||
|         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,12 +81,15 @@ 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; | ||||||
|         } |         } | ||||||
|       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
	 Zeno Rogue
					Zeno Rogue