mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-02 12:19:18 +00:00
crystal:: started working on lands (Camelot done) and distances
This commit is contained in:
parent
000f271552
commit
50f37a6b63
168
crystal.cpp
168
crystal.cpp
@ -18,10 +18,15 @@ typedef array<ld, MAXDIM> ldcoord;
|
|||||||
static const ldcoord ldc0 = {};
|
static const ldcoord ldc0 = {};
|
||||||
|
|
||||||
ldcoord told(coord c) { ldcoord a; for(int i=0; i<MAXDIM; i++) a[i] = c[i]; return a; }
|
ldcoord told(coord c) { ldcoord a; for(int i=0; i<MAXDIM; i++) a[i] = c[i]; return a; }
|
||||||
|
coord roundcoord(ldcoord c) { coord a; for(int i=0; i<MAXDIM; i++) a[i] = floor(c[i] + .5); return a; }
|
||||||
|
// coord roundcoord_modulo(ldcoord c) { coord a; for(int i=0; i<MAXDIM; i++) a[i] = (floor(c[i] + .5) * 61 / 4) % 61; return a; }
|
||||||
|
|
||||||
ldcoord operator + (ldcoord a, ldcoord b) { ldcoord r; for(int i=0; i<MAXDIM; i++) r[i] = a[i] + b[i]; return r; }
|
ldcoord operator + (ldcoord a, ldcoord b) { ldcoord r; for(int i=0; i<MAXDIM; i++) r[i] = a[i] + b[i]; return r; }
|
||||||
ldcoord operator * (ldcoord a, int v) { ldcoord r; for(int i=0; i<MAXDIM; i++) r[i] = a[i] * v; return r; }
|
ldcoord operator - (ldcoord a, ldcoord b) { ldcoord r; for(int i=0; i<MAXDIM; i++) r[i] = a[i] - b[i]; return r; }
|
||||||
ldcoord operator / (ldcoord a, int v) { ldcoord r; for(int i=0; i<MAXDIM; i++) r[i] = a[i] / v; return r; }
|
ldcoord operator * (ldcoord a, ld v) { ldcoord r; for(int i=0; i<MAXDIM; i++) r[i] = a[i] * v; return r; }
|
||||||
|
ldcoord operator / (ldcoord a, ld v) { ldcoord r; for(int i=0; i<MAXDIM; i++) r[i] = a[i] / v; return r; }
|
||||||
|
|
||||||
|
ld operator | (ldcoord a, ldcoord b) { ld r=0; for(int i=0; i<MAXDIM; i++) r += a[i] * b[i]; return r; }
|
||||||
|
|
||||||
int tocode(int cname) { return (1 << (cname >> 1)); }
|
int tocode(int cname) { return (1 << (cname >> 1)); }
|
||||||
|
|
||||||
@ -245,12 +250,15 @@ struct crystal_structure {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct lwalker {
|
struct lwalker {
|
||||||
crystal_structure cs;
|
crystal_structure& cs;
|
||||||
int id;
|
int id;
|
||||||
int spin;
|
int spin;
|
||||||
|
lwalker(crystal_structure& cs) : cs(cs) {}
|
||||||
|
void operator = (const lwalker& x) { id = x.id; spin = x.spin; }
|
||||||
};
|
};
|
||||||
|
|
||||||
lwalker operator +(lwalker a, int v) { a.spin = gmod(a.spin + v, a.cs.dir); return a; }
|
lwalker operator +(lwalker a, int v) { a.spin = gmod(a.spin + v, a.cs.dir); return a; }
|
||||||
|
|
||||||
lwalker operator +(lwalker a, wstep_t) {
|
lwalker operator +(lwalker a, wstep_t) {
|
||||||
a.spin = a.cs.cmap[a.id][a.spin];
|
a.spin = a.cs.cmap[a.id][a.spin];
|
||||||
a.id ^= tocode(a.spin);
|
a.id ^= tocode(a.spin);
|
||||||
@ -260,12 +268,15 @@ lwalker operator +(lwalker a, wstep_t) {
|
|||||||
|
|
||||||
coord add(coord c, lwalker a, int val) {
|
coord add(coord c, lwalker a, int val) {
|
||||||
int code = a.cs.cmap[a.id][a.spin];
|
int code = a.cs.cmap[a.id][a.spin];
|
||||||
c[code>>1] += (code&1) ? val : -val;
|
c[code>>1] += ((code&1) ? val : -val);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<heptagon*, coord> hcoords;
|
map<heptagon*, coord> hcoords;
|
||||||
map<coord, heptagon*> heptagon_at;
|
map<coord, heptagon*> heptagon_at;
|
||||||
|
map<int, eLand> landmemo;
|
||||||
|
unordered_map<cell*, unordered_map<cell*, int>> distmemo;
|
||||||
|
map<cell*, ldcoord> sgc;
|
||||||
|
|
||||||
crystal_structure cs;
|
crystal_structure cs;
|
||||||
|
|
||||||
@ -276,8 +287,7 @@ coord add(coord c, int cname, int val) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
lwalker makewalker(crystal_structure& cs, coord c, int d) {
|
lwalker makewalker(crystal_structure& cs, coord c, int d) {
|
||||||
lwalker a;
|
lwalker a(cs);
|
||||||
a.cs = cs;
|
|
||||||
a.id = 0;
|
a.id = 0;
|
||||||
for(int i=0; i<cs.dim; i++) if(c[i] & FULLSTEP) a.id += (1<<i);
|
for(int i=0; i<cs.dim; i++) if(c[i] & FULLSTEP) a.id += (1<<i);
|
||||||
a.spin = d;
|
a.spin = d;
|
||||||
@ -302,14 +312,18 @@ heptagon *get_heptagon_at(coord c, int deg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ldcoord get_coord(cell *c) {
|
ldcoord get_coord(cell *c) {
|
||||||
|
auto b = sgc.emplace(c, ldc0);
|
||||||
|
ldcoord& res = b.first->second;
|
||||||
|
if(b.second) {
|
||||||
if(c->master->c7 != c) {
|
if(c->master->c7 != c) {
|
||||||
ldcoord res = ldc0;
|
|
||||||
for(int i=0; i<c->type; i+=2)
|
for(int i=0; i<c->type; i+=2)
|
||||||
res = res + told(hcoords[c->cmove(i)->master]);
|
res = res + told(hcoords[c->cmove(i)->master]);
|
||||||
return res * 2 / c->type;
|
res = res * 2 / c->type;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return told(hcoords[c->master]);
|
res = told(hcoords[c->master]);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hrmap_crystal : hrmap {
|
struct hrmap_crystal : hrmap {
|
||||||
@ -319,6 +333,14 @@ struct hrmap_crystal : hrmap {
|
|||||||
cs.build();
|
cs.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~hrmap_crystal() {
|
||||||
|
hcoords.clear();
|
||||||
|
heptagon_at.clear();
|
||||||
|
distmemo.clear();
|
||||||
|
landmemo.clear();
|
||||||
|
sgc.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void verify() { }
|
void verify() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -414,20 +436,114 @@ bool crystal_cell(cell *c, transmatrix V) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int hypot2(coord co1, coord co2) {
|
ld hypot2(ldcoord co1, ldcoord co2) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for(int a=0; a<cs.dim; a++) result += (co1[a] - co2[a]) * (co1[a] - co2[a]);
|
for(int a=0; a<cs.dim; a++) result += (co1[a] - co2[a]) * (co1[a] - co2[a]);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int distance(cell *c1, cell *c2) {
|
int precise_distance(cell *c1, cell *c2) {
|
||||||
if(true || (PURE && !add_bitruncation)) {
|
if(c1 == c2) return 0;
|
||||||
|
if(PURE && !add_bitruncation) {
|
||||||
coord co1 = hcoords[c1->master];
|
coord co1 = hcoords[c1->master];
|
||||||
coord co2 = hcoords[c2->master];
|
coord co2 = hcoords[c2->master];
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for(int a=0; a<cs.dim; a++) result += abs(co1[a] - co2[a]);
|
for(int a=0; a<cs.dim; a++) result += abs(co1[a] - co2[a]);
|
||||||
return result / FULLSTEP;
|
return result / FULLSTEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(c2 == currentmap->gamestart()) swap(c1, c2);
|
||||||
|
else if(isize(distmemo[c2]) > isize(distmemo[c1])) swap(c1, c2);
|
||||||
|
|
||||||
|
if(distmemo[c1].count(c2)) return distmemo[c1][c2];
|
||||||
|
|
||||||
|
int zmin = 999999, zmax = -99;
|
||||||
|
forCellEx(c3, c2) if(distmemo[c1].count(c3)) {
|
||||||
|
int d = distmemo[c1][c3];
|
||||||
|
if(d < zmin) zmin = d;
|
||||||
|
if(d > zmax) zmax = d;
|
||||||
|
}
|
||||||
|
if(zmin+1 < zmax-1) println(hlog, "zmin < zmax");
|
||||||
|
if(zmin+1 == zmax-1) return distmemo[c1][c2] = zmin+1;
|
||||||
|
|
||||||
|
ldcoord co1 = get_coord(c1);
|
||||||
|
ldcoord co2 = get_coord(c2) - co1;
|
||||||
|
|
||||||
|
// draw a cylinder from co1 to co2, and find the solution by going through that cylinder
|
||||||
|
|
||||||
|
ldcoord mul = co2 / sqrt(co2|co2);
|
||||||
|
|
||||||
|
ld mmax = (co2|mul);
|
||||||
|
|
||||||
|
manual_celllister cl;
|
||||||
|
cl.add(c2);
|
||||||
|
|
||||||
|
int steps = 0;
|
||||||
|
int nextsteps = 1;
|
||||||
|
|
||||||
|
for(int i=0; i<isize(cl.lst); i++) {
|
||||||
|
if(i == nextsteps) steps++, nextsteps = isize(cl.lst);
|
||||||
|
cell *c = cl.lst[i];
|
||||||
|
forCellCM(c3, c) if(!cl.listed(c3)) {
|
||||||
|
if(c3 == c1) {
|
||||||
|
return distmemo[c1][c2] = distmemo[c2][c1] = 1 + steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto h = get_coord(c3) - co1;
|
||||||
|
ld dot = (h|mul);
|
||||||
|
if(dot > mmax + 2.5) continue;
|
||||||
|
|
||||||
|
for(int k=0; k<cs.dim; k++) if(abs(h[k] - dot * mul[k]) > 4.1) goto next3;
|
||||||
|
cl.add(c3);
|
||||||
|
next3: ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println(hlog, "Error: distance not found");
|
||||||
|
return 999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
cell *camelot_center;
|
||||||
|
|
||||||
|
ld space_distance(cell *c1, cell *c2) {
|
||||||
|
ldcoord co1 = get_coord(c1);
|
||||||
|
ldcoord co2 = get_coord(c2);
|
||||||
|
return sqrt(hypot2(co1, co2));
|
||||||
|
}
|
||||||
|
|
||||||
|
int dist_relative(cell *c) {
|
||||||
|
int r = roundTableRadius(NULL);
|
||||||
|
cell *start = currentmap->gamestart();
|
||||||
|
if(!camelot_center) {
|
||||||
|
printf("Finding Camelot center...");
|
||||||
|
camelot_center = start;
|
||||||
|
while(precise_distance(camelot_center, start) < r + 5)
|
||||||
|
camelot_center = camelot_center->cmove(hrand(camelot_center->type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(PURE && !add_bitruncation)
|
||||||
|
return precise_distance(c, camelot_center) - r;
|
||||||
|
|
||||||
|
ld sdmul = (r+5) / space_distance(camelot_center, start);
|
||||||
|
ld dis = space_distance(camelot_center, c) * sdmul;
|
||||||
|
println(hlog, "dis = ", dis);
|
||||||
|
if(dis < r)
|
||||||
|
return int(dis) - r;
|
||||||
|
else {
|
||||||
|
forCellCM(c1, c) if(space_distance(camelot_center, c1) * sdmul < r)
|
||||||
|
return 0;
|
||||||
|
return int(dis) + 1 - r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int dist_alt(cell *c) {
|
||||||
|
if(specialland == laCamelot && camelot_center) {
|
||||||
|
if(PURE && !add_bitruncation)
|
||||||
|
return precise_distance(c, camelot_center);
|
||||||
|
if(c == camelot_center) return 0;
|
||||||
|
return 1 + int(space_distance(camelot_center, c));
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ld crug_rotation[MAXDIM][MAXDIM];
|
ld crug_rotation[MAXDIM][MAXDIM];
|
||||||
@ -513,6 +629,34 @@ void build_rugdata() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eLand getCLand(int x) {
|
||||||
|
if(landmemo.count(x)) return landmemo[x];
|
||||||
|
if(x > 0) return landmemo[x] = getNewLand(landmemo[x-1]);
|
||||||
|
if(x < 0) return landmemo[x] = getNewLand(landmemo[x+1]);
|
||||||
|
return landmemo[x] = laCrossroads;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_land(cell *c) {
|
||||||
|
setland(c, specialland);
|
||||||
|
|
||||||
|
auto co = get_coord(c);
|
||||||
|
auto co1 = roundcoord(co * 60);
|
||||||
|
int cv = co1[0];
|
||||||
|
|
||||||
|
if(specialland == laCrossroads) {
|
||||||
|
eLand l1 = getCLand(gdiv(cv, 360));
|
||||||
|
eLand l2 = getCLand(gdiv(cv+59, 360));
|
||||||
|
if(l1 != l2) setland(c, laBarrier);
|
||||||
|
else setland(c, l1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(specialland == laCamelot) {
|
||||||
|
setland(c, laCrossroads);
|
||||||
|
buildCamelot(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int readArgs() {
|
int readArgs() {
|
||||||
using namespace arg;
|
using namespace arg;
|
||||||
|
|
||||||
|
@ -114,7 +114,9 @@ transmatrix calc_relative_matrix(cell *c2, cell *c1, const hyperpoint& point_hin
|
|||||||
//bool hsol = false;
|
//bool hsol = false;
|
||||||
//transmatrix sol;
|
//transmatrix sol;
|
||||||
|
|
||||||
|
int steps = 0;
|
||||||
while(h1 != h2) {
|
while(h1 != h2) {
|
||||||
|
steps++; if(steps > 100) { println(hlog, "not found"); return Id; }
|
||||||
if(smallbounded && quotient) {
|
if(smallbounded && quotient) {
|
||||||
transmatrix T;
|
transmatrix T;
|
||||||
ld bestdist = 1e9;
|
ld bestdist = 1e9;
|
||||||
|
8
hyper.h
8
hyper.h
@ -91,7 +91,7 @@ void addMessage(string s, char spamtype = 0);
|
|||||||
|
|
||||||
#define binarytiling (geometry == gBinaryTiling)
|
#define binarytiling (geometry == gBinaryTiling)
|
||||||
#define archimedean (geometry == gArchimedean)
|
#define archimedean (geometry == gArchimedean)
|
||||||
#define eubinary (euclid || binarytiling)
|
#define eubinary (euclid || binarytiling || geometry == gCrystal)
|
||||||
|
|
||||||
#define cgclass (ginf[geometry].cclass)
|
#define cgclass (ginf[geometry].cclass)
|
||||||
#define euclid (cgclass == gcEuclid)
|
#define euclid (cgclass == gcEuclid)
|
||||||
@ -3392,6 +3392,7 @@ hyperpoint xspinpush0(ld alpha, ld x);
|
|||||||
extern FILE *debugfile;
|
extern FILE *debugfile;
|
||||||
extern int debugflags;
|
extern int debugflags;
|
||||||
int gmod(int i, int j);
|
int gmod(int i, int j);
|
||||||
|
int gdiv(int i, int j);
|
||||||
extern walltype winf[walltypes];
|
extern walltype winf[walltypes];
|
||||||
extern vector<landtacinfo> land_tac;
|
extern vector<landtacinfo> land_tac;
|
||||||
string llts(long long i);
|
string llts(long long i);
|
||||||
@ -4139,13 +4140,16 @@ namespace arcm {
|
|||||||
namespace crystal {
|
namespace crystal {
|
||||||
extern bool add_bitruncation;
|
extern bool add_bitruncation;
|
||||||
color_t colorize(cell *c);
|
color_t colorize(cell *c);
|
||||||
int distance(cell *c1, cell *c2);
|
int precise_distance(cell *c1, cell *c2);
|
||||||
hrmap *new_map();
|
hrmap *new_map();
|
||||||
void create_step(heptagon *h, int d);
|
void create_step(heptagon *h, int d);
|
||||||
void build_rugdata();
|
void build_rugdata();
|
||||||
void apply_rotation(const transmatrix t);
|
void apply_rotation(const transmatrix t);
|
||||||
void switch_z_coordinate();
|
void switch_z_coordinate();
|
||||||
void next_home_orientation();
|
void next_home_orientation();
|
||||||
|
void set_land(cell *c);
|
||||||
|
int dist_alt(cell *c);
|
||||||
|
int dist_relative(cell *c);
|
||||||
}
|
}
|
||||||
|
|
||||||
hyperpoint get_warp_corner(cell *c, int cid);
|
hyperpoint get_warp_corner(cell *c, int cid);
|
||||||
|
@ -2375,7 +2375,7 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
|
|
||||||
// this fixes the following problem:
|
// this fixes the following problem:
|
||||||
// http://steamcommunity.com/app/342610/discussions/0/1470840994970724215/
|
// http://steamcommunity.com/app/342610/discussions/0/1470840994970724215/
|
||||||
if(!generatingEquidistant && from && d >= 7 && c->land && !binarytiling && !archimedean) {
|
if(!generatingEquidistant && from && d >= 7 && c->land && !binarytiling && !archimedean && geometry != gCrystal) {
|
||||||
int cdi = celldist(c);
|
int cdi = celldist(c);
|
||||||
if(celldist(from) > cdi) {
|
if(celldist(from) > cdi) {
|
||||||
forCellCM(c2, c) if(celldist(c2) < cdi) {
|
forCellCM(c2, c) if(celldist(c2) < cdi) {
|
||||||
@ -2413,7 +2413,8 @@ void setdist(cell *c, int d, cell *from) {
|
|||||||
#else
|
#else
|
||||||
if(true) {
|
if(true) {
|
||||||
#endif
|
#endif
|
||||||
if(sphere || fulltorus) setLandSphere(c);
|
if(geometry == gCrystal) crystal::set_land(c);
|
||||||
|
else if(sphere || fulltorus) setLandSphere(c);
|
||||||
else if(euclid) setLandEuclid(c);
|
else if(euclid) setLandEuclid(c);
|
||||||
else if(quotient) { setland(c, specialland); setLandQuotient(c); }
|
else if(quotient) { setland(c, specialland); setLandQuotient(c); }
|
||||||
else if(weirdhyperbolic) setLandWeird(c);
|
else if(weirdhyperbolic) setLandWeird(c);
|
||||||
|
Loading…
Reference in New Issue
Block a user