mirror of
				https://github.com/zenorogue/hyperrogue.git
				synced 2025-10-31 05:52:59 +00:00 
			
		
		
		
	irregular grids
This commit is contained in:
		| @@ -105,8 +105,10 @@ bool grailWasFound(cell *c) { | |||||||
|  |  | ||||||
| void generateAlts(heptagon *h, int levs, bool link_cdata) { | void generateAlts(heptagon *h, int levs, bool link_cdata) { | ||||||
|   if(!h->alt) return; |   if(!h->alt) return; | ||||||
|  |   if(!irr::on) { | ||||||
|     preventbarriers(h->c7); |     preventbarriers(h->c7); | ||||||
|     for(int i=0; i<S7; i++) preventbarriers(h->c7->mov[i]); |     for(int i=0; i<S7; i++) preventbarriers(h->c7->mov[i]); | ||||||
|  |     } | ||||||
|   if(gp::on) |   if(gp::on) | ||||||
|     for(int i=0; i<S7; i++) preventbarriers(createStep(h, i)->c7); |     for(int i=0; i<S7; i++) preventbarriers(createStep(h, i)->c7); | ||||||
|   for(int i=0; i<S7; i++)  |   for(int i=0; i<S7; i++)  | ||||||
| @@ -973,7 +975,7 @@ int wallchance(cell *c, bool deepOcean) { | |||||||
| bool horo_ok() { | bool horo_ok() { | ||||||
|   // do the horocycles work in the current geometry? |   // do the horocycles work in the current geometry? | ||||||
|   // (they work in ALL hyperbolic geometries currently!) |   // (they work in ALL hyperbolic geometries currently!) | ||||||
|   return hyperbolic; |   return hyperbolic && !irr::on; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| bool gp_wall_test() { | bool gp_wall_test() { | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ namespace hr { | |||||||
| double randd() { return (rand() + .5) / (RAND_MAX + 1.); } | double randd() { return (rand() + .5) / (RAND_MAX + 1.); } | ||||||
|  |  | ||||||
| double cellgfxdist(cell *c, int i) { | double cellgfxdist(cell *c, int i) { | ||||||
|   if(gp::on) return hdist0(tC0(shmup::calc_relative_matrix(c->mov[i], c, i))); |   if(gp::on || irr::on) return hdist0(tC0(shmup::calc_relative_matrix(c->mov[i], c, i))); | ||||||
|   return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf; |   return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								cell.cpp
									
									
									
									
									
								
							
							
						
						
									
										40
									
								
								cell.cpp
									
									
									
									
									
								
							| @@ -73,6 +73,9 @@ hrmap_hyperbolic::hrmap_hyperbolic() { | |||||||
|   h.alt = NULL; |   h.alt = NULL; | ||||||
|   h.distance = 0; |   h.distance = 0; | ||||||
|   isnonbitrunc = nonbitrunc; |   isnonbitrunc = nonbitrunc; | ||||||
|  |   if(irr::on) | ||||||
|  |     irr::link_start(origin); | ||||||
|  |   else | ||||||
|     h.c7 = newCell(S7, origin); |     h.c7 = newCell(S7, origin); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -107,7 +110,7 @@ struct hrmap_spherical : hrmap { | |||||||
|       h.spintable = 0; |       h.spintable = 0; | ||||||
|       h.fieldval = i; |       h.fieldval = i; | ||||||
|       for(int i=0; i<S7; i++) h.move[i] = NULL; |       for(int i=0; i<S7; i++) h.move[i] = NULL; | ||||||
|       h.c7 = newCell(S7, &h); |       if(!irr::on) h.c7 = newCell(S7, &h); | ||||||
|       } |       } | ||||||
|     if(S7 == 5) |     if(S7 == 5) | ||||||
|       siblings = {1, 0, 10, 4, 3, 8, 9, 11, 5, 6, 2, 7}; |       siblings = {1, 0, 10, 4, 3, 8, 9, 11, 5, 6, 2, 7}; | ||||||
| @@ -174,6 +177,13 @@ struct hrmap_spherical : hrmap { | |||||||
|         dodecahedron[i+1]->setspin(2, 3-i); |         dodecahedron[i+1]->setspin(2, 3-i); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |     if(irr::on) { | ||||||
|  |       irr::link_start(dodecahedron[0]); | ||||||
|  |       for(int i=0; i<spherecells(); i++) | ||||||
|  |         for(int j=0; j<S7; j++) | ||||||
|  |           irr::may_link_next(dodecahedron[i], j); | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   heptagon *getOrigin() { return dodecahedron[0]; } |   heptagon *getOrigin() { return dodecahedron[0]; } | ||||||
| @@ -717,7 +727,7 @@ struct hrmap_quotient : hrmap { | |||||||
|         h->fieldval = S7*i; |         h->fieldval = S7*i; | ||||||
|         h->rval0 = h->rval1 = 0; h->cdata = NULL; |         h->rval0 = h->rval1 = 0; h->cdata = NULL; | ||||||
|         h->distance = 0; |         h->distance = 0; | ||||||
|         h->c7 = newCell(S7, h); |         if(!irr::on) h->c7 = newCell(S7, h); | ||||||
|         } |         } | ||||||
|       for(int j=0; j<S7; j++) { |       for(int j=0; j<S7; j++) { | ||||||
|         int co = connections[i*S7+j]; |         int co = connections[i*S7+j]; | ||||||
| @@ -738,6 +748,13 @@ struct hrmap_quotient : hrmap { | |||||||
|         allh[i]->move[j]->alt = createStep(allh[i]->alt, j); */ |         allh[i]->move[j]->alt = createStep(allh[i]->alt, j); */ | ||||||
|       }     |       }     | ||||||
|      |      | ||||||
|  |     if(irr::on) { | ||||||
|  |       irr::link_start(allh[0]); | ||||||
|  |       for(int i=0; i<TOT; i++) | ||||||
|  |         for(int j=0; j<S7; j++) | ||||||
|  |           irr::may_link_next(allh[i], j); | ||||||
|  |       } | ||||||
|  |  | ||||||
|     celllister cl(gamestart(), 100, 100000000, NULL); |     celllister cl(gamestart(), 100, 100000000, NULL); | ||||||
|     celllist = cl.lst; |     celllist = cl.lst; | ||||||
|     } |     } | ||||||
| @@ -827,6 +844,9 @@ cell *createMov(cell *c, int d) { | |||||||
|     } |     } | ||||||
|    |    | ||||||
|   if(c->mov[d]) return c->mov[d]; |   if(c->mov[d]) return c->mov[d]; | ||||||
|  |   else if(irr::on) { | ||||||
|  |     irr::link_cell(c, d); | ||||||
|  |     } | ||||||
|   else if(nonbitrunc && gp::on) { |   else if(nonbitrunc && gp::on) { | ||||||
|     gp::extend_map(c, d); |     gp::extend_map(c, d); | ||||||
|     if(!c->mov[d]) { |     if(!c->mov[d]) { | ||||||
| @@ -951,7 +971,8 @@ void clearHexes(heptagon *at) { | |||||||
|     delete at->cdata; |     delete at->cdata; | ||||||
|     at->cdata = NULL; |     at->cdata = NULL; | ||||||
|     } |     } | ||||||
|   if(at->c7) subcell(at->c7, clearcell); |   if(irr::on) irr::clear_links(at); | ||||||
|  |   else if(at->c7) subcell(at->c7, clearcell); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| void unlink_cdata(heptagon *h) { | void unlink_cdata(heptagon *h) { | ||||||
| @@ -1017,7 +1038,7 @@ void verifycell(cell *c) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| void verifycells(heptagon *at) { | void verifycells(heptagon *at) { | ||||||
|   if(gp::on) return; |   if(gp::on || irr::on) return; | ||||||
|   for(int i=0; i<S7; i++) if(at->move[i] && at->move[i]->move[at->spin(i)] && at->move[i]->move[at->spin(i)] != at) { |   for(int i=0; i<S7; i++) if(at->move[i] && at->move[i]->move[at->spin(i)] && at->move[i]->move[at->spin(i)] != at) { | ||||||
|     printf("hexmix error %p [%d s=%d] %p %p\n", at, i, at->spin(i), at->move[i], at->move[i]->move[at->spin(i)]); |     printf("hexmix error %p [%d s=%d] %p %p\n", at, i, at->spin(i), at->move[i], at->move[i]->move[at->spin(i)]); | ||||||
|     } |     } | ||||||
| @@ -1066,6 +1087,7 @@ int celldist(cell *c) { | |||||||
|   if(sphere) return celldistance(c, currentmap->gamestart()); |   if(sphere) return celldistance(c, currentmap->gamestart()); | ||||||
|   if(ctof(c)) return c->master->distance; |   if(ctof(c)) return c->master->distance; | ||||||
|   if(gp::on) return gp::compute_dist(c, celldist); |   if(gp::on) return gp::compute_dist(c, celldist); | ||||||
|  |   if(irr::on)  return c->master->distance; | ||||||
|   int dx[MAX_S3]; |   int dx[MAX_S3]; | ||||||
|   for(int u=0; u<S3; u++) |   for(int u=0; u<S3; u++) | ||||||
|     dx[u] = createMov(c, u+u)->master->distance; |     dx[u] = createMov(c, u+u)->master->distance; | ||||||
| @@ -1400,7 +1422,7 @@ int getCdata(cell *c, int j) { | |||||||
|     int jj = 0; |     int jj = 0; | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     for(int k=0; k<3; k++) |     for(int k=0; k<3; k++) | ||||||
|       jj += getHeptagonCdata(ar[k]->master)->val[j]; |       jj += getHeptagonCdata(ar[k])->val[j]; | ||||||
|     return jj; |     return jj; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -1411,9 +1433,9 @@ int getBits(cell *c) { | |||||||
|   else if(c->type != 6) return getHeptagonCdata(c->master)->bits; |   else if(c->type != 6) return getHeptagonCdata(c->master)->bits; | ||||||
|   else { |   else { | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     int b0 = getHeptagonCdata(ar[0]->master)->bits; |     int b0 = getHeptagonCdata(ar[0])->bits; | ||||||
|     int b1 = getHeptagonCdata(ar[1]->master)->bits; |     int b1 = getHeptagonCdata(ar[1])->bits; | ||||||
|     int b2 = getHeptagonCdata(ar[2]->master)->bits; |     int b2 = getHeptagonCdata(ar[2])->bits; | ||||||
|     return (b0 & b1) | (b1 & b2) | (b2 & b0); |     return (b0 & b1) | (b1 & b2) | (b2 & b0); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -1475,7 +1497,7 @@ int celldistance(cell *c1, cell *c2) { | |||||||
|     return 64; |     return 64; | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   if(gp::on || euclid) { |   if(gp::on || euclid || irr::on) { | ||||||
|      |      | ||||||
|     if(saved_distances.count(make_pair(c1,c2))) |     if(saved_distances.count(make_pair(c1,c2))) | ||||||
|       return saved_distances[make_pair(c1,c2)]; |       return saved_distances[make_pair(c1,c2)]; | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ | |||||||
| #include "language.cpp" | #include "language.cpp" | ||||||
| #include "cell.cpp" | #include "cell.cpp" | ||||||
| #include "goldberg.cpp" | #include "goldberg.cpp" | ||||||
|  | #include "irregular.cpp" | ||||||
| #include "pattern2.cpp" | #include "pattern2.cpp" | ||||||
| #include "flags.cpp" | #include "flags.cpp" | ||||||
| #include "yendor.cpp" | #include "yendor.cpp" | ||||||
|   | |||||||
| @@ -3094,7 +3094,7 @@ namespace windmap { | |||||||
|       // cw.spin = 0; |       // cw.spin = 0; | ||||||
|       neighbors.emplace_back(); |       neighbors.emplace_back(); | ||||||
|       auto &v = neighbors.back(); |       auto &v = neighbors.back(); | ||||||
|       if(gp::on) |       if(gp::on || irr::on) | ||||||
|         for(int l=0; l<S7; l++) { |         for(int l=0; l<S7; l++) { | ||||||
|           heptspin hs(cw.c->master, cw.spin); |           heptspin hs(cw.c->master, cw.spin); | ||||||
|           hs = hs + l + wstep; |           hs = hs + l + wstep; | ||||||
|   | |||||||
							
								
								
									
										119
									
								
								floorshapes.cpp
									
									
									
									
									
								
							
							
						
						
									
										119
									
								
								floorshapes.cpp
									
									
									
									
									
								
							| @@ -218,9 +218,17 @@ void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | namespace irr { void generate_floorshapes(); } | ||||||
|  |  | ||||||
| void generate_floorshapes() { | void generate_floorshapes() { | ||||||
|  |  | ||||||
|  |   if(irr::on) { | ||||||
|  |     printf("generating irregular floorshapes...\n"); | ||||||
|  |     irr::generate_floorshapes(); | ||||||
|  |     printf("done\n"); | ||||||
|  |     return; | ||||||
|  |     } | ||||||
|  |      | ||||||
|   if(gp::on) { |   if(gp::on) { | ||||||
|     return; |     return; | ||||||
|     } |     } | ||||||
| @@ -489,6 +497,103 @@ namespace gp { | |||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | namespace irr { | ||||||
|  |  | ||||||
|  |   map<int, matrixlist> usedml; | ||||||
|  |  | ||||||
|  |   void generate_floorshapes() { | ||||||
|  |    | ||||||
|  |     if(irr::cells.empty()) return; | ||||||
|  |  | ||||||
|  |     for(auto pfsh: all_escher_floorshapes) { | ||||||
|  |       auto& fsh = *pfsh; | ||||||
|  |       generate_matrices_scale(1, fsh.noftype); | ||||||
|  |       auto& m = hept_matrices; | ||||||
|  |        | ||||||
|  |       /* if(siid == 0) | ||||||
|  |         for(auto& ma: m.v) ma.first = ma.first * pispin; */ | ||||||
|  |    | ||||||
|  |       fsh.b.resize(irr::sc); | ||||||
|  |  | ||||||
|  |       for(int id=0; id<irr::sc; id++) {       | ||||||
|  |         auto& vs = irr::cells[id]; | ||||||
|  |  | ||||||
|  |         int cor = isize(vs.vertices); | ||||||
|  |         m.n.sym = cor;       | ||||||
|  |          | ||||||
|  |         int i = 0; | ||||||
|  |    | ||||||
|  |         for(int d=0; d<m.o.sym; d++) { | ||||||
|  |           hyperpoint center = hpxy(0,0); | ||||||
|  |      | ||||||
|  |           for(int c=0; c<cor; c++) { | ||||||
|  |             hyperpoint nlcorner = vs.vertices[(d+c+1) % cor]; | ||||||
|  |             hyperpoint nrcorner = vs.vertices[(d+c+2) % cor]; | ||||||
|  |              | ||||||
|  |             hyperpoint nfar = vs.jpoints[vs.neid[(d+c+1) % cor]]; | ||||||
|  |             hyperpoint nlfar = nfar; | ||||||
|  |             hyperpoint nrfar = nfar; | ||||||
|  |             m.v[i].second[c] = build_matrix(center, nlcorner, nrcorner); | ||||||
|  |             m.v[i+1].second[c] = build_matrix(nfar, nlcorner, nrcorner); | ||||||
|  |             m.v[i+2].second[c] = build_matrix(nfar, nlcorner, nlfar); | ||||||
|  |             m.v[i+3].second[c] = build_matrix(nfar, nrcorner, nrfar); | ||||||
|  |             } | ||||||
|  |            | ||||||
|  |           i += 4; | ||||||
|  |           } | ||||||
|  |            | ||||||
|  |         usedml[id] = m; | ||||||
|  |        | ||||||
|  |         m.n.sym = cor; | ||||||
|  |         bshape2(fsh.b[id], fsh.prio, fsh.shapeid2 ? fsh.shapeid2 : fsh.shapeid1, m); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |     for(auto pfsh: all_plain_floorshapes) { | ||||||
|  |       auto& fsh = *pfsh; | ||||||
|  |  | ||||||
|  |       ld sca = fsh.rad0 / shFullFloor.rad0; | ||||||
|  |        | ||||||
|  |       fsh.b.resize(irr::sc); | ||||||
|  |       fsh.shadow.resize(irr::sc);         | ||||||
|  |        | ||||||
|  |       for(int i=0; i<irr::sc; i++) {       | ||||||
|  |         auto& vs = irr::cells[i]; | ||||||
|  |         vector<hyperpoint> cornerlist; | ||||||
|  |          | ||||||
|  |         int cor = isize(vs.vertices); | ||||||
|  |         for(int j=0; j<cor; j++) | ||||||
|  |           cornerlist.push_back(rspintox(vs.vertices[j]) * xpush(hdist0(vs.vertices[j]) * sca) * C0); | ||||||
|  |        | ||||||
|  |         bshape(fsh.b[i], fsh.prio); | ||||||
|  |         for(int i=0; i<=cor; i++) hpcpush(cornerlist[i%cor]); | ||||||
|  |          | ||||||
|  |         bshape(fsh.shadow[i], fsh.prio); | ||||||
|  |         for(int i=0; i<=cor; i++) | ||||||
|  |           hpcpush(mid_at(hpxy(0,0), cornerlist[i%cor], SHADMUL)); | ||||||
|  |          | ||||||
|  |         cell fc; | ||||||
|  |         fc.type = cor; | ||||||
|  |         irr::cellindex[&fc] = i; | ||||||
|  |          | ||||||
|  |         // printf("at = %d,%d cor = %d sca = %lf\n", li.relative.first, li.relative.second, cor, sca); | ||||||
|  |    | ||||||
|  |         for(int k=0; k<SIDEPARS; k++)  | ||||||
|  |           for(int c=0; c<cor; c++) { | ||||||
|  |             fsh.gpside[k][c].resize(irr::sc); | ||||||
|  |             bshape(fsh.gpside[k][c][i], fsh.prio); | ||||||
|  |             hpcpush(iddspin(&fc, c) * cornerlist[c]); | ||||||
|  |             hpcpush(iddspin(&fc, c) * cornerlist[(c+1)%cor]); | ||||||
|  |             chasmifyPoly(dlow_table[k], dhi_table[k], k); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |     finishshape(); last = NULL; | ||||||
|  |     extra_vertices(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
| qfloorinfo qfi; | qfloorinfo qfi; | ||||||
| qfloorinfo qfi_dc; | qfloorinfo qfi_dc; | ||||||
|  |  | ||||||
| @@ -521,6 +626,13 @@ void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, i | |||||||
|     int id = gp::get_plainshape_id(c); |     int id = gp::get_plainshape_id(c); | ||||||
|     queuepolyat(V, shv[id], col, prio); |     queuepolyat(V, shv[id], col, prio); | ||||||
|     } |     } | ||||||
|  |   else if(irr::on) { | ||||||
|  |     int id = irr::cellindex[c]; | ||||||
|  |     if(id < 0 || id >= isize(shv)) { | ||||||
|  |       return; | ||||||
|  |       } | ||||||
|  |     queuepolyat(V, shv[id], col, prio); | ||||||
|  |     } | ||||||
|   else if((euclid || gp::on) && ishex1(c))  |   else if((euclid || gp::on) && ishex1(c))  | ||||||
|     queuepolyat(V * pispin, shv[0], col, prio); |     queuepolyat(V * pispin, shv[0], col, prio); | ||||||
|   else if(!(S7&1) && nonbitrunc) { |   else if(!(S7&1) && nonbitrunc) { | ||||||
| @@ -566,8 +678,13 @@ void viewmat() { | |||||||
|     gp::just_matrices = false; |     gp::just_matrices = false; | ||||||
|     } |     } | ||||||
|   // if(gp::on && !gp::usedml.count(cwt.c)) return; |   // if(gp::on && !gp::usedml.count(cwt.c)) return; | ||||||
|   for(auto& v: (pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { | //  for(auto& v: (pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { | ||||||
| //  for(auto& v: (gp::on ? gp::usedml[cwt.c] : pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { | //  for(auto& v: (gp::on ? gp::usedml[cwt.c] : pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { | ||||||
|  | //    hyperpoint h1 = gmatrix[cwt.c] * v.second[0] * hpxyz(1,0,0); | ||||||
|  |   id = irr::cellindex[cwt.c]; | ||||||
|  |   for(auto& v: irr::usedml[id].v) {  | ||||||
|  | //  for(auto& v: (gp::on ? gp::usedml[cwt.c] : pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) { | ||||||
|  |      | ||||||
|     hyperpoint h1 = gmatrix[cwt.c] * v.second[0] * hpxyz(1,0,0); |     hyperpoint h1 = gmatrix[cwt.c] * v.second[0] * hpxyz(1,0,0); | ||||||
|     hyperpoint h2 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,1,0); |     hyperpoint h2 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,1,0); | ||||||
|     hyperpoint h3 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,0,1); |     hyperpoint h3 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,0,1); | ||||||
|   | |||||||
| @@ -170,6 +170,7 @@ void precalc() { | |||||||
|   base_distlimit = ginf[geometry].distlimit[nonbitrunc]; |   base_distlimit = ginf[geometry].distlimit[nonbitrunc]; | ||||||
|    |    | ||||||
|   gp::compute_geometry();   |   gp::compute_geometry();   | ||||||
|  |   irr::compute_geometry(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| transmatrix ddi(ld dir, ld dist) { | transmatrix ddi(ld dir, ld dist) { | ||||||
|   | |||||||
| @@ -857,16 +857,18 @@ namespace hr { namespace gp { | |||||||
|     return dmain + length(centerloc-at) - length(centerloc); |     return dmain + length(centerloc-at) - length(centerloc); | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   array<cell*, 3> get_masters(cell *c) { |   array<heptagon*, 3> get_masters(cell *c) { | ||||||
|     if(gp::on) { |     if(gp::on) { | ||||||
|       auto li = get_local_info(c); |       auto li = get_local_info(c); | ||||||
|       be_in_triangle(li);       |       be_in_triangle(li);       | ||||||
|       auto cm = c->master; |       auto cm = c->master; | ||||||
|       int i = li.last_dir; |       int i = li.last_dir; | ||||||
|       return make_array(cm->c7, createStep(cm, i)->c7, createStep(cm, fix7(i+1))->c7); |       return make_array(cm, createStep(cm, i), createStep(cm, fix7(i+1))); | ||||||
|       } |       } | ||||||
|  |     else if(irr::on) | ||||||
|  |       return irr::get_masters(c); | ||||||
|     else |     else | ||||||
|       return make_array(c->mov[0], c->mov[2], c->mov[4]);     |       return make_array(c->mov[0]->master, c->mov[2]->master, c->mov[4]->master); | ||||||
|     } |     } | ||||||
|    |    | ||||||
|   int compute_dist(cell *c, int master_function(cell*)) { |   int compute_dist(cell *c, int master_function(cell*)) { | ||||||
|   | |||||||
							
								
								
									
										26
									
								
								graph.cpp
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								graph.cpp
									
									
									
									
									
								
							| @@ -158,6 +158,7 @@ void drawSpeed(const transmatrix& V) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| int ctof(cell *c) { | int ctof(cell *c) { | ||||||
|  |   if(irr::on) return irr::ctof(c); | ||||||
|   if(nonbitrunc && !gp::on) return 1; |   if(nonbitrunc && !gp::on) return 1; | ||||||
|   // if(euclid) return 0; |   // if(euclid) return 0; | ||||||
|   return ishept(c) ? 1 : 0; |   return ishept(c) ? 1 : 0; | ||||||
| @@ -232,7 +233,14 @@ void drawLightning(const transmatrix& V) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| int displaydir(cell *c, int d) { | int displaydir(cell *c, int d) { | ||||||
|   if(euclid) |   if(irr::on) { | ||||||
|  |     auto id = irr::cellindex[c]; | ||||||
|  |     auto& vs = irr::cells[id]; | ||||||
|  |     if(d < 0 || d >= c->type) return 0; | ||||||
|  |     auto& p = vs.jpoints[vs.neid[d]]; | ||||||
|  |     return -int(atan2(p[1], p[0]) * S84 / 2 / M_PI + MODFIXER + .5); | ||||||
|  |     } | ||||||
|  |   else if(euclid) | ||||||
|     return - d * S84 / c->type; |     return - d * S84 / c->type; | ||||||
|   else |   else | ||||||
|     return S42 - d * S84 / c->type; |     return S42 - d * S84 / c->type; | ||||||
| @@ -2092,7 +2100,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) { | |||||||
|       Vb = Vb * pispin; |       Vb = Vb * pispin; | ||||||
|       Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir)); |       Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir)); | ||||||
|       } |       } | ||||||
|     else if(gp::on) { |     else if(gp::on || irr::on) { | ||||||
|       transmatrix T = shmup::calc_relative_matrix(c->mov[c->mondir], c, c->mondir); |       transmatrix T = shmup::calc_relative_matrix(c->mov[c->mondir], c, c->mondir); | ||||||
|       Vb = Vb * T * rspintox(tC0(inverse(T))) * xpush(tentacle_length); |       Vb = Vb * T * rspintox(tC0(inverse(T))) * xpush(tentacle_length); | ||||||
|       } |       } | ||||||
| @@ -3076,6 +3084,7 @@ bool noAdjacentChasms(cell *c) { | |||||||
|  |  | ||||||
| // does the current geometry allow nice duals | // does the current geometry allow nice duals | ||||||
| bool has_nice_dual() { | bool has_nice_dual() { | ||||||
|  |   if(irr::on) return false; | ||||||
|   if(!nonbitrunc) return true; |   if(!nonbitrunc) return true; | ||||||
|   if((S7 & 1) == 0) return true; |   if((S7 & 1) == 0) return true; | ||||||
|   if(!gp::on) return false; |   if(!gp::on) return false; | ||||||
| @@ -3172,7 +3181,7 @@ bool placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, int col) { | |||||||
|    |    | ||||||
|   transmatrix V2 = V * ddspin(c, i); |   transmatrix V2 = V * ddspin(c, i); | ||||||
|   |   | ||||||
|   if(gp::on) { |   if(gp::on || irr::on) { | ||||||
|     draw_shapevec(c, V2, qfi.fshape->gpside[sidepar][i], col, prio); |     draw_shapevec(c, V2, qfi.fshape->gpside[sidepar][i], col, prio); | ||||||
|     return false; |     return false; | ||||||
|     } |     } | ||||||
| @@ -4024,7 +4033,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | |||||||
|          |          | ||||||
|         case laSwitch: |         case laSwitch: | ||||||
|           set_floor(shSwitchFloor); |           set_floor(shSwitchFloor); | ||||||
|           if(ctof(c)) for(int i=0; i<c->type; i++) |           if(ctof(c) && !gp::on && !irr::on) for(int i=0; i<c->type; i++) | ||||||
|             queuepoly(Vf * ddspin(c, i, S6) * xpush(rhexf), shSwitchDisk, darkena(minf[active_switch()].color, fd, 0xFF)); |             queuepoly(Vf * ddspin(c, i, S6) * xpush(rhexf), shSwitchDisk, darkena(minf[active_switch()].color, fd, 0xFF)); | ||||||
|           break; |           break; | ||||||
|  |  | ||||||
| @@ -4709,7 +4718,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) { | |||||||
|        |        | ||||||
|       int prec = sphere ? 3 : 1; |       int prec = sphere ? 3 : 1; | ||||||
|        |        | ||||||
|       if(gp::on) { |       if(irr::on) { | ||||||
|  |         int id = irr::cellindex[c]; | ||||||
|  |         auto &vs = irr::cells[id]; | ||||||
|  |         for(int t=0; t<c->type; t++) | ||||||
|  |           if(c->mov[t] && c->mov[t] < c) | ||||||
|  |             queueline(V * vs.vertices[t], V * vs.vertices[(1+t)%c->type], gridcolor(c, c->mov[t]), prec); | ||||||
|  |         } | ||||||
|  |       else if(gp::on) { | ||||||
|         vid.linewidth *= gp::scale * 2; |         vid.linewidth *= gp::scale * 2; | ||||||
|         if(isWarped(c) && has_nice_dual()) { |         if(isWarped(c) && has_nice_dual()) { | ||||||
|           if(pseudohept(c)) for(int t=0; t<c->type; t++) |           if(pseudohept(c)) for(int t=0; t<c->type; t++) | ||||||
|   | |||||||
| @@ -75,6 +75,9 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix | |||||||
|   h->move[pard] = parent; tsetspin(h->spintable, pard, d); |   h->move[pard] = parent; tsetspin(h->spintable, pard, d); | ||||||
|   parent->move[d] = h; tsetspin(parent->spintable, d, pard); |   parent->move[d] = h; tsetspin(parent->spintable, d, pard); | ||||||
|   if(parent->c7) { |   if(parent->c7) { | ||||||
|  |     if(irr::on) | ||||||
|  |       irr::link_next(parent, d); | ||||||
|  |     else | ||||||
|       h->c7 = newCell(S7, h); |       h->c7 = newCell(S7, h); | ||||||
|     h->rval0 = h->rval1 = 0; h->cdata = NULL; |     h->rval0 = h->rval1 = 0; h->cdata = NULL; | ||||||
|     h->emeraldval = emerald_heptagon(parent->emeraldval, d); |     h->emeraldval = emerald_heptagon(parent->emeraldval, d); | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								hyper.h
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								hyper.h
									
									
									
									
									
								
							| @@ -78,7 +78,7 @@ void addMessage(string s, char spamtype = 0); | |||||||
| #define S3 ginf[geometry].vertex | #define S3 ginf[geometry].vertex | ||||||
| #define hyperbolic_37 (S7 == 7 && S3 == 3) | #define hyperbolic_37 (S7 == 7 && S3 == 3) | ||||||
| #define hyperbolic_not37 ((S7 > 7 || S3 > 3) && hyperbolic) | #define hyperbolic_not37 ((S7 > 7 || S3 > 3) && hyperbolic) | ||||||
| #define weirdhyperbolic ((S7 > 7 || S3 > 3 || gp::on) && hyperbolic) | #define weirdhyperbolic ((S7 > 7 || S3 > 3 || gp::on || irr::on) && hyperbolic) | ||||||
| #define stdhyperbolic (S7 == 7 && S3 == 3 && !gp::on) | #define stdhyperbolic (S7 == 7 && S3 == 3 && !gp::on) | ||||||
|  |  | ||||||
| #define cgclass (ginf[geometry].cclass) | #define cgclass (ginf[geometry].cclass) | ||||||
| @@ -2549,6 +2549,20 @@ struct hrmap_hyperbolic : hrmap { | |||||||
|   void verify() { verifycells(origin); } |   void verify() { verifycells(origin); } | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|  | namespace quotientspace { hrmap *new_map(); } | ||||||
|  | namespace irr {  | ||||||
|  |   extern bool on; | ||||||
|  |   void link_to_base(heptagon *h, heptspin base); | ||||||
|  |   void link_start(heptagon *h); | ||||||
|  |   void link_next(heptagon *h, int d); | ||||||
|  |   void may_link_next(heptagon *h, int d); | ||||||
|  |   void link_cell(cell *c, int d); | ||||||
|  |   void clear_links(heptagon *h); | ||||||
|  |   bool pseudohept(cell*); | ||||||
|  |   array<heptagon*, 3> get_masters(cell *c); | ||||||
|  |   bool ctof(cell* c); | ||||||
|  |   } | ||||||
|  |  | ||||||
| extern hrmap *currentmap; | extern hrmap *currentmap; | ||||||
| extern vector<hrmap*> allmaps; | extern vector<hrmap*> allmaps; | ||||||
|  |  | ||||||
| @@ -3149,7 +3163,7 @@ namespace gp { | |||||||
|  |  | ||||||
|   int solve_triangle(int dmain, int d0, int d1, loc at); |   int solve_triangle(int dmain, int d0, int d1, loc at); | ||||||
|  |  | ||||||
|   array<cell*, 3> get_masters(cell *c); |   array<heptagon*, 3> get_masters(cell *c); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| int get_sightrange(); | int get_sightrange(); | ||||||
|   | |||||||
							
								
								
									
										16
									
								
								hypgraph.cpp
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								hypgraph.cpp
									
									
									
									
									
								
							| @@ -486,6 +486,8 @@ ld master_to_c7_angle() { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| transmatrix actualV(const heptspin& hs, const transmatrix& V) { | transmatrix actualV(const heptspin& hs, const transmatrix& V) { | ||||||
|  |   if(irr::on) | ||||||
|  |     return V * spin(M_PI + 2 * M_PI / S7 * (hs.spin + irr::periodmap[hs.h].base.spin)); | ||||||
|   return (hs.spin || nonbitrunc) ? V * spin(hs.spin*2*M_PI/S7 + master_to_c7_angle()) : V; |   return (hs.spin || nonbitrunc) ? V * spin(hs.spin*2*M_PI/S7 + master_to_c7_angle()) : V; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -564,10 +566,22 @@ void drawrec(const heptspin& hs, hstate s, const transmatrix& V) { | |||||||
|   transmatrix V10; |   transmatrix V10; | ||||||
|   const transmatrix& V1 = hs.mirrored ? (V10 = V * Mirror) : V; |   const transmatrix& V1 = hs.mirrored ? (V10 = V * Mirror) : V; | ||||||
|    |    | ||||||
|  |   bool draw = c->pathdist < PINFD; | ||||||
|  |    | ||||||
|   if(gp::on) { |   if(gp::on) { | ||||||
|     gp::drawrec(c, actualV(hs, V1)); |     gp::drawrec(c, actualV(hs, V1)); | ||||||
|     } |     } | ||||||
|    |    | ||||||
|  |   else if(irr::on) { | ||||||
|  |     auto& hi = irr::periodmap[hs.h]; | ||||||
|  |     transmatrix V0 = actualV(hs, V1); | ||||||
|  |     auto& vc = irr::cells_of_heptagon[hi.base.h]; | ||||||
|  |     for(int i=0; i<isize(vc); i++) | ||||||
|  |       if(dodrawcell(hi.subcells[i]) && in_qrange(V0 * irr::cells[vc[i]].pusher)) | ||||||
|  |         draw = true, | ||||||
|  |         drawcell(hi.subcells[i], V0 * irr::cells[vc[i]].pusher, 0, false); | ||||||
|  |     } | ||||||
|  |    | ||||||
|   else { |   else { | ||||||
|     if(dodrawcell(c)) { |     if(dodrawcell(c)) { | ||||||
|       transmatrix V2 = actualV(hs, V1); |       transmatrix V2 = actualV(hs, V1); | ||||||
| @@ -585,7 +599,7 @@ void drawrec(const heptspin& hs, hstate s, const transmatrix& V) { | |||||||
|       } |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if(c->pathdist < PINFD && in_qrange(V)) for(int d=0; d<S7; d++) { |   if(draw && in_qrange(V)) for(int d=0; d<S7; d++) { | ||||||
|     hstate s2 = transition(s, d); |     hstate s2 = transition(s, d); | ||||||
|     if(s2 == hsError) continue; |     if(s2 == hsError) continue; | ||||||
|     heptspin hs2 = hs + d + wstep; |     heptspin hs2 = hs + d + wstep; | ||||||
|   | |||||||
							
								
								
									
										530
									
								
								irregular.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										530
									
								
								irregular.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,530 @@ | |||||||
|  | namespace hr { namespace irr { | ||||||
|  |  | ||||||
|  | bool on; | ||||||
|  |  | ||||||
|  | int sc = 100; | ||||||
|  |  | ||||||
|  | struct cellinfo { | ||||||
|  |   cell *owner; | ||||||
|  |   vector<hyperpoint> jpoints; | ||||||
|  |   hyperpoint p; | ||||||
|  |   transmatrix pusher, rpusher; | ||||||
|  |   vector<int> neid; | ||||||
|  |   vector<int> spin; | ||||||
|  |   vector<hyperpoint> vertices; | ||||||
|  |   int localindex; | ||||||
|  |   bool is_pseudohept; | ||||||
|  |   int patterndir; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  | map<cell*, int> cellindex; | ||||||
|  |  | ||||||
|  | vector<cellinfo> cells; | ||||||
|  |  | ||||||
|  | ld inner(hyperpoint h1, hyperpoint h2) { | ||||||
|  |   return  | ||||||
|  |     hyperbolic ? h1[2] * h2[2] - h1[0] * h2[0] - h1[1] * h2[1] : | ||||||
|  |     h1[2] * h2[2] + h1[0] * h2[0] + h1[1] * h2[1]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | hyperpoint circumscribe(hyperpoint a, hyperpoint b, hyperpoint c) { | ||||||
|  |   using namespace hyperpoint_vec; | ||||||
|  |   hyperpoint h = C0; | ||||||
|  |  | ||||||
|  |   b = b - a; | ||||||
|  |   c = c - a; | ||||||
|  |    | ||||||
|  |   if(inner(b,b) < 0) { | ||||||
|  |     b = b / sqrt(-inner(b, b)); | ||||||
|  |     c = c + b * inner(c, b); | ||||||
|  |     h = h + b * inner(h, b); | ||||||
|  |     } | ||||||
|  |   else { | ||||||
|  |     b = b / sqrt(inner(b, b)); | ||||||
|  |     c = c - b * inner(c, b); | ||||||
|  |     h = h - b * inner(h, b); | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |   if(inner(c,c) < 0) { | ||||||
|  |     c = c / sqrt(-inner(c, c)); | ||||||
|  |     h = h + c * inner(h, c); | ||||||
|  |     } | ||||||
|  |   else { | ||||||
|  |     c = c / sqrt(inner(c, c)); | ||||||
|  |     h = h - c * inner(h, c); | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |   if(h[2] < 0) h[0] = -h[0], h[1] = -h[1], h[2] = -h[2]; | ||||||
|  |  | ||||||
|  |   ld i = inner(h, h); | ||||||
|  |   if(i > 0) h /= sqrt(i); | ||||||
|  |   else h /= -sqrt(-i); | ||||||
|  |  | ||||||
|  |   return h; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | bool clockwise(hyperpoint h1, hyperpoint h2) { | ||||||
|  |   return h1[0] * h2[1] > h1[1] * h2[0]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | map<heptagon*, vector<int> > cells_of_heptagon; | ||||||
|  |  | ||||||
|  | int runlevel; | ||||||
|  | vector<ld> edgelens, distlens; | ||||||
|  |  | ||||||
|  | void make_cells_of_heptagon() { | ||||||
|  |   cells_of_heptagon.clear(); | ||||||
|  |   for(int i=0; i<isize(cells); i++) { | ||||||
|  |     auto &p1 = cells[i]; | ||||||
|  |     auto &vc = cells_of_heptagon[p1.owner->master]; | ||||||
|  |     p1.localindex = isize(vc); | ||||||
|  |     vc.push_back(i); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |    | ||||||
|  | hrmap *base; | ||||||
|  |  | ||||||
|  | bool gridmaking; | ||||||
|  |  | ||||||
|  | bool step(int delta) { | ||||||
|  |  | ||||||
|  |   if(!gridmaking) return false; | ||||||
|  |   timetowait = 0; | ||||||
|  |  | ||||||
|  |   auto& all = base->allcells(); | ||||||
|  |  | ||||||
|  |   auto t = SDL_GetTicks(); | ||||||
|  |   while(SDL_GetTicks() < t + 250) | ||||||
|  |   switch(runlevel) { | ||||||
|  |     case 0: { | ||||||
|  |  | ||||||
|  |      cells.clear(); | ||||||
|  |      cells_of_heptagon.clear(); | ||||||
|  |       | ||||||
|  |      if(sc <= isize(all) * 2) { | ||||||
|  |        for(auto h: all) { | ||||||
|  |          cellinfo s; s.patterndir = -1; | ||||||
|  |          s.owner = h, s.p = spin(hrand(1000)) * xpush(.01) * C0; | ||||||
|  |          cells.emplace_back(s); | ||||||
|  |          } | ||||||
|  |        } | ||||||
|  |       runlevel++; | ||||||
|  |       break; | ||||||
|  |       } | ||||||
|  |       | ||||||
|  |     case 1: { | ||||||
|  |       while(isize(cells) < sc) { | ||||||
|  |         if(SDL_GetTicks() > t + 250) { make_cells_of_heptagon(); return false; } | ||||||
|  |         cellinfo s; s.patterndir = -1; | ||||||
|  |         ld bestval = 0; | ||||||
|  |         for(int j=0; j<10; j++) { | ||||||
|  |           int k = hrand(isize(all)); | ||||||
|  |           cell *c = all[k]; | ||||||
|  |           hyperpoint h = randomPointIn(c->type); | ||||||
|  |           ld mindist = 1e6; | ||||||
|  |           for(auto p: cells) { | ||||||
|  |             ld val = hdist(h, shmup::calc_relative_matrix(p.owner, c, h) * p.p); | ||||||
|  |             if(val < mindist) mindist = val; | ||||||
|  |             } | ||||||
|  |           if(mindist > bestval) bestval = mindist, s.owner = c, s.p = h; | ||||||
|  |           } | ||||||
|  |         // printf("%lf %p %s\n", bestval, s.owner, display(s.p)); | ||||||
|  |         cells.emplace_back(s); | ||||||
|  |         } | ||||||
|  |       make_cells_of_heptagon(); | ||||||
|  |       runlevel++; | ||||||
|  |       break; | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |     case 2: { | ||||||
|  |  | ||||||
|  |       sort(cells.begin(), cells.end(), [] (cellinfo &s1, cellinfo &s2) { return hdist0(s1.p) < hdist0(s2.p); }); | ||||||
|  |       make_cells_of_heptagon(); | ||||||
|  |  | ||||||
|  |       edgelens.clear(); | ||||||
|  |       distlens.clear(); | ||||||
|  |    | ||||||
|  |       int stats[16]; | ||||||
|  |       for(int k=0; k<16; k++) stats[k] = 0; | ||||||
|  |        | ||||||
|  |       for(int i=0; i<sc; i++) { | ||||||
|  |         auto &p1 = cells[i]; | ||||||
|  |         p1.vertices.clear(); | ||||||
|  |         p1.neid.clear(); | ||||||
|  |      | ||||||
|  |         p1.pusher = rgpushxto0(p1.p); | ||||||
|  |         p1.rpusher = gpushxto0(p1.p); | ||||||
|  |          | ||||||
|  |         p1.jpoints.clear(); | ||||||
|  |      | ||||||
|  |         for(int j=0; j<sc; j++) { | ||||||
|  |           auto &p2 = cells[j]; | ||||||
|  |           p1.jpoints.push_back(p1.rpusher * shmup::calc_relative_matrix(p2.owner, p1.owner, p1.p) * p2.p); | ||||||
|  |           } | ||||||
|  |      | ||||||
|  |         int j = 0; | ||||||
|  |         if(j == i) j = 1; | ||||||
|  |      | ||||||
|  |         for(int k=0; k<sc; k++) if(k != i) { | ||||||
|  |           if(hdist(p1.jpoints[k], C0) < hdist(p1.jpoints[j], C0)) | ||||||
|  |             j = k; | ||||||
|  |           } | ||||||
|  |            | ||||||
|  |         hyperpoint t = mid(p1.jpoints[j], C0); | ||||||
|  |               // p1.vertices.push_back(p1.pusher * t); | ||||||
|  |         int j0 = j; | ||||||
|  |         int oldj = j; | ||||||
|  |         do { | ||||||
|  |           int best_k = -1; | ||||||
|  |           hyperpoint best_h; | ||||||
|  |           for(int k=0; k<sc; k++) if(k != i && k != j && k != oldj) { | ||||||
|  |             hyperpoint h = circumscribe(C0, p1.jpoints[j], p1.jpoints[k]); | ||||||
|  |             if(h[2] < 0) continue; | ||||||
|  |             if(!clockwise(t, h)) continue; | ||||||
|  |             if(best_k == -1) | ||||||
|  |               best_k = k, best_h = h; | ||||||
|  |             else if(clockwise(h, best_h)) | ||||||
|  |               best_k = k, best_h = h; | ||||||
|  |             } | ||||||
|  |           p1.vertices.push_back(best_h); | ||||||
|  |           p1.neid.push_back(best_k); | ||||||
|  |           distlens.push_back(hdist0(best_h)); | ||||||
|  |           oldj = j, j = best_k, t = best_h; | ||||||
|  |           if(j == -1) break; | ||||||
|  |           if(isize(p1.vertices) == 15) break; | ||||||
|  |           } | ||||||
|  |         while(j != j0); | ||||||
|  |          | ||||||
|  |         for(int j=0; j<isize(p1.vertices); j++) | ||||||
|  |           edgelens.push_back(hdist(p1.vertices[j], p1.vertices[(j+1) % isize(p1.vertices)])); | ||||||
|  |      | ||||||
|  |         stats[isize(p1.vertices)]++; | ||||||
|  |         } | ||||||
|  |      | ||||||
|  |       for(int a=0; a<16; a++) printf("%3d ", stats[a]); | ||||||
|  |       if(isize(edgelens)) { | ||||||
|  |         printf("|"); | ||||||
|  |         printf("%4d ", isize(edgelens)); | ||||||
|  |         sort(edgelens.begin(), edgelens.end()); | ||||||
|  |         for(int a=0; a<=8; a++) printf("%6.3lf", double(edgelens[(a * isize(edgelens) - 1) / 8])); | ||||||
|  |         printf(" | "); | ||||||
|  |         sort(distlens.begin(), distlens.end()); | ||||||
|  |         for(int a=0; a<=8; a++) printf("%5.2lf", double(distlens[(a * isize(edgelens) - 1) / 8])); | ||||||
|  |         } | ||||||
|  |       printf("\n"); | ||||||
|  |        | ||||||
|  |       runlevel++; | ||||||
|  |       break; | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |     case 3: { | ||||||
|  |    | ||||||
|  |       for(int i=0; i<isize(cells); i++) if(isize(cells[i].vertices) > 8 || isize(cells[i].vertices) < 3) { | ||||||
|  |         cells[i] = cells.back(); | ||||||
|  |         i--; cells.pop_back(); | ||||||
|  |         } | ||||||
|  |       if(isize(cells) < sc*3/4) runlevel = 0; | ||||||
|  |       else if(isize(cells) < sc) runlevel = 1; | ||||||
|  |       else runlevel++; | ||||||
|  |       break; | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |     case 4: { | ||||||
|  |    | ||||||
|  |       ld minedge = edgelens[isize(edgelens) / 2] / 5; | ||||||
|  |       if(edgelens[0] < minedge) { | ||||||
|  |         printf("rearranging\n"); | ||||||
|  |         for(int i=0; i<isize(cells); i++) { | ||||||
|  |           auto& p1 = cells[i]; | ||||||
|  |           using namespace hyperpoint_vec; | ||||||
|  |           hyperpoint h = hpxyz(0, 0, 0); | ||||||
|  |           for(auto v: p1.vertices) h = h + v; | ||||||
|  |      | ||||||
|  |           for(int j=0; j<isize(p1.vertices); j++) | ||||||
|  |             if(hdist(p1.vertices[j], p1.vertices[(j+1) % isize(p1.vertices)]) < minedge) | ||||||
|  |               h = h + p1.vertices[j] + p1.vertices[(j+1) % isize(p1.vertices)]; | ||||||
|  |           cells[i].p = p1.pusher * normalize(h); | ||||||
|  |           } | ||||||
|  |         runlevel = 2; | ||||||
|  |         break; | ||||||
|  |         } | ||||||
|  |       runlevel++; | ||||||
|  |       break; | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |     case 5: { | ||||||
|  |        | ||||||
|  |       int notfound = 0; | ||||||
|  |      | ||||||
|  |       for(int i=0; i<sc; i++) { | ||||||
|  |         auto &p1 = cells[i]; | ||||||
|  |         int N = isize(p1.vertices); | ||||||
|  |         p1.spin.resize(N); | ||||||
|  |         for(int j=0; j<N; j++) { | ||||||
|  |           auto i1 = p1.neid[j]; | ||||||
|  |           bool found = false; | ||||||
|  |           for(int k=0; k < isize(cells[i1].vertices); k++) | ||||||
|  |             if(cells[i1].neid[k] == i) | ||||||
|  |               found = true, p1.spin[j] = k; | ||||||
|  |           if(!found) notfound++; | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |        | ||||||
|  |       printf("notfound = %d\n", notfound); | ||||||
|  |       if(notfound) { runlevel = 0; break; } | ||||||
|  |        | ||||||
|  |       int heptas = 0; | ||||||
|  |       for(auto p: cells_of_heptagon) { | ||||||
|  |         printf("%p: %d\n", p.first, isize(p.second)); | ||||||
|  |         heptas++; | ||||||
|  |         } | ||||||
|  |        | ||||||
|  |       if(heptas != isize(all)) { | ||||||
|  |         printf("heptas = %d\n", heptas); | ||||||
|  |         runlevel = 0; break; | ||||||
|  |         } | ||||||
|  |      | ||||||
|  |       for(int i=0; i<sc; i++) { | ||||||
|  |         auto &p1 = cells[i]; | ||||||
|  |         for(int j: p1.neid) { | ||||||
|  |           auto &p2 = cells[j]; | ||||||
|  |           bool ok = p1.owner == p2.owner || isNeighbor(p1.owner, p2.owner); | ||||||
|  |           if(!ok) { printf("far edge\n"); runlevel = 0; return false; } | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       runlevel = 10; | ||||||
|  |        | ||||||
|  |       for(auto& s: cells) s.is_pseudohept = false; | ||||||
|  |       for(auto& s: cells) { | ||||||
|  |         s.is_pseudohept = true; | ||||||
|  |         for(int i: s.neid) if(cells[i].is_pseudohept) s.is_pseudohept = false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |       for(auto& s: cells) { | ||||||
|  |         int d = -1; | ||||||
|  |         ld dist = hcrossf / 2; | ||||||
|  |         ld dists[8]; | ||||||
|  |         for(int i=0; i<S7; i++) { | ||||||
|  |           dists[i] = hdist(s.p, spin(hexshift - i * ALPHA) * xpush(-hcrossf) * C0); | ||||||
|  |           // shmup::calc_relative_matrix(s.owner->mov[i], s.owner, s.p) * C0); | ||||||
|  |           // spin(2 * M_PI * i / S7) * xpush(hcrossf) * C0); | ||||||
|  |           if(dists[i] < dist) | ||||||
|  |             d = i, dist = dists[i];             | ||||||
|  |           } | ||||||
|  |         if(d != -1 && dists[(d+1) % S7] > dists[(d+S7-1) % S7]) | ||||||
|  |           d = (d + S7 - 1) % S7; | ||||||
|  |         s.patterndir = d; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |       break; | ||||||
|  |       } | ||||||
|  |      | ||||||
|  |     case 10: | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | void compute_geometry() { | ||||||
|  |   if(irr::on) { | ||||||
|  |     ld scal = sqrt(isize(cells_of_heptagon) * 1. / sc); | ||||||
|  |     crossf *= scal; | ||||||
|  |     hepvdist *= scal; | ||||||
|  |     rhexf *= scal; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | bool draw_cell_schematics(cell *c, transmatrix V) { | ||||||
|  |   if(gridmaking) { | ||||||
|  |     heptagon *h = c->master; | ||||||
|  |     for(int i: cells_of_heptagon[h]) { | ||||||
|  |       auto& p = cells[i]; | ||||||
|  |       if(p.owner == c) { | ||||||
|  |         queuestr(V * rgpushxto0(p.p), .1, its(i), isize(p.vertices) > 8 ? 0xFF0000 : 0xFFFFFF); | ||||||
|  |         int N = isize(p.vertices); | ||||||
|  |         for(int j=0; j<N; j++) | ||||||
|  |           queueline(V * p.pusher * p.vertices[j], V * p.pusher * p.vertices[(1+j)%N], 0xFFFFFFFF); | ||||||
|  |  | ||||||
|  |         queueline(V * p.p, V * C0, 0xFF0000FF); | ||||||
|  |         if(p.patterndir != -1) | ||||||
|  |           queueline(V * p.p, V * shmup::calc_relative_matrix(c->master->move[p.patterndir]->c7, c, p.p) * C0, 0x00FF00FF); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   return false; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | struct heptinfo { | ||||||
|  |   heptspin base; | ||||||
|  |   vector<cell*> subcells; | ||||||
|  |   }; | ||||||
|  |  | ||||||
|  | map<heptagon*, heptinfo> periodmap; | ||||||
|  |  | ||||||
|  | void link_to_base(heptagon *h, heptspin base) { | ||||||
|  |   // printf("linking %p to %p/%d\n", h, base.h, base.spin); | ||||||
|  |   auto &hi = periodmap[h]; | ||||||
|  |   hi.base = base; | ||||||
|  |   for(int k: cells_of_heptagon[base.h]) { | ||||||
|  |     cell *c = newCell(isize(cells[k].vertices), h); | ||||||
|  |     hi.subcells.push_back(c); | ||||||
|  |     cellindex[c] = k; | ||||||
|  |     } | ||||||
|  |   h->c7 = hi.subcells[0]; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | void clear_links(heptagon *h) { | ||||||
|  |   auto& hi = periodmap[h]; | ||||||
|  |   for(cell *c: hi.subcells) { | ||||||
|  |     for(int i=0; i<c->type; i++) if(c->mov[i]) c->mov[i]->mov[c->spin(i)] = NULL; | ||||||
|  |     cellindex.erase(c); | ||||||
|  |     delete c; | ||||||
|  |     } | ||||||
|  |   h->c7 = NULL; | ||||||
|  |   periodmap.erase(h); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | void link_start(heptagon *h) { | ||||||
|  |   link_to_base(h, heptspin(cells[0].owner->master, 0)); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | void link_next(heptagon *parent, int d) { | ||||||
|  |   if(!periodmap.count(parent)) | ||||||
|  |     link_to_base(parent, heptspin(cells[0].owner->master, 0)); | ||||||
|  |   // printf("linking next: %p direction %d [s%d]\n", parent, d, parent->spin(d)); | ||||||
|  |   auto *h = parent->move[d]; | ||||||
|  |   heptspin hs = periodmap[parent].base + d + wstep - parent->spin(d); | ||||||
|  |   link_to_base(h, hs); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | void may_link_next(heptagon *parent, int d) { | ||||||
|  |   if(!periodmap.count(parent->move[d])) | ||||||
|  |     link_next(parent, d); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void link_cell(cell *c, int d) { | ||||||
|  |   // printf("linking cell: %p direction %d\n", c, d); | ||||||
|  |   int ci = cellindex[c]; | ||||||
|  |   auto& sc = cells[ci]; | ||||||
|  |   int ci2 = sc.neid[d]; | ||||||
|  |   auto& sc2 = cells[ci2]; | ||||||
|  |    | ||||||
|  |   heptagon *master2 = NULL; | ||||||
|  |  | ||||||
|  |   if(sc2.owner == sc.owner) { | ||||||
|  |     master2 = c->master; | ||||||
|  |     // printf("local\n"); | ||||||
|  |     } | ||||||
|  |   else { | ||||||
|  |     int dirs = 0; | ||||||
|  |     int os = periodmap[c->master].base.spin; | ||||||
|  |     for(int d=0; d<S7; d++) if(sc2.owner->master == sc.owner->master->move[(os+d)%S7]) { | ||||||
|  |       heptspin hss(c->master, d); | ||||||
|  |       hss += wstep; | ||||||
|  |       master2 = hss.h; | ||||||
|  |       // printf("master2 is %p; base = %p; should be = %p\n", master2, periodmap[master2].base.h, sc2.owner->master); | ||||||
|  |       dirs++; | ||||||
|  |       } | ||||||
|  |     if(dirs != 1) { printf("dirs error\n"); exit(1); } | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |   cell *c2 = periodmap[master2].subcells[sc2.localindex]; | ||||||
|  |   c->mov[d] = c2; | ||||||
|  |   tsetspin(c->spintable, d, sc.spin[d]); | ||||||
|  |   c2->mov[sc.spin[d]] = c; | ||||||
|  |   tsetspin(c2->spintable, sc.spin[d], d); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | void show_gridmaker() { | ||||||
|  |   cmode = sm::SIDE; | ||||||
|  |   gamescreen(0);   | ||||||
|  |   dialog::init(XLAT("Irregular grid")); | ||||||
|  |   dialog::addSelItem(XLAT("activate"), its(runlevel), 'f'); | ||||||
|  |   dialog::display(); | ||||||
|  |   if(runlevel == 10) dialog::add_action([] { | ||||||
|  |     popScreen(); | ||||||
|  |     pop_game(); | ||||||
|  |     for(hrmap *& hm : allmaps) if(hm == base) hm = NULL; | ||||||
|  |     stop_game(); | ||||||
|  |     irr::on = true; | ||||||
|  |     nonbitrunc = true; | ||||||
|  |     need_reset_geometry = true; | ||||||
|  |     gridmaking = false; | ||||||
|  |     start_game(); | ||||||
|  |     }); | ||||||
|  |   keyhandler = [] (int sym, int uni) { | ||||||
|  |     dialog::handleNavigation(sym, uni); | ||||||
|  |     // no exit | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | void create_map() { | ||||||
|  |   push_game(); | ||||||
|  |   switch(geometry) { | ||||||
|  |     case gNormal: | ||||||
|  |       geometry = gKleinQuartic; | ||||||
|  |       break; | ||||||
|  |      | ||||||
|  |     case gOctagon: | ||||||
|  |       geometry = gBolza2; | ||||||
|  |       break; | ||||||
|  |      | ||||||
|  |     default: ; | ||||||
|  |       break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   nonbitrunc = true; | ||||||
|  |   need_reset_geometry = true; | ||||||
|  |   start_game(); | ||||||
|  |   base = currentmap;  | ||||||
|  |   drawthemap(); | ||||||
|  |   pushScreen(show_gridmaker); | ||||||
|  |   runlevel = 0; | ||||||
|  |   gridmaking = true; | ||||||
|  |   } | ||||||
|  |    | ||||||
|  | int readArgs() { | ||||||
|  |   using namespace arg; | ||||||
|  |             | ||||||
|  |   if(0) ; | ||||||
|  |   else if(argis("-irr")) { | ||||||
|  |     PHASE(3); | ||||||
|  |     shift(); sc = argi(); | ||||||
|  |     restart_game(); | ||||||
|  |     create_map(); | ||||||
|  |     } | ||||||
|  |   else return 1; | ||||||
|  |   return 0; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | bool pseudohept(cell* c) { | ||||||
|  |   return cells[cellindex[c]].is_pseudohept; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | bool ctof(cell* c) { | ||||||
|  |   return cells[cellindex[c]].patterndir == -1; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | array<heptagon*, 3> get_masters(cell *c) { | ||||||
|  |   int d = cells[cellindex[c]].patterndir; | ||||||
|  |   heptspin s = periodmap[c->master].base; | ||||||
|  |   heptspin s0 = heptspin(c->master, 0) + (d - s.spin); | ||||||
|  |   return make_array(s0.h, (s0 + wstep).h, (s0 + 1 + wstep).h); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | auto hook =  | ||||||
|  |   addHook(hooks_args, 100, readArgs) +  | ||||||
|  |   addHook(hooks_drawcell, 100, draw_cell_schematics) + | ||||||
|  |   addHook(shmup::hooks_turn, 100, step); | ||||||
|  |  | ||||||
|  |   }} | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |   if(mouseover && !ctof(mouseover)) { | ||||||
|  |     for(auto h: gp::get_masters(mouseover))  | ||||||
|  |       queueline(shmup::ggmatrix(h->c7)*C0, shmup::ggmatrix(mouseover)*C0, 0xFFFFFFFF); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | */ | ||||||
| @@ -210,14 +210,14 @@ void giantLandSwitch(cell *c, int d, cell *from) { | |||||||
|       else { |       else { | ||||||
|  |  | ||||||
|         if(d == 9) { |         if(d == 9) { | ||||||
|           cell *c2 = gp::on ? c->master->c7 : c; |           cell *c2 = (gp::on || irr::on) ? c->master->c7 : c; | ||||||
|           if(cdist50(c2) == 3 && polarb50(c2) == 1) |           if(cdist50(c2) == 3 && polarb50(c2) == 1) | ||||||
|             c->wall = waPalace; |             c->wall = waPalace; | ||||||
|           } |           } | ||||||
|        |        | ||||||
|         if(d == 8 && sphere) { |         if(d == 8 && sphere) { | ||||||
|           int gs = getHemisphere(c,0); |           int gs = getHemisphere(c,0); | ||||||
|           if(gp::on) { |           if(gp::on || irr::on) { | ||||||
|             int v = 1; |             int v = 1; | ||||||
|             forCellEx(c2, c) if(getHemisphere(c2, 0) != gs) |             forCellEx(c2, c) if(getHemisphere(c2, 0) != gs) | ||||||
|               v = 2; |               v = 2; | ||||||
| @@ -583,7 +583,7 @@ void giantLandSwitch(cell *c, int d, cell *from) { | |||||||
|             else if(v == 25 || v == 59 || v == 27 || v == 57) |             else if(v == 25 || v == 59 || v == 27 || v == 57) | ||||||
|               c->wall = waVineHalfB; |               c->wall = waVineHalfB; | ||||||
|             else c->wall = waNone; |             else c->wall = waNone; | ||||||
|             if(gp::on && cellHalfvine(c)) { |             if((gp::on || irr::on) && cellHalfvine(c)) { | ||||||
|               c->wall = waNone; |               c->wall = waNone; | ||||||
|               forCellCM(c2, c) if(emeraldval(c2) == (v^1)) |               forCellCM(c2, c) if(emeraldval(c2) == (v^1)) | ||||||
|                 c->wall = waVinePlant; |                 c->wall = waVinePlant; | ||||||
|   | |||||||
| @@ -1159,6 +1159,15 @@ land_validity_t& land_validity(eLand l) { | |||||||
|   if(isWarped(l) && a4 && gp::on) |   if(isWarped(l) && a4 && gp::on) | ||||||
|     return dont_work; |     return dont_work; | ||||||
|    |    | ||||||
|  |   if((isWarped(l) || l == laDual) && irr::on) | ||||||
|  |     return dont_work; | ||||||
|  |    | ||||||
|  |   if(irr::on && among(l, laStorms, laPrairie, laBlizzard, laVolcano)) | ||||||
|  |     return dont_work; | ||||||
|  |  | ||||||
|  |   if(irr::on && among(l, laWhirlpool, laCamelot, laCaribbean, laClearing, laTemple, laHive, laMirror, laMirrorOld, laReptile, laKraken, laBurial)) | ||||||
|  |     return dont_work; | ||||||
|  |    | ||||||
|   // equidistant-based lands |   // equidistant-based lands | ||||||
|   if(isEquidLand(l)) { |   if(isEquidLand(l)) { | ||||||
|     // no equidistants supported in chaos mode |     // no equidistants supported in chaos mode | ||||||
|   | |||||||
| @@ -826,7 +826,7 @@ void setAppropriateOverview() { | |||||||
|     pushScreen(yendor::showMenu); |     pushScreen(yendor::showMenu); | ||||||
|   else if(peace::on) |   else if(peace::on) | ||||||
|     pushScreen(peace::showMenu); |     pushScreen(peace::showMenu); | ||||||
|   else if((geometry != gNormal || gp::on) && !chaosmode && !(geometry == gEuclid && isCrossroads(specialland)) && !(weirdhyperbolic && specialland == laCrossroads4)) { |   else if((geometry != gNormal || gp::on || irr::on) && !chaosmode && !(geometry == gEuclid && isCrossroads(specialland)) && !(weirdhyperbolic && specialland == laCrossroads4)) { | ||||||
|     runGeometryExperiments(); |     runGeometryExperiments(); | ||||||
|     } |     } | ||||||
|   else { |   else { | ||||||
|   | |||||||
							
								
								
									
										87
									
								
								pattern2.cpp
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								pattern2.cpp
									
									
									
									
									
								
							| @@ -49,11 +49,13 @@ bool ishex2(cell *c) { | |||||||
|   else return c->type != S6; |   else return c->type != S6; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | int emeraldval(heptagon *h) { return h->emeraldval >> 3; } | ||||||
|  |  | ||||||
| int emeraldval(cell *c) { | int emeraldval(cell *c) { | ||||||
|   if(euclid) return eupattern(c); |   if(euclid) return eupattern(c); | ||||||
|   if(sphere) return 0; |   if(sphere) return 0; | ||||||
|   if(ctof(c)) |   if(ctof(c)) | ||||||
|     return c->master->emeraldval >> 3; |     return emeraldval(c->master); | ||||||
|   else { |   else { | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     return emerald_hexagon( |     return emerald_hexagon( | ||||||
| @@ -96,9 +98,9 @@ int fiftyval(cell *c) { | |||||||
|   else { |   else { | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     return bitmajority( |     return bitmajority( | ||||||
|       fiftyval(ar[0]),  |       ar[0]->fiftyval,  | ||||||
|       fiftyval(ar[1]),  |       ar[1]->fiftyval,  | ||||||
|       fiftyval(ar[2])) + 512; |       ar[2]->fiftyval) + 512; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -109,47 +111,47 @@ int cdist50(cell *c) { | |||||||
|       return "0123333332112332223322233211233333322"[eufifty(c)] - '0'; |       return "0123333332112332223322233211233333322"[eufifty(c)] - '0'; | ||||||
|     else return "012333321112322232222321123"[eufifty(c)] - '0'; |     else return "012333321112322232222321123"[eufifty(c)] - '0'; | ||||||
|     } |     } | ||||||
|   if(c->type != 6) return cdist50(fiftyval(c)); |   if(ctof(c)) return cdist50(c->master->fiftyval); | ||||||
|   auto ar = gp::get_masters(c); |   auto ar = gp::get_masters(c); | ||||||
|   int a0 = cdist50(ar[0]); |   int a0 = cdist50(ar[0]->fiftyval); | ||||||
|   int a1 = cdist50(ar[1]); |   int a1 = cdist50(ar[1]->fiftyval); | ||||||
|   int a2 = cdist50(ar[2]); |   int a2 = cdist50(ar[2]->fiftyval); | ||||||
|   if(a0 == 0 || a1 == 0 || a2 == 0) return 1; |   if(a0 == 0 || a1 == 0 || a2 == 0) return 1; | ||||||
|   return a0+a1+a2-5; |   return a0+a1+a2-5; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| int land50(cell *c) { | int land50(cell *c) { | ||||||
|   if(c->type != 6) return land50(fiftyval(c)); |   if(sphere || euclid) return 0; | ||||||
|   else if(sphere || euclid) return 0; |   else if(ctof(c)) return land50(fiftyval(c)); | ||||||
|   else { |   else { | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     for(int i=0; i<3; i++) |     for(int i=0; i<3; i++) | ||||||
|       if(cdist50(ar[i]) < 3) return land50(ar[i]); |       if(cdist50(ar[i]->fiftyval) < 3) return land50(ar[i]->fiftyval); | ||||||
|     return 0; |     return 0; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| int polara50(cell *c) { | int polara50(cell *c) { | ||||||
|   if(c->type != 6) return polara50(fiftyval(c)); |   if(sphere || euclid || S7>7 || S6>6) return 0; | ||||||
|   else if(sphere || euclid || S7>7 || S6>6) return 0; |   else if(gp::on || irr::on) return polara50(fiftyval(c->master->c7)); | ||||||
|   else if(gp::on) return polara50(fiftyval(c->master->c7)); |   else if(ctof(c)) return polara50(fiftyval(c)); | ||||||
|   else { |   else { | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     for(int i=0; i<3; i++) |     for(int i=0; i<3; i++) | ||||||
|       if(cdist50(ar[i]) < 3) return polara50(ar[i]); |       if(cdist50(ar[i]->fiftyval) < 3) return polara50(ar[i]->fiftyval); | ||||||
|     return 0; |     return 0; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| int polarb50(cell *c) { | int polarb50(cell *c) { | ||||||
|   if(euclid) return true; |   if(euclid) return true; | ||||||
|   if(c->type != 6) return polarb50(fiftyval(c)); |   if(sphere || euclid || S7>7 || S6>6) return true; | ||||||
|   else if(sphere || euclid || S7>7 || S6>6) return true; |   else if(gp::on || irr::on) return polarb50(fiftyval(c->master->c7)); | ||||||
|   else if(gp::on) return polarb50(fiftyval(c->master->c7)); |   else if(ctof(c)) return polarb50(fiftyval(c)); | ||||||
|   else { |   else { | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     for(int i=0; i<3; i++) |     for(int i=0; i<3; i++) | ||||||
|       if(cdist50(ar[i]) < 3) return polarb50(ar[i]); |       if(cdist50(ar[i]->fiftyval) < 3) return polarb50(ar[i]->fiftyval); | ||||||
|     return 0; |     return 0; | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -158,30 +160,32 @@ int elhextable[28][3] = { | |||||||
|   {0,1,2}, {1,2,9}, {1,9,-1}, {1,8,-1}, {1,-1,-1} |   {0,1,2}, {1,2,9}, {1,9,-1}, {1,8,-1}, {1,-1,-1} | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
| int fiftyval049(cell *c) { | int fiftyval049(heptagon *h) { | ||||||
|   if(euclid) return fiftyval(c) / 32; |   int i = h->fiftyval / 32; | ||||||
|   else if(ctof(c)) { |  | ||||||
|     int i = fiftyval(c) / 32; |  | ||||||
|   if(i <= 7) return i; |   if(i <= 7) return i; | ||||||
|   if(quotient) return 0; |   if(quotient) return 0; | ||||||
|   vector<int> allcodes; |   vector<int> allcodes; | ||||||
|   for(int k=0; k<7; k++) { |   for(int k=0; k<7; k++) { | ||||||
|       cell *c2 = createStep(c->master, k)->c7; |     heptagon *h2 = createStep(h, k); | ||||||
|       if(polara50(c2) == polara50(c) && polarb50(c2) == polarb50(c))         |     if(polara50(h2->fiftyval) == polara50(h->fiftyval) && polarb50(h2->fiftyval) == polarb50(h->fiftyval)) | ||||||
|         allcodes.push_back(fiftyval049(c2)); |       allcodes.push_back(fiftyval049(h2)); | ||||||
|     } |     } | ||||||
|   int d = allcodes[1] - allcodes[0]; |   int d = allcodes[1] - allcodes[0]; | ||||||
|   if(d == -1 || d == 6) swap(allcodes[0], allcodes[1]); |   if(d == -1 || d == 6) swap(allcodes[0], allcodes[1]); | ||||||
|   // printf("%d,%d: %d\n", allcodes[0], allcodes[1], allcodes[0] + 7); |   // printf("%d,%d: %d\n", allcodes[0], allcodes[1], allcodes[0] + 7); | ||||||
|   return allcodes[0] + 7; |   return allcodes[0] + 7; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | int fiftyval049(cell *c) { | ||||||
|  |   if(euclid) return fiftyval(c) / 32; | ||||||
|  |   else if(ctof(c)) return fiftyval049(c->master); | ||||||
|   else if(sphere) return 0; |   else if(sphere) return 0; | ||||||
|   else { |   else { | ||||||
|     int a[3], qa=0; |     int a[3], qa=0; | ||||||
|     int pa = polara50(c), pb = polarb50(c); |     int pa = polara50(c), pb = polarb50(c); | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     for(int i=0; i<3; i++) |     for(int i=0; i<3; i++) | ||||||
|       if(polara50(ar[i]) == pa && polarb50(ar[i]) == pb) |       if(polara50(ar[i]->fiftyval) == pa && polarb50(ar[i]->fiftyval) == pb) | ||||||
|         a[qa++] = fiftyval049(ar[i]); |         a[qa++] = fiftyval049(ar[i]); | ||||||
|     // 0-1-2 |     // 0-1-2 | ||||||
|     sort(a, a+qa); |     sort(a, a+qa); | ||||||
| @@ -248,6 +252,7 @@ int val46(cell *c); | |||||||
|  |  | ||||||
| int zebra40(cell *c) { | int zebra40(cell *c) { | ||||||
|   if(euclid) return eupattern(c); |   if(euclid) return eupattern(c); | ||||||
|  |   else if(irr::on) return c->master->zebraval/10; | ||||||
|   else if(a46) { |   else if(a46) { | ||||||
|     int v = val46(c); |     int v = val46(c); | ||||||
|     if(v<4) return v; |     if(v<4) return v; | ||||||
| @@ -285,9 +290,9 @@ int zebra40(cell *c) { | |||||||
|   else { |   else { | ||||||
|     int ii[3], z; |     int ii[3], z; | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     ii[0] = (ar[0]->master->zebraval/10); |     ii[0] = (ar[0]->zebraval/10); | ||||||
|     ii[1] = (ar[1]->master->zebraval/10); |     ii[1] = (ar[1]->zebraval/10); | ||||||
|     ii[2] = (ar[2]->master->zebraval/10); |     ii[2] = (ar[2]->zebraval/10); | ||||||
|     for(int r=0; r<2; r++)  |     for(int r=0; r<2; r++)  | ||||||
|       if(ii[1] < ii[0] || ii[2] < ii[0])  |       if(ii[1] < ii[0] || ii[2] < ii[0])  | ||||||
|         z = ii[0], ii[0] = ii[1], ii[1] = ii[2], ii[2] = z; |         z = ii[0], ii[0] = ii[1], ii[1] = ii[2], ii[2] = z; | ||||||
| @@ -304,14 +309,14 @@ int zebra40(cell *c) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| int zebra3(cell *c) { | int zebra3(cell *c) { | ||||||
|   if(c->type != 6) return (c->master->zebraval/10)/4; |   if(ctof(c)) return (c->master->zebraval/10)/4; | ||||||
|   else if(sphere || S7>7 || S6>6) return 0; |   else if(euclid || sphere || S7>7 || S6>6) return 0; | ||||||
|   else {  |   else {  | ||||||
|     int ii[3]; |     int ii[3]; | ||||||
|     auto ar = gp::get_masters(c); |     auto ar = gp::get_masters(c); | ||||||
|     ii[0] = (ar[0]->master->zebraval/10)/4; |     ii[0] = (ar[0]->zebraval/10)/4; | ||||||
|     ii[1] = (ar[1]->master->zebraval/10)/4; |     ii[1] = (ar[1]->zebraval/10)/4; | ||||||
|     ii[2] = (ar[2]->master->zebraval/10)/4; |     ii[2] = (ar[2]->zebraval/10)/4; | ||||||
|     if(ii[0] == ii[1]) return ii[0]; |     if(ii[0] == ii[1]) return ii[0]; | ||||||
|     if(ii[1] == ii[2]) return ii[1]; |     if(ii[1] == ii[2]) return ii[1]; | ||||||
|     if(ii[2] == ii[0]) return ii[2]; |     if(ii[2] == ii[0]) return ii[2]; | ||||||
| @@ -328,7 +333,7 @@ pair<int, bool> fieldval(cell *c) { | |||||||
|  |  | ||||||
| int fieldval_uniq(cell *c) { | int fieldval_uniq(cell *c) { | ||||||
|   if(sphere) { |   if(sphere) { | ||||||
|     if(ctof(c)) return c->master->fieldval; |     if(ctof(c) || gp::on || irr::on) return c->master->fieldval; | ||||||
|     else return createMov(c, 0)->master->fieldval + 256 * createMov(c,2)->master->fieldval + (1<<16) * createMov(c,4)->master->fieldval; |     else return createMov(c, 0)->master->fieldval + 256 * createMov(c,2)->master->fieldval + (1<<16) * createMov(c,4)->master->fieldval; | ||||||
|     } |     } | ||||||
|   else if(torus) { |   else if(torus) { | ||||||
| @@ -338,7 +343,7 @@ int fieldval_uniq(cell *c) { | |||||||
|     auto p = cell_to_pair(c); |     auto p = cell_to_pair(c); | ||||||
|     return gmod(p.first * torusconfig::dx + p.second * torusconfig::dy, torusconfig::qty); |     return gmod(p.first * torusconfig::dx + p.second * torusconfig::dy, torusconfig::qty); | ||||||
|     } |     } | ||||||
|   if(ctof(c) || gp::on) return c->master->fieldval/S7; |   if(ctof(c) || gp::on || irr::on) return c->master->fieldval/S7; | ||||||
|   else { |   else { | ||||||
|     int z = 0; |     int z = 0; | ||||||
|     for(int u=0; u<S6; u+=2)  |     for(int u=0; u<S6; u+=2)  | ||||||
| @@ -348,7 +353,7 @@ int fieldval_uniq(cell *c) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| int fieldval_uniq_rand(cell *c, int randval) { | int fieldval_uniq_rand(cell *c, int randval) { | ||||||
|   if(sphere || torus || euclid)  |   if(sphere || torus || euclid || gp::on || irr::on)  | ||||||
|     // we do not care in these cases |     // we do not care in these cases | ||||||
|     return fieldval_uniq(c); |     return fieldval_uniq(c); | ||||||
|   if(ctof(c)) return currfp.gmul(c->master->fieldval, randval)/7; |   if(ctof(c)) return currfp.gmul(c->master->fieldval, randval)/7; | ||||||
| @@ -708,7 +713,8 @@ namespace patterns { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|   void val_all(cell *c, patterninfo &si, int sub, int pat) { |   void val_all(cell *c, patterninfo &si, int sub, int pat) { | ||||||
|     if(a46) val46(c, si, sub, pat); |     if(irr::on) si.symmetries = 1; | ||||||
|  |     else if(a46) val46(c, si, sub, pat); | ||||||
|     else if(a38) val38(c, si, sub, pat); |     else if(a38) val38(c, si, sub, pat); | ||||||
|     else if(sphere) valSibling(c, si, sub, pat); |     else if(sphere) valSibling(c, si, sub, pat); | ||||||
|     else if(euclid4) valEuclid4(c, si, sub); |     else if(euclid4) valEuclid4(c, si, sub); | ||||||
| @@ -1005,6 +1011,7 @@ namespace patterns { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| int geosupport_threecolor() { | int geosupport_threecolor() { | ||||||
|  |   if(irr::on) return 0; | ||||||
|   if(!nonbitrunc && S3 == 3) { |   if(!nonbitrunc && S3 == 3) { | ||||||
|     if(S7 % 2) return 1; |     if(S7 % 2) return 1; | ||||||
|     return 2; |     return 2; | ||||||
| @@ -1019,6 +1026,7 @@ int geosupport_threecolor() { | |||||||
| int geosupport_graveyard() { | int geosupport_graveyard() { | ||||||
|   // always works in bitrunc geometries |   // always works in bitrunc geometries | ||||||
|   if(!nonbitrunc) return 2; |   if(!nonbitrunc) return 2; | ||||||
|  |   if(irr::on) return 0; | ||||||
|    |    | ||||||
|   // always works in patterns supporting three-color |   // always works in patterns supporting three-color | ||||||
|   int tc = max(geosupport_threecolor(), gp_threecolor()); |   int tc = max(geosupport_threecolor(), gp_threecolor()); | ||||||
| @@ -1130,6 +1138,7 @@ int pattern_threecolor(cell *c) { | |||||||
| // in the 'pure heptagonal' tiling, returns true for a set of cells | // in the 'pure heptagonal' tiling, returns true for a set of cells | ||||||
| // which roughly corresponds to the heptagons in the normal tiling | // which roughly corresponds to the heptagons in the normal tiling | ||||||
| bool pseudohept(cell *c) { | bool pseudohept(cell *c) { | ||||||
|  |   if(irr::on) return irr::pseudohept(c); | ||||||
|   if(gp::on && gp_threecolor() == 2) |   if(gp::on && gp_threecolor() == 2) | ||||||
|     return gp::pseudohept_val(c) == 0; |     return gp::pseudohept_val(c) == 0; | ||||||
|   if(gp::on && gp_threecolor() == 1 && (S7&1) && (S3 == 3)) |   if(gp::on && gp_threecolor() == 1 && (S7&1) && (S3 == 3)) | ||||||
|   | |||||||
| @@ -3313,7 +3313,12 @@ void destroyBoats(cell *c) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
| transmatrix master_relative(cell *c, bool get_inverse) { | transmatrix master_relative(cell *c, bool get_inverse) { | ||||||
|   if(gp::on) { |   if(irr::on) { | ||||||
|  |     int id = irr::cellindex[c]; | ||||||
|  |     ld alpha = 2 * M_PI / S7 * irr::periodmap[c->master].base.spin; | ||||||
|  |     return get_inverse ? irr::cells[id].rpusher * spin(-alpha-master_to_c7_angle()): spin(alpha + master_to_c7_angle()) * irr::cells[id].pusher; | ||||||
|  |     } | ||||||
|  |   else if(gp::on) { | ||||||
|     if(c == c->master->c7) { |     if(c == c->master->c7) { | ||||||
|       return spin((get_inverse?-1:1) * master_to_c7_angle()); |       return spin((get_inverse?-1:1) * master_to_c7_angle()); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -1029,10 +1029,10 @@ namespace gamestack { | |||||||
|   bool pushed() { return isize(gd); } |   bool pushed() { return isize(gd); } | ||||||
|    |    | ||||||
|   void push() { |   void push() { | ||||||
|     if(geometry) { |     /* if(geometry) { | ||||||
|       printf("ERROR: push implemented only in non-hyperbolic geometry\n"); |       printf("ERROR: push implemented only in non-hyperbolic geometry\n"); | ||||||
|       exit(1); |       exit(1); | ||||||
|       } |       } */ | ||||||
|     gamedata gdn; |     gamedata gdn; | ||||||
|     gdn.hmap = currentmap; |     gdn.hmap = currentmap; | ||||||
|     gdn.cwt = cwt; |     gdn.cwt = cwt; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Zeno Rogue
					Zeno Rogue