mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 22:12:59 +00:00 
			
		
		
		
	simplified and generalized cdata
This commit is contained in:
		| @@ -364,6 +364,7 @@ void connectHeptagons(heptspin hi, heptspin hs); | ||||
| transmatrix adjcell_matrix(heptagon *h, int d); | ||||
|  | ||||
| struct hrmap_archimedean : hrmap { | ||||
|   map<int, struct cdata> eucdata; | ||||
|   heptagon *origin; | ||||
|   heptagon *getOrigin() { return origin; } | ||||
|  | ||||
| @@ -441,6 +442,10 @@ struct hrmap_archimedean : hrmap { | ||||
|     } | ||||
|  | ||||
|   ~hrmap_archimedean() { | ||||
|     if(hyperbolic) for(auto& p: archimedean_gmatrix) if(p.second.first->cdata) { | ||||
|       delete p.second.first->cdata; | ||||
|       p.second.first->cdata = NULL; | ||||
|       } | ||||
|     clearfrom(origin); | ||||
|     altmap.clear(); | ||||
|     archimedean_gmatrix.clear(); | ||||
|   | ||||
| @@ -90,8 +90,9 @@ namespace binary { | ||||
|   ld horohex_scale = 0.6; | ||||
|    | ||||
|   heptagon *build(heptagon *parent, int d, int d1, int t, int side, int delta) { | ||||
|     auto h = buildHeptagon1(tailored_alloc<heptagon> (t), parent, d, hsOrigin, d1); | ||||
|     auto h = buildHeptagon1(tailored_alloc<heptagon> (t), parent, d, hsA, d1); | ||||
|     h->distance = parent->distance + delta; | ||||
|     h->dm4 = parent->dm4 + delta; | ||||
|     h->c7 = NULL; | ||||
|     if(parent->c7) h->c7 = newCell(t, h); | ||||
|     h->cdata = NULL; | ||||
|   | ||||
							
								
								
									
										133
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										133
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -29,11 +29,6 @@ cell *newCell(int type, heptagon *master) { | ||||
|   return c; | ||||
|   } | ||||
|  | ||||
| struct cdata { | ||||
|   int val[4]; | ||||
|   int bits; | ||||
|   }; | ||||
|  | ||||
| // -- hrmap --- | ||||
|  | ||||
| hrmap *currentmap; | ||||
| @@ -603,6 +598,10 @@ bool randpatternMajority(cell *c, int ival, int iterations) { | ||||
|  | ||||
| cdata orig_cdata; | ||||
|  | ||||
| bool geometry_supports_cdata() { | ||||
|   return among(geometry, gEuclid, gEuclidSquare, gNormal, gOctagon, g45, g46, g47, gBinaryTiling) || (archimedean && !sphere); | ||||
|   } | ||||
|  | ||||
| void affect(cdata& d, short rv, signed char signum) { | ||||
|   if(rv&1) d.val[0]+=signum; else d.val[0]-=signum; | ||||
|   if(rv&2) d.val[1]+=signum; else d.val[1]-=signum; | ||||
| @@ -620,12 +619,20 @@ void setHeptagonRval(heptagon *h) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
| bool dmeq(int a, int b) { return (a&3) == (b&3); } | ||||
|  | ||||
| cdata *getHeptagonCdata(heptagon *h) { | ||||
|   if(h->cdata) return h->cdata; | ||||
|  | ||||
|   if(sphere || quotient) h = currentmap->gamestart()->master; | ||||
|    | ||||
|   bool starting = h->s == hsOrigin; | ||||
|   if(binarytiling) { | ||||
|     if(binary::mapside(h) == 0) starting = true; | ||||
|     for(int i=0; i<h->type; i++) if(binary::mapside(h->cmove(i)) == 0) starting = true; | ||||
|     } | ||||
|  | ||||
|   if(h == currentmap->gamestart()->master) { | ||||
|   if(starting) { | ||||
|     h->cdata = new cdata(orig_cdata); | ||||
|     for(int& v: h->cdata->val) v = 0; | ||||
|     h->cdata->bits = reptilecheat ? (1 << 21) - 1 : 0; | ||||
| @@ -633,56 +640,32 @@ cdata *getHeptagonCdata(heptagon *h) { | ||||
|     return h->cdata; | ||||
|     } | ||||
|    | ||||
|   cdata mydata = *getHeptagonCdata(h->move(0)); | ||||
|   int dir = binarytiling ? 5 : 0; | ||||
|    | ||||
|   cdata mydata = *getHeptagonCdata(h->cmove(dir)); | ||||
|  | ||||
|   for(int di=3; di<5; di++) { | ||||
|     heptspin hs(h, di, false); | ||||
|     int signum = +1; | ||||
|     while(true) { | ||||
|       heptspin hstab[15]; | ||||
|       hstab[7] = hs; | ||||
|        | ||||
|       for(int i=8; i<12; i++) { | ||||
|         hstab[i] = hstab[i-1]; | ||||
|         hstab[i] += ((i&1) ? 4 : 3); | ||||
|         hstab[i] += wstep; | ||||
|         hstab[i] += ((i&1) ? 3 : 4); | ||||
|         } | ||||
|  | ||||
|       for(int i=6; i>=3; i--) { | ||||
|         hstab[i] = hstab[i+1]; | ||||
|         hstab[i] += ((i&1) ? 3 : 4); | ||||
|         hstab[i] += wstep; | ||||
|         hstab[i] += ((i&1) ? 4 : 3); | ||||
|         } | ||||
|        | ||||
|       if(hstab[3].at->distance < hstab[7].at->distance) { | ||||
|         hs = hstab[3]; continue; | ||||
|         } | ||||
|  | ||||
|       if(hstab[11].at->distance < hstab[7].at->distance) { | ||||
|         hs = hstab[11]; continue; | ||||
|         } | ||||
|        | ||||
|       int jj = 7; | ||||
|       for(int k=3; k<12; k++) if(hstab[k].at->distance < hstab[jj].at->distance) jj = k; | ||||
|        | ||||
|       int ties = 0, tiespos = 0; | ||||
|       for(int k=3; k<12; k++) if(hstab[k].at->distance == hstab[jj].at->distance)  | ||||
|         ties++, tiespos += (k-jj); | ||||
|          | ||||
|       // printf("ties=%d tiespos=%d jj=%d\n", ties, tiespos, jj); | ||||
|       if(ties == 2) jj += tiespos/2; | ||||
|        | ||||
|       if(jj&1) signum = -1; | ||||
|       hs = hstab[jj]; | ||||
|        | ||||
|       break; | ||||
|       } | ||||
|     hs = hs + 3 + wstep; | ||||
|   if(S3 == 4) { | ||||
|     heptspin hs(h, 0); | ||||
|     while(dmeq((hs+1).cpeek()->dm4, (hs.at->dm4 - 1))) hs = hs + 1 + wstep + 1; | ||||
|     while(dmeq((hs-1).cpeek()->dm4, (hs.at->dm4 - 1))) hs = hs - 1 + wstep - 1; | ||||
|     setHeptagonRval(hs.at); | ||||
|      | ||||
|     affect(mydata, hs.spin ? hs.at->rval0 : hs.at->rval1, signum); | ||||
|     affect(mydata, hs.at->rval0, 1);  | ||||
|     } | ||||
|   else for(int di: {0,1}) { | ||||
|     heptspin hs(h, dir, false); | ||||
|     hs -= di; | ||||
|     while(true) { | ||||
|       heptspin hs2 = hs + wstep + 1 + wstep - 1; | ||||
|       if(dmeq(hs2.at->dm4, hs.at->dm4 + 1)) break; | ||||
|       hs = hs2; | ||||
|       } | ||||
|     while(true) { | ||||
|       heptspin hs2 = hs + 1 + wstep - 1 + wstep; | ||||
|       if(dmeq(hs2.at->dm4, hs.at->dm4 + 1)) break; | ||||
|       hs = hs2; | ||||
|       } | ||||
|     setHeptagonRval(hs.at); | ||||
|     affect(mydata, hs.spin == dir ? hs.at->rval0 : hs.at->rval1, 1); | ||||
|     } | ||||
|  | ||||
|   return h->cdata = new cdata(mydata); | ||||
| @@ -696,8 +679,12 @@ cdata *getEuclidCdata(int h) { | ||||
|     } | ||||
|    | ||||
|   int x, y; | ||||
|   hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap); | ||||
|   if(euc->eucdata.count(h)) return &(euc->eucdata[h]); | ||||
|   auto& data =  | ||||
|     archimedean ? ((arcm::hrmap_archimedean*) (currentmap))->eucdata : | ||||
|     ((hrmap_euclidean*) (currentmap))->eucdata; | ||||
|      | ||||
|   // hrmap_euclidean* euc = dynamic_cast<hrmap_euclidean*> (currentmap); | ||||
|   if(data.count(h)) return &(data[h]); | ||||
|    | ||||
|   tie(x,y) = vec_to_pair(h); | ||||
|  | ||||
| @@ -705,7 +692,7 @@ cdata *getEuclidCdata(int h) { | ||||
|     cdata xx; | ||||
|     for(int i=0; i<4; i++) xx.val[i] = 0; | ||||
|     xx.bits = 0; | ||||
|     return &(euc->eucdata[h] = xx); | ||||
|     return &(data[h] = xx); | ||||
|     } | ||||
|   int ord = 1, bid = 0; | ||||
|   while(!((x|y)&ord)) ord <<= 1, bid++; | ||||
| @@ -737,16 +724,36 @@ cdata *getEuclidCdata(int h) { | ||||
|       if(gbit) xx.bits |= (1<<b); | ||||
|       } | ||||
|      | ||||
|     return &(euc->eucdata[h] = xx); | ||||
|     return &(data[h] = xx); | ||||
|     } | ||||
|    | ||||
|   // impossible! | ||||
|   return NULL; | ||||
|   } | ||||
|  | ||||
| int ld_to_int(ld x) { | ||||
|   return int(x + 1000000.5) - 1000000; | ||||
|   } | ||||
|  | ||||
| int pseudocoords(cell *c) { | ||||
|   transmatrix T = arcm::archimedean_gmatrix[c->master].second; | ||||
|   return pair_to_vec(ld_to_int(T[0][GDIM]), ld_to_int((spin(60*degree) * T)[0][GDIM])); | ||||
|   } | ||||
|  | ||||
| cdata *arcmCdata(cell *c) { | ||||
|   heptagon *h2 = arcm::archimedean_gmatrix[c->master].first; | ||||
|   dynamicval<eGeometry> g(geometry, gNormal);  | ||||
|   dynamicval<hrmap*> cm(currentmap, arcm::current_altmap);   | ||||
|   return getHeptagonCdata(h2); | ||||
|   } | ||||
|  | ||||
| int getCdata(cell *c, int j) { | ||||
|   if(masterless) return getEuclidCdata(decodeId(c->master))->val[j]; | ||||
|   else if(geometry) return 0; | ||||
|   else if(archimedean && euclid) | ||||
|     return getEuclidCdata(pseudocoords(c))->val[j]; | ||||
|   else if(archimedean && hyperbolic)  | ||||
|     return arcmCdata(c)->val[j]*3; | ||||
|   else if(!geometry_supports_cdata()) return 0; | ||||
|   else if(ctof(c)) return getHeptagonCdata(c->master)->val[j]*3; | ||||
|   else { | ||||
|     int jj = 0; | ||||
| @@ -759,8 +766,12 @@ int getCdata(cell *c, int j) { | ||||
|  | ||||
| int getBits(cell *c) { | ||||
|   if(masterless) return getEuclidCdata(decodeId(c->master))->bits; | ||||
|   else if(geometry) return 0; | ||||
|   else if(c->type != 6) return getHeptagonCdata(c->master)->bits; | ||||
|   else if(archimedean && euclid) | ||||
|     return getEuclidCdata(pseudocoords(c))->bits; | ||||
|   else if(archimedean && hyperbolic)  | ||||
|     return arcmCdata(c)->bits; | ||||
|   else if(!geometry_supports_cdata()) return 0; | ||||
|   else if(c == c->master->c7) return getHeptagonCdata(c->master)->bits; | ||||
|   else { | ||||
|     auto ar = gp::get_masters(c); | ||||
|     int b0 = getHeptagonCdata(ar[0])->bits; | ||||
|   | ||||
| @@ -352,6 +352,8 @@ struct debugScreen { | ||||
|         "Extra value that is important in some lands. The specific meaning depends on the land."); }); | ||||
|       dialog::addSelItem("land param (hex)", itsh8(what->landparam), 0); | ||||
|       dialog::addSelItem("land param (heat)", fts(HEAT(what)), 't'); | ||||
|       dialog::addSelItem("cdata",  | ||||
|         its(getCdata(what, 0))+"/"+its(getCdata(what,1))+"/"+its(getCdata(what,2))+"/"+its(getCdata(what,3))+"/"+itsh(getBits(what)), 't'); | ||||
|       dialog::add_action([what] () {  | ||||
|         static ld d = HEAT(what); | ||||
|         dialog::editNumber(d, -2, 2, 0.1, d, "landparam", | ||||
|   | ||||
							
								
								
									
										5
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -685,6 +685,11 @@ enum hstate { hsOrigin, hsA, hsB, hsError, hsA0, hsA1, hsB0, hsB1, hsC }; | ||||
| struct cell *createMov(struct cell *c, int d); | ||||
| struct heptagon *createStep(struct heptagon *c, int d); | ||||
|  | ||||
| struct cdata { | ||||
|   int val[4]; | ||||
|   int bits; | ||||
|   }; | ||||
|  | ||||
| // in bitruncated/irregular/Goldberg geometries, heptagons form the  | ||||
| // underlying regular tiling (not necessarily heptagonal); in pure | ||||
| // geometries, they correspond 1-1 to tiles; in 'masterless' geometries | ||||
|   | ||||
| @@ -83,7 +83,7 @@ bool blizzard_no_escape(cell *c) { | ||||
| bool out_ruin(cell *c) { | ||||
|   if(sphere) | ||||
|     return getHemisphere(c, 0) > 0; | ||||
|   else if(stdhyperbolic) { | ||||
|   else if(geometry_supports_cdata()) { | ||||
|     int cd = getCdata(c, 3); | ||||
|     cd &= 31; | ||||
|     return cd >= 16; | ||||
| @@ -686,7 +686,7 @@ void giantLandSwitch(cell *c, int d, cell *from) { | ||||
|         else { | ||||
|           int i = archimedean ? hrand(50) : zebra40(c); | ||||
|           if(i < 40) { | ||||
|             int cd = hyperbolic_37 ? getCdata(c, 3) : hrand(16); | ||||
|             int cd = geometry_supports_cdata() ? getCdata(c, 3) : hrand(16); | ||||
|             cd &= 15; | ||||
|             if(cd >= 4 && cd < 12) c->wall = waChasm; | ||||
|             else { | ||||
|   | ||||
| @@ -647,6 +647,8 @@ namespace lv { | ||||
|  | ||||
| int old_daily_id = 1000000; | ||||
|  | ||||
| const int landscapes_when = 1000; | ||||
|  | ||||
| // check if the given land should appear in lists | ||||
| land_validity_t& land_validity(eLand l) { | ||||
|  | ||||
| @@ -909,7 +911,7 @@ land_validity_t& land_validity(eLand l) { | ||||
|     } | ||||
|      | ||||
|   // needs standard/Euclidean (needs fractal landscape) | ||||
|   if(among(l, laTortoise, laVariant) && !stdeuc) | ||||
|   if(among(l, laTortoise, laVariant) && !(old_daily_id < landscapes_when ? stdeuc : geometry_supports_cdata())) | ||||
|     return not_implemented; | ||||
|    | ||||
|   // technical lands do not count | ||||
|   | ||||
| @@ -1546,7 +1546,7 @@ namespace patterns { | ||||
|     dialog::addItem(XLAT("random colors"), 'r'); | ||||
|     dialog::addItem(XLAT("distance from origin"), 'M'); | ||||
|      | ||||
|     if(stdeuc) { | ||||
|     if(geometry_supports_cdata()) { | ||||
|       dialog::addItem(XLAT("rainbow landscape"), 'l'); | ||||
|       dialog::addItem(XLAT("dark rainbow landscape"), 'd'); | ||||
|       } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue