mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	simpler multi-connection system
This commit is contained in:
		
							
								
								
									
										104
									
								
								rulegen.cpp
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								rulegen.cpp
									
									
									
									
									
								
							| @@ -719,6 +719,7 @@ struct treestate { | |||||||
|   int id; |   int id; | ||||||
|   bool known; |   bool known; | ||||||
|   vector<int> rules; |   vector<int> rules; | ||||||
|  |   vector<int> sub_status; // 1 if DIR_LEFT or DIR_RIGHT and connected to a child | ||||||
|   twalker giver; |   twalker giver; | ||||||
|   int sid; |   int sid; | ||||||
|   int parent_dir; |   int parent_dir; | ||||||
| @@ -891,10 +892,6 @@ struct mismatch_error : rulegen_retry { | |||||||
|   mismatch_error() : rulegen_retry("mismatch error") {} |   mismatch_error() : rulegen_retry("mismatch error") {} | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| struct double_edges: rulegen_surrender { |  | ||||||
|   double_edges() : rulegen_surrender("double edges detected") {} |  | ||||||
|   }; |  | ||||||
|  |  | ||||||
| EX int rule_root; | EX int rule_root; | ||||||
|  |  | ||||||
| vector<int> gen_rule(twalker cwmain); | vector<int> gen_rule(twalker cwmain); | ||||||
| @@ -907,8 +904,6 @@ vector<tcell*> cq; | |||||||
| #if HDR | #if HDR | ||||||
| /* special codes */ | /* special codes */ | ||||||
| static const int DIR_UNKNOWN = -1; | static const int DIR_UNKNOWN = -1; | ||||||
| static const int DIR_MULTI_GO_LEFT = -2; |  | ||||||
| static const int DIR_MULTI_GO_RIGHT = -3; |  | ||||||
| static const int DIR_LEFT = -4; | static const int DIR_LEFT = -4; | ||||||
| static const int DIR_RIGHT = -5; | static const int DIR_RIGHT = -5; | ||||||
| static const int DIR_PARENT = -6; | static const int DIR_PARENT = -6; | ||||||
| @@ -1107,7 +1102,6 @@ struct bad_tree : rulegen_retry { | |||||||
|  |  | ||||||
| bool equiv(twalker w1, twalker w2); | bool equiv(twalker w1, twalker w2); | ||||||
|  |  | ||||||
| inline bool IS_DIR_MULTI(int d) { return among(d, DIR_MULTI_GO_LEFT, DIR_MULTI_GO_RIGHT); } |  | ||||||
| struct branchdata { | struct branchdata { | ||||||
|   int id; |   int id; | ||||||
|   int dir; |   int dir; | ||||||
| @@ -1133,11 +1127,6 @@ struct branchdata { | |||||||
|     dir += i; |     dir += i; | ||||||
|     dir = gmod(dir, isize(treestates[id].rules)); |     dir = gmod(dir, isize(treestates[id].rules)); | ||||||
|     } |     } | ||||||
|   void spin_full(int i) { |  | ||||||
|     spin(i); |  | ||||||
|     while(IS_DIR_MULTI(treestates[id].rules[dir])) |  | ||||||
|       spin(i); |  | ||||||
|     } |  | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| inline void print(hstream& hs, const branchdata& bd) { print(hs, "[", bd.id,":",bd.dir, " ", bd.at, ":", bd.temporary, "]"); } | inline void print(hstream& hs, const branchdata& bd) { print(hs, "[", bd.id,":",bd.dir, " ", bd.at, ":", bd.temporary, "]"); } | ||||||
| @@ -1145,28 +1134,20 @@ inline void print(hstream& hs, const branchdata& bd) { print(hs, "[", bd.id,":", | |||||||
| /* we need to be careful with multiple edges */ | /* we need to be careful with multiple edges */ | ||||||
|  |  | ||||||
| bool paired(twalker w1, twalker w2) { | bool paired(twalker w1, twalker w2) { | ||||||
|   if(w1 + wstep == w2) return true; |   return w1 + wstep == w2; | ||||||
|   if(w1.cpeek() == w2.at && w2.cpeek() == w1.at) { |  | ||||||
|     return true; |  | ||||||
|     } |  | ||||||
|   return false; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| bool equiv(twalker w1, twalker w2) { | bool equiv(twalker w1, twalker w2) { | ||||||
|   if(w1 == w2) return true; |   return w1 == w2; | ||||||
|   if(w1.at == w2.at && w1.cpeek() == w2.cpeek()) { |  | ||||||
|     return true; |  | ||||||
|     } |  | ||||||
|   return false; |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
| void advance(vector<branchdata>& bdata, branchdata at, int dir, bool start_forward, bool stack, int distlimit) { | void advance(vector<branchdata>& bdata, branchdata at, int dir, bool start_forward, bool stack, int distlimit) { | ||||||
|   if(start_forward) { |   if(start_forward) { | ||||||
|     at.step(); |     at.step(); | ||||||
|     at.spin_full(dir); |     at.spin(dir); | ||||||
|     } |     } | ||||||
|   else { |   else { | ||||||
|     at.spin_full(dir); |     at.spin(dir); | ||||||
|     } |     } | ||||||
|   vector<branchdata> b; |   vector<branchdata> b; | ||||||
|   int steps = 0; |   int steps = 0; | ||||||
| @@ -1175,7 +1156,13 @@ void advance(vector<branchdata>& bdata, branchdata at, int dir, bool start_forwa | |||||||
|       throw rulegen_failure("max_adv_steps exceeded"); |       throw rulegen_failure("max_adv_steps exceeded"); | ||||||
|     auto& ts = treestates[at.id]; |     auto& ts = treestates[at.id]; | ||||||
|     auto r = ts.rules[at.dir]; |     auto r = ts.rules[at.dir]; | ||||||
|     if(r < 0) { |     if(ts.sub_status[at.dir]) { | ||||||
|  |       at.temporary = 0; | ||||||
|  |       b.push_back(at); | ||||||
|  |       b.push_back(at); | ||||||
|  |       at.spin(dir); | ||||||
|  |       } | ||||||
|  |     else if(r < 0) { | ||||||
|       at.temporary = 0; |       at.temporary = 0; | ||||||
|       b.push_back(at); |       b.push_back(at); | ||||||
|       break; |       break; | ||||||
| @@ -1186,11 +1173,11 @@ void advance(vector<branchdata>& bdata, branchdata at, int dir, bool start_forwa | |||||||
|         b.pop_back(); |         b.pop_back(); | ||||||
|       else |       else | ||||||
|         advance(b, at, -dir, true, true, distlimit); |         advance(b, at, -dir, true, true, distlimit); | ||||||
|       at.spin_full(dir); |       at.spin(dir); | ||||||
|       } |       } | ||||||
|     else { |     else { | ||||||
|       at.step(); |       at.step(); | ||||||
|       if(at.at.at->dist < distlimit || !ts.is_live) at.spin_full(dir); |       if(at.at.at->dist < distlimit || !ts.is_live) at.spin(dir); | ||||||
|       else { |       else { | ||||||
|         at.temporary = dir; |         at.temporary = dir; | ||||||
|         b.push_back(at); |         b.push_back(at); | ||||||
| @@ -1207,7 +1194,8 @@ void advance(vector<branchdata>& bdata, branchdata at, int dir, bool start_forwa | |||||||
|   } |   } | ||||||
|  |  | ||||||
| void verify_lr(branchdata bd, int dir) { | void verify_lr(branchdata bd, int dir) { | ||||||
|   if(dir) { bd.spin_full(dir); if(bd.dir == 0) bd.dir = bd.at.at->type; } |   return; | ||||||
|  |   if(dir) { bd.spin(dir); if(bd.dir == 0) bd.dir = bd.at.at->type; } | ||||||
|   auto& r = treestates[bd.id].rules; |   auto& r = treestates[bd.id].rules; | ||||||
|   for(int i=0; i<isize(r); i++) { |   for(int i=0; i<isize(r); i++) { | ||||||
|     int val = i < bd.dir ? DIR_LEFT : DIR_RIGHT; |     int val = i < bd.dir ? DIR_LEFT : DIR_RIGHT; | ||||||
| @@ -1225,25 +1213,26 @@ void examine_branch(int id, int left, int right) { | |||||||
|   auto rg = treestates[id].giver; |   auto rg = treestates[id].giver; | ||||||
|   if(debugflags & DF_GEOM) |   if(debugflags & DF_GEOM) | ||||||
|     println(hlog, "need to examine branches ", tie(left, right), " of ", id, " starting from ", rg); |     println(hlog, "need to examine branches ", tie(left, right), " of ", id, " starting from ", rg); | ||||||
|  |   indenter ind(2); | ||||||
|   vector<branchdata> bdata; |   vector<branchdata> bdata; | ||||||
|   int dist_at = rg.at->dist; |   int dist_at = rg.at->dist; | ||||||
|  |  | ||||||
|   do { |   do { | ||||||
|     /* can be false in case of multi-edges */ |     if(true) { | ||||||
|     if(treestates[id].rules[left] >= 0) {       |       auto bl = branchdata{id, left, rg+left, dist_at+dlbonus}; | ||||||
|  |       bl.temporary = 0; | ||||||
|       if(bdata.size() && bdata.back().dir == 0) |       if(treestates[id].rules[left] >= 0) | ||||||
|         bdata.pop_back(); |  | ||||||
|       else { |  | ||||||
|         auto bl = branchdata{id, left, rg+left, dist_at+dlbonus}; |  | ||||||
|         advance(bdata, bl, -1, true, true, dist_at+5); |         advance(bdata, bl, -1, true, true, dist_at+5); | ||||||
|         } |       else bdata.push_back(bl); | ||||||
|       } |       } | ||||||
|     left++; |     left++; | ||||||
|     if(left == rg.at->type) left = 0; |     if(left == rg.at->type) left = 0; | ||||||
|     if(treestates[id].rules[left] >= 0) { |     if(true) { | ||||||
|       auto br = branchdata{id, left, rg+left, dist_at+dlbonus}; |       auto br = branchdata{id, left, rg+left, dist_at+dlbonus}; | ||||||
|       advance(bdata, br, +1, true, false, dist_at+5); |       br.temporary = 0; | ||||||
|  |       if(treestates[id].rules[left] >= 0) | ||||||
|  |         advance(bdata, br, +1, true, false, dist_at+5); | ||||||
|  |       else bdata.push_back(br); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|   while(left != right); |   while(left != right); | ||||||
| @@ -1340,6 +1329,23 @@ void find_single_live_branch(twalker at) { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | void find_sub_status() { | ||||||
|  |   for(int id=0; id<isize(treestates); id++)  | ||||||
|  |     treestates[id].sub_status.resize(isize(treestates[id].rules), 0); | ||||||
|  |  | ||||||
|  |   for(int id=0; id<isize(treestates); id++) { | ||||||
|  |     auto& ts = treestates[id]; | ||||||
|  |     for(int im=0; im<isize(ts.rules); im++) | ||||||
|  |     if(ts.rules[im] >= 0 || ts.rules[im] == DIR_PARENT) | ||||||
|  |     for(int i=0; i<isize(ts.rules); i++) if(i != im) { | ||||||
|  |       if((ts.giver+im).peek() == (ts.giver+i).peek()) { | ||||||
|  |         println(hlog, "found multi connection at ", id, ":", i, " equals ", im, ts.rules[im] == DIR_PARENT ? " [parent]" : " [child]"); | ||||||
|  |         ts.sub_status[i] = 1; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
| void rules_iteration() { | void rules_iteration() { | ||||||
|   clear_codes(); |   clear_codes(); | ||||||
|    |    | ||||||
| @@ -1394,25 +1400,15 @@ void rules_iteration() { | |||||||
|     } |     } | ||||||
|    |    | ||||||
|   for(int id=0; id<isize(treestates); id++) { |   for(int id=0; id<isize(treestates); id++) { | ||||||
|     auto& rg = treestates[id].giver; |  | ||||||
|     auto& r = treestates[id].rules; |     auto& r = treestates[id].rules; | ||||||
|  |  | ||||||
|     for(int p=0; p<2; p++) |  | ||||||
|     for(int it=0; it<isize(r); it++) { |  | ||||||
|       for(int i=0; i<isize(r); i++) { |  | ||||||
|         int i1 = gmod(i+1, isize(r)); |  | ||||||
|         if((rg+i).peek() == (rg+i1).peek()) { |  | ||||||
|           if(r[i1] == DIR_UNKNOWN && (r[i] >= (p?DIR_UNKNOWN:0) || r[i] == DIR_PARENT || r[i] == DIR_MULTI_GO_LEFT)) |  | ||||||
|             r[i1] = DIR_MULTI_GO_LEFT; |  | ||||||
|           if(r[i] == DIR_UNKNOWN && (r[i1] >= 0 || r[i1] == DIR_PARENT || r[i+1] == DIR_MULTI_GO_RIGHT)) |  | ||||||
|             r[i] = DIR_MULTI_GO_RIGHT; |  | ||||||
|           } |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|     for(int i=0; i<isize(r); i++) if(r[i] == DIR_UNKNOWN) { |     for(int i=0; i<isize(r); i++) if(r[i] == DIR_UNKNOWN) { | ||||||
|       int val = treestates[id].code.second[i+1]; |       int val = treestates[id].code.second[i+1]; | ||||||
|       if(val < 2 || val >= 8) throw rulegen_failure("wrong code in gen_rule"); |       if(val < 2 || val >= 8) { | ||||||
|  |         debuglist = { treestates[id].giver }; | ||||||
|  |         println(hlog, "id = ", id, " i = ", i, " val = ", val, " code = ", treestates[id].code); | ||||||
|  |         throw rulegen_failure("wrong code in gen_rule"); | ||||||
|  |         } | ||||||
|       r[i] = ((val & 1) ? DIR_RIGHT : DIR_LEFT); |       r[i] = ((val & 1) ? DIR_RIGHT : DIR_LEFT); | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
| @@ -1424,6 +1420,8 @@ void rules_iteration() { | |||||||
|  |  | ||||||
|   int q = isize(single_live_branch_close_to_root); |   int q = isize(single_live_branch_close_to_root); | ||||||
|  |  | ||||||
|  |   find_sub_status(); | ||||||
|  |  | ||||||
|   for(int id=0; id<isize(treestates); id++) if(treestates[id].is_live) { |   for(int id=0; id<isize(treestates); id++) if(treestates[id].is_live) { | ||||||
|     auto& r = treestates[id].rules; |     auto& r = treestates[id].rules; | ||||||
|     int last_live_branch = -1; |     int last_live_branch = -1; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue