mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 14:02:59 +00:00 
			
		
		
		
	gp:: GP(x,x) now works in elliptic geometry
This commit is contained in:
		
							
								
								
									
										180
									
								
								goldberg.cpp
									
									
									
									
									
								
							
							
						
						
									
										180
									
								
								goldberg.cpp
									
									
									
									
									
								
							| @@ -20,9 +20,14 @@ namespace gp { | |||||||
|       e1.first*e2.second + e2.first*e1.second + e1.second*e2.second); |       e1.first*e2.second + e2.first*e1.second + e1.second*e2.second); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |   loc operator*(loc e1, int i) { | ||||||
|  |     return loc(e1.first*i, e1.second*i); | ||||||
|  |     } | ||||||
|  |    | ||||||
|   struct goldberg_mapping_t { |   struct goldberg_mapping_t { | ||||||
|     cellwalker cw; |     cellwalker cw; | ||||||
|     char rdir; |     char rdir; | ||||||
|  |     char mindir; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|   loc eudir(int d) { |   loc eudir(int d) { | ||||||
| @@ -100,6 +105,7 @@ namespace gp { | |||||||
|     for(int y=0; y<32; y++) for(int x=0; x<32; x++) { |     for(int y=0; y<32; y++) for(int x=0; x<32; x++) { | ||||||
|       goldberg_map[y][x].cw.c = NULL; |       goldberg_map[y][x].cw.c = NULL; | ||||||
|       goldberg_map[y][x].rdir = -1; |       goldberg_map[y][x].rdir = -1; | ||||||
|  |       goldberg_map[y][x].mindir = 0; | ||||||
|       } |       } | ||||||
|     } |     } | ||||||
|    |    | ||||||
| @@ -111,7 +117,7 @@ namespace gp { | |||||||
|     static char bufs[16][16]; |     static char bufs[16][16]; | ||||||
|     static int bufid; |     static int bufid; | ||||||
|     bufid++; bufid %= 16; |     bufid++; bufid %= 16; | ||||||
|     snprintf(bufs[bufid], 16, "[%d,%d]", at.first, at.second); |     snprintf(bufs[bufid], 16, "[%2d,%2d]", at.first, at.second); | ||||||
|     return bufs[bufid]; |     return bufs[bufid]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -119,7 +125,7 @@ namespace gp { | |||||||
|     static char bufs[16][32]; |     static char bufs[16][32]; | ||||||
|     static int bufid; |     static int bufid; | ||||||
|     bufid++; bufid %= 16; |     bufid++; bufid %= 16; | ||||||
|     snprintf(bufs[bufid], 32, "[%p/%d:%d:%d]", cw.c, cw.c?cw.c->type:-1, cw.spin, cw.mirrored); |     snprintf(bufs[bufid], 32, "[%p/%2d:%d:%d]", cw.c, cw.c?cw.c->type:-1, cw.spin, cw.mirrored); | ||||||
|     return bufs[bufid]; |     return bufs[bufid]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -127,41 +133,87 @@ namespace gp { | |||||||
|    |    | ||||||
| #define WHD(x) // x | #define WHD(x) // x | ||||||
|  |  | ||||||
|   void conn1(loc at, int dir, int dir1) { |   bool operator != (cellwalker cw1, cellwalker cw2) { | ||||||
|  |     return cw1.c != cw2.c || cw1.spin != cw2.spin || cw1.mirrored != cw2.mirrored; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   cell*& peek(cellwalker cw) { | ||||||
|  |     return cw.c->mov[cw.spin]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   cellwalker get_localwalk(const goldberg_mapping_t& wc, int dir) { | ||||||
|  |     if(dir < wc.mindir) dir += 6; | ||||||
|  |     if(dir >= wc.mindir + 6) dir -= 6; | ||||||
|  |     return wc.cw + dir; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   void set_localwalk(goldberg_mapping_t& wc, int dir, const cellwalker& cw) { | ||||||
|  |     if(dir < wc.mindir) dir += 6; | ||||||
|  |     if(dir >= wc.mindir + 6) dir -= 6; | ||||||
|  |     wc.cw = cw - dir; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   bool pull(loc at, int dir) { | ||||||
|     auto& wc = get_mapping(at); |     auto& wc = get_mapping(at); | ||||||
|     auto& wc1 = get_mapping(at + eudir(dir)); |     auto at1 = at + eudir(dir); | ||||||
|     int cdir = (wc.cw + dir).spin; |     int dir1 = fix6(dir+3); | ||||||
|     WHD( printf("  connection %s/%d %s ", disp(at), dir, dcw(wc.cw+dir)); ) |     cellwalker wcw = get_localwalk(wc, dir); | ||||||
|     if(!wc1.cw.c) { |     auto& wc1= get_mapping(at1); | ||||||
|       wc1.cw.c = wc.cw.c->mov[cdir]; |  | ||||||
|     if(wc1.cw.c) { |     if(wc1.cw.c) { | ||||||
|         // wc1.c/wc.c->spin(cdir) == dir1 |       if(peek(wcw)) { | ||||||
|         wc1.cw = (wc.cw + dir + wstep - dir1); |         auto wcw1 = get_localwalk(wc1, dir1); | ||||||
|         WHD( printf("(pulled) "); ) |         if(wcw + wstep != wcw1) { | ||||||
|         } |           WHD( printf("%s : %s / %s (pull error from %s :: %s)\n", disp(at1), dcw(wcw+wstep), dcw(wcw1), disp(at), dcw(wcw)); ) | ||||||
|       if(!wc1.cw.c) { |  | ||||||
|         wc1.cw.c = newCell(6, wc.cw.c->master); |  | ||||||
|         spawn++; |  | ||||||
|         // 0 for wc1.c should be dir1 |  | ||||||
|         wc1.cw.mirrored = wc.cw.mirrored; |  | ||||||
|         wc1.cw.spin = fix6(wc.cw.mirrored ? dir1 : -dir1); |  | ||||||
|         WHD( printf("(created) "); ) |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     int cdir1 = (wc1.cw + dir1).spin; |  | ||||||
|     WHD( printf("%s ", dcw(wc1.cw+dir1)); ) |  | ||||||
|     if(wc.cw.c->mov[cdir] && wc.cw.c->mov[cdir] != wc1.cw.c) { |  | ||||||
|       WHD( printf("FAIL: %p\n", wc.cw.c->mov[cdir]); exit(1); ) |  | ||||||
|       } |  | ||||||
|     if(wc.cw.c->mov[cdir]) { |  | ||||||
|       if(wc.cw.c->spin(cdir) != cdir1) { |  | ||||||
|         printf("warning: wrong spin: %d vs %d\n", wc.cw.c->spin(cdir), cdir1); |  | ||||||
|           exit(1); |           exit(1); | ||||||
|           } |           } | ||||||
|         } |         } | ||||||
|  |       return false; | ||||||
|  |       } | ||||||
|  |     if(peek(wcw)) { | ||||||
|  |       set_localwalk(wc1, dir1, wcw + wstep); | ||||||
|  |       WHD( printf("%s : %s (pulled from %s :: %s)\n", disp(at1), dcw(wcw + wstep), disp(at), dcw(wcw)); ) | ||||||
|  |       return true; | ||||||
|  |       } | ||||||
|  |     return false; | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |   void conn1(loc at, int dir, int dir1) { | ||||||
|  |     auto& wc = get_mapping(at); | ||||||
|  |     auto wcw = get_localwalk(wc, dir); | ||||||
|  |     auto& wc1 = get_mapping(at + eudir(dir)); | ||||||
|  |     WHD( printf("  connection %s/%d %s ~ %s/%d ", disp(at), dir, dcw(wc.cw+dir), disp(at+eudir(dir)), dir1); ) | ||||||
|  |     if(!wc1.cw.c) { | ||||||
|  |       if(peek(wcw)) { | ||||||
|  |         WHD( printf("(pulled) "); ) | ||||||
|  |         set_localwalk(wc1, dir1, wcw + wstep); | ||||||
|  |         } | ||||||
|  |       else { | ||||||
|  |         peek(wcw) = newCell(6, wc.cw.c->master); | ||||||
|  |         tsetspin(wcw.c->spintable, wcw.spin, 0); | ||||||
|  |         set_localwalk(wc1, dir1, wcw + wstep); | ||||||
|  |         spawn++; | ||||||
|  |         WHD( printf("(created) "); ) | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     WHD( printf("%s ", dcw(wc1.cw+dir1)); ) | ||||||
|  |     auto wcw1 = get_localwalk(wc1, dir1); | ||||||
|  |     if(peek(wcw)) { | ||||||
|  |       if(wcw+wstep != wcw1) { | ||||||
|  |         WHD( printf("FAIL: %s / %s\n", dcw(wcw), dcw(wcw1)); exit(1); ) | ||||||
|  |         } | ||||||
|  |       else { | ||||||
|  |         WHD(printf("(was there)\n");) | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     else { | ||||||
|       WHD(printf("ok\n"); ) |       WHD(printf("ok\n"); ) | ||||||
|     wc.cw.c->mov[cdir] = wc1.cw.c; |       peek(wcw) = wcw1.c; | ||||||
|     tsetspin(wc.cw.c->spintable, cdir, cdir1 + (wc.cw.mirrored != wc1.cw.mirrored ? 8 : 0)); |       tsetspin(wcw.c->spintable, wcw.spin, wcw1.spin + (wcw.mirrored != wcw1.mirrored ? 8 : 0)); | ||||||
|  |       if(wcw+wstep != wcw1) { | ||||||
|  |         printf("assertion failed\n"); | ||||||
|  |         exit(1); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   void conn(loc at, int dir) { |   void conn(loc at, int dir) { | ||||||
| @@ -169,6 +221,13 @@ namespace gp { | |||||||
|     conn1(at + eudir(dir), fix6(dir+3), fix6(dir)); |     conn1(at + eudir(dir), fix6(dir+3), fix6(dir)); | ||||||
|     } |     } | ||||||
|    |    | ||||||
|  |   goldberg_mapping_t& set_heptspin(loc at, heptspin hs) { | ||||||
|  |     auto& ac0 = get_mapping(at); | ||||||
|  |     ac0.cw = cellwalker(hs.h->c7, hs.spin, hs.mirrored); | ||||||
|  |     WHD( printf("%s : %s\n", disp(at), dcw(ac0.cw)); ) | ||||||
|  |     return ac0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   void extend_map(cell *c, int d) { |   void extend_map(cell *c, int d) { | ||||||
|     WHD( printf("EXTEND %p %d\n", c, d); ) |     WHD( printf("EXTEND %p %d\n", c, d); ) | ||||||
|     if(c->master->c7 != c) { |     if(c->master->c7 != c) { | ||||||
| @@ -196,26 +255,41 @@ namespace gp { | |||||||
|     vc[1] = param; |     vc[1] = param; | ||||||
|     vc[2] = param * loc(0,1); |     vc[2] = param * loc(0,1); | ||||||
|      |      | ||||||
|     // get_mapping(loc) gives our local map. We set the vertices first |     heptspin hs(c->master, d, false); | ||||||
|     { |  | ||||||
|     auto h = c->master; |  | ||||||
|     auto& ac0 = get_mapping(vc[0]); |  | ||||||
|     ac0.cw = cellwalker(h->c7, d); |  | ||||||
|     WHD( printf("%s : %s\n", disp(vc[0]), dcw(ac0.cw)); ) |  | ||||||
|      |      | ||||||
|     // 3 ~ h->spin(d) |     auto& ac0 = set_heptspin(vc[0], hs); | ||||||
|     auto& ac1 = get_mapping(vc[1]); |     ac0.mindir = -1; | ||||||
|     cell *c0 = createStep(h, d)->c7; |     auto& ac1 = set_heptspin(vc[1], hs + wstep - 3); | ||||||
|     ac1.cw = cellwalker(c0, h->spin(d) - (h->mirror(d) ? -3 : 3), h->mirror(d)); |     auto& ac2 = set_heptspin(vc[2], hs + 1 + wstep - 4); | ||||||
|     WHD( printf("%s : %s\n", disp(vc[1]), dcw(ac1.cw)); ) |     ac2.mindir = 1; | ||||||
|      |      | ||||||
|  |     if(elliptic && param.first == param.second) { | ||||||
|  |       int x = param.first; | ||||||
|  |       if(ac1.cw.mirrored != hs.mirrored) ac1.cw--; | ||||||
|  |       if(ac2.cw.mirrored != hs.mirrored) ac2.cw--; | ||||||
|        |        | ||||||
|     auto& ac2 = get_mapping(vc[2]); |       for(int d=0; d<3; d++) for(int k=0; k<3; k++)  | ||||||
|     int d1 = (d+1)%S7; |       for(int i=0; i<x; i++) { | ||||||
|     cell *c1 = createStep(h, d1)->c7; |         int dd = (2*d+k); | ||||||
|     ac2.cw = cellwalker(c1, h->spin(d1) - (h->mirror(d1) ? -4 : 4), h->mirror(d1)); |         loc cx = vc[d] + eudir(dd) * i; | ||||||
|     WHD( printf("%s : %s\n", disp(vc[2]), dcw(ac2.cw)); ) |         if(!pull(cx, dd)) break; | ||||||
|     // 4 ~ h->spin(d1) |         } | ||||||
|  |        | ||||||
|  |       for(int i=0; i<=2*x; i++) | ||||||
|  |       for(int d=0; d<3; d++) { | ||||||
|  |         loc cx = vc[d] + eudir(1+2*d) * i; | ||||||
|  |         if(i < 2*x) conn(cx, 1+2*d); | ||||||
|  |         int jmax = x-i, drev = 2*d; | ||||||
|  |         if(jmax < 0) drev += 3, jmax = -jmax; | ||||||
|  |         for(int j=0; j<jmax; j++) { | ||||||
|  |           loc cy = cx + eudir(drev) * j; | ||||||
|  |           conn(cy, drev); | ||||||
|  |           conn(cy, drev+1); | ||||||
|  |           conn(cy, drev+2); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |        | ||||||
|  |       return; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     // then we set the edges of our big equilateral triangle (in a symmetric way) |     // then we set the edges of our big equilateral triangle (in a symmetric way) | ||||||
| @@ -298,6 +372,7 @@ namespace gp { | |||||||
|           exit(1); |           exit(1); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
|     WHD( printf("DONE\n\n"); )     |     WHD( printf("DONE\n\n"); )     | ||||||
|     } |     } | ||||||
|    |    | ||||||
| @@ -351,8 +426,8 @@ namespace gp { | |||||||
|       )); |       )); | ||||||
|     for(int i=0; i<S7; i++) { |     for(int i=0; i<S7; i++) { | ||||||
|       transmatrix T = dir_matrix(i); |       transmatrix T = dir_matrix(i); | ||||||
|       for(int x=-10; x<10; x++) |       for(int x=-16; x<16; x++) | ||||||
|       for(int y=-10; y<10; y++) |       for(int y=-16; y<16; y++) | ||||||
|       for(int d=0; d<6; d++) { |       for(int d=0; d<6; d++) { | ||||||
|         loc at = loc(x, y); |         loc at = loc(x, y); | ||||||
|          |          | ||||||
| @@ -445,10 +520,7 @@ namespace gp { | |||||||
|     auto old_tstate_max = texture::config.tstate_max; |     auto old_tstate_max = texture::config.tstate_max; | ||||||
| #endif | #endif | ||||||
|     xy = internal_representation(xy); |     xy = internal_representation(xy); | ||||||
|     if(xy.second && elliptic) { |     if(xy.second && xy.second != xy.first && elliptic) { | ||||||
|       if(xy.second==xy.first) |  | ||||||
|         addMessage("GP(x,x) not implemented yet for elliptic geometry"); |  | ||||||
|       else |  | ||||||
|       addMessage("This does not work in elliptic geometry"); |       addMessage("This does not work in elliptic geometry"); | ||||||
|       xy.second = 0; |       xy.second = 0; | ||||||
|       } |       } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue