mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	build_shortest_path function
This commit is contained in:
		
							
								
								
									
										43
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										43
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -1783,6 +1783,49 @@ int celldistance(cell *c1, cell *c2) { | ||||
|   return hyperbolic_celldistance(c1, c2); | ||||
|   } | ||||
|  | ||||
| vector<cell*> build_shortest_path(cell *c1, cell *c2) { | ||||
|   if(geometry == gCrystal) return crystal::build_shortest_path(c1, c2); | ||||
|   vector<cell*> p; | ||||
|   if(euclid) { | ||||
|     using namespace hyperpoint_vec; | ||||
|     p.push_back(c1); | ||||
|     hyperpoint h = tC0(calc_relative_matrix(c2, c1, C0)) - C0; | ||||
|     cell *x = c1; | ||||
|     hyperpoint h1 = C0;  | ||||
|     int d = celldistance(c1, c2); | ||||
|     for(int i=0; i<=d * 10; i++) { | ||||
|       h1 += h / d / 10.; | ||||
|       virtualRebase(x, h1,  true); | ||||
|       if(x != p.back()) p.push_back(x); | ||||
|       } | ||||
|     if(isize(p) != d + 1) | ||||
|       println(hlog, "warning: path size ", isize(p), " should be ", d+1); | ||||
|     } | ||||
|   else if(c2 == currentmap->gamestart()) { | ||||
|     while(c1 != c2) { | ||||
|       p.push_back(c1); | ||||
|       forCellCM(c, c1) if(celldist(c) < celldist(c1)) { c1 = c; goto next1; } | ||||
|       println(hlog, "could not build_shortest_path"); exit(1); | ||||
|       next1: ; | ||||
|       } | ||||
|     p.push_back(c1); | ||||
|     } | ||||
|   else if(c1 == currentmap->gamestart()) { | ||||
|     p = build_shortest_path(c2, c1); | ||||
|     reverse(p.begin(), p.end()); | ||||
|     } | ||||
|   else { | ||||
|     while(c1 != c2) { | ||||
|       p.push_back(c1); | ||||
|       forCellCM(c, c1) if(celldistance(c, c2) < celldistance(c1, c2)) { c1 = c; goto next; } | ||||
|       println(hlog, "could not build_shortest_path"); exit(1); | ||||
|       next: ; | ||||
|       } | ||||
|     p.push_back(c1); | ||||
|     } | ||||
|   return p; | ||||
|   } | ||||
|  | ||||
| void clearCellMemory() { | ||||
|   for(int i=0; i<isize(allmaps); i++)  | ||||
|     if(allmaps[i]) | ||||
|   | ||||
							
								
								
									
										53
									
								
								crystal.cpp
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								crystal.cpp
									
									
									
									
									
								
							| @@ -538,6 +538,59 @@ bool crystal_cell(cell *c, transmatrix V) { | ||||
|   return false; | ||||
|   } | ||||
|  | ||||
| vector<cell*> build_shortest_path(cell *c1, cell *c2) { | ||||
|   auto m = crystal_map(); | ||||
|   ldcoord co1 = m->get_coord(c1); | ||||
|   ldcoord co2 = m->get_coord(c2) - co1; | ||||
|    | ||||
|   // draw a cylinder from co1 to co2, and find the solution by going through that cylinder | ||||
|    | ||||
|   ldcoord mul = co2 / sqrt(co2|co2); | ||||
|    | ||||
|   ld mmax = (co2|mul); | ||||
|    | ||||
|   vector<cell*> p;   | ||||
|   vector<int> parent_id; | ||||
|    | ||||
|   manual_celllister cl; | ||||
|   cl.add(c2); | ||||
|   parent_id.push_back(-1); | ||||
|    | ||||
|   int steps = 0; | ||||
|   int nextsteps = 1; | ||||
|    | ||||
|   for(int i=0; i<isize(cl.lst); i++) { | ||||
|     if(i == nextsteps) steps++, nextsteps = isize(cl.lst); | ||||
|     cell *c = cl.lst[i]; | ||||
|     forCellCM(c3, c) if(!cl.listed(c3)) { | ||||
|       if(c3 == c1) {  | ||||
|         p.push_back(c1); | ||||
|         while(c3 != c2) { | ||||
|           while(i) { | ||||
|             p.push_back(c3); | ||||
|             i = parent_id[i]; | ||||
|             c3 = cl.lst[i]; | ||||
|             } | ||||
|           } | ||||
|         p.push_back(c3); | ||||
|         return p; | ||||
|         } | ||||
|  | ||||
|       auto h = m->get_coord(c3) - co1; | ||||
|       ld dot = (h|mul); | ||||
|       if(dot > mmax + PERIOD/2 + .1) continue; | ||||
|  | ||||
|       for(int k=0; k<m->cs.dim; k++) if(abs(h[k] - dot * mul[k]) > PERIOD + .1) goto next3; | ||||
|       cl.add(c3); | ||||
|       parent_id.push_back(i); | ||||
|       next3: ; | ||||
|       } | ||||
|     } | ||||
|    | ||||
|   println(hlog, "Error: path not found"); | ||||
|   return p; | ||||
|   } | ||||
|  | ||||
| int precise_distance(cell *c1, cell *c2) { | ||||
|   if(c1 == c2) return 0; | ||||
|   auto m = crystal_map(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue