mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-23 15:36:59 +00:00
reg3:: strafe and dirs_adjacent with subcubes -- Great Wall generation works
This commit is contained in:
parent
5f54bf2888
commit
0e0e4d0212
26
barriers.cpp
26
barriers.cpp
@ -745,13 +745,15 @@ EX void buildCrossroads2(cell *c) {
|
||||
}
|
||||
|
||||
#if MAXMDIM >= 4
|
||||
EX bool bufferzone() { return false; }
|
||||
|
||||
EX void extend3D(cell *c) {
|
||||
eLand l1 = c->land;
|
||||
c->barleft = NOWALLSEP_USED;
|
||||
|
||||
cellwalker cw(c, c->bardir);
|
||||
|
||||
if(S3 == 5) {
|
||||
if(bufferzone()) {
|
||||
cw += wstep; cw += rev;
|
||||
cw.at->bardir = NOBARRIERS;
|
||||
setland(cw.at, laBarrier);
|
||||
@ -765,9 +767,10 @@ EX void extend3D(cell *c) {
|
||||
cw1.at->bardir = cw1.spin;
|
||||
}
|
||||
|
||||
for(int j=0; j<S7; j++) if(cgi.dirs_adjacent[cw.spin][j]) {
|
||||
cellwalker bb2 = reg3::strafe(cw, j);
|
||||
if(S3 == 5) { bb2 += rev; bb2 += wstep; }
|
||||
auto& ad = currentmap->adjacent_dirs(cw);
|
||||
for(int j=0; j<S7; j++) if(ad[j]) {
|
||||
cellwalker bb2 = currentmap->strafe(cw, j);
|
||||
if(bufferzone()) { bb2 += rev; bb2 += wstep; }
|
||||
|
||||
if(bb2.at->bardir == NODIR) {
|
||||
bb2.at->bardir = bb2.spin;
|
||||
@ -788,7 +791,7 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) {
|
||||
return false;
|
||||
}
|
||||
cellwalker cw(c, forced_dir);
|
||||
if(S3 == 5) { cw += wstep; cw += rev; }
|
||||
if(bufferzone()) { cw += wstep; cw += rev; }
|
||||
set<cell*> listed_cells = { cw.at };
|
||||
vector<cellwalker> to_test { cw };
|
||||
for(int i=0; i<isize(to_test); i++) {
|
||||
@ -796,13 +799,14 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) {
|
||||
if(bb.at->mpdist < BARLEV) return false;
|
||||
if(bb.cpeek()->mpdist < BARLEV) return false;
|
||||
if(bb.cpeek()->bardir != NODIR) return false;
|
||||
if(S3 == 5 && (bb+rev).cpeek()->mpdist < BARLEV) return false;
|
||||
if(S3 == 5 && (bb+rev).cpeek()->bardir != NODIR) return false;
|
||||
if(bufferzone() && (bb+rev).cpeek()->mpdist < BARLEV) return false;
|
||||
if(bufferzone() && (bb+rev).cpeek()->bardir != NODIR) return false;
|
||||
if(bb.at->bardir != NODIR) return false;
|
||||
auto& ad = currentmap->adjacent_dirs(bb);
|
||||
for(int j=0; j<S7; j++) {
|
||||
if(S3 == 5 && i <= 5) bb.at->cmove(j);
|
||||
if(cgi.dirs_adjacent[bb.spin][j] && bb.at->move(j)) {
|
||||
cellwalker bb2 = reg3::strafe(bb, j);
|
||||
if(bufferzone() && i <= 5) bb.at->cmove(j);
|
||||
if(ad[j] && bb.at->move(j)) {
|
||||
cellwalker bb2 = currentmap->strafe(bb, j);
|
||||
if(listed_cells.count(bb2.at)) continue;
|
||||
listed_cells.insert(bb2.at);
|
||||
to_test.push_back(bb2);
|
||||
@ -812,7 +816,7 @@ EX bool buildBarrier3D(cell *c, eLand l2, int forced_dir) {
|
||||
|
||||
for(int i=0; i<isize(to_test); i++) {
|
||||
auto bb = to_test[i];
|
||||
if(S3 == 5) { bb.at->bardir = NOBARRIERS; setland(bb.at, laBarrier); bb += rev; bb += wstep; }
|
||||
if(bufferzone()) { bb.at->bardir = NOBARRIERS; setland(bb.at, laBarrier); bb += rev; bb += wstep; }
|
||||
bb.at->land = c->land;
|
||||
bb.at->bardir = bb.spin;
|
||||
bb.at->barleft = NOWALLSEP;
|
||||
|
29
bigstuff.cpp
29
bigstuff.cpp
@ -206,10 +206,11 @@ void hrmap::generateAlts(heptagon *h, int levs, bool link_cdata) {
|
||||
}
|
||||
|
||||
#if MAXMDIM >= 4
|
||||
EX int hrandom_adjacent(int d) {
|
||||
vector<int> choices = {d};
|
||||
for(int a=0; a<S7; a++) if(cgi.dirs_adjacent[d][a]) choices.push_back(a);
|
||||
return hrand_elt(choices, d);
|
||||
EX int hrandom_adjacent(cellwalker cw) {
|
||||
auto& da = currentmap->adjacent_dirs(cw);
|
||||
vector<int> choices = {cw.spin};
|
||||
for(int a=0; a<S7; a++) if(da[a]) choices.push_back(a);
|
||||
return hrand_elt(choices, cw.spin);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -271,7 +272,7 @@ EX heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special
|
||||
#if MAXMDIM >= 4
|
||||
// in 3D honeycombs we vary the direction, but never for three successive i's
|
||||
if(WDIM == 3 && firststate == hsOrigin && (i%3))
|
||||
bf.spin = hrandom_adjacent(bf.spin);
|
||||
bf.spin = hrandom_adjacent(bf);
|
||||
#endif
|
||||
}
|
||||
cx[rad] = bf.at;
|
||||
@ -694,9 +695,12 @@ EX void buildEquidistant(cell *c) {
|
||||
if(cw.at->landparam != c->landparam-1) continue;
|
||||
if(!cw.at->landflags) continue;
|
||||
if(S7 == 6) c->landflags = 1;
|
||||
else for(int j=0; j<S7; j++) if(cw.at->move(j) && cw.at->move(j)->landparam == c->landparam - 2 && !cgi.dirs_adjacent[j][cw.spin])
|
||||
if(c->landparam == 2 ? cw.at->move(j)->land != laEndorian : cw.at->move(j)->landparam)
|
||||
c->landflags = 1;
|
||||
else {
|
||||
auto& da = currentmap->adjacent_dirs(cw);
|
||||
for(int j=0; j<S7; j++) if(cw.at->move(j) && cw.at->move(j)->landparam == c->landparam - 2 && !da[j])
|
||||
if(c->landparam == 2 ? cw.at->move(j)->land != laEndorian : cw.at->move(j)->landparam)
|
||||
c->landflags = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(c->landparam == 2) {
|
||||
@ -718,8 +722,11 @@ EX void buildEquidistant(cell *c) {
|
||||
if(cw.at->landparam != c->landparam-1) continue;
|
||||
if(!cw.at->landflags) continue;
|
||||
if(S7 == 6) c->landflags = 1;
|
||||
else for(int j=0; j<S7; j++) if(cw.at->move(j) && cw.at->move(j)->landparam == c->landparam - 2 && !cgi.dirs_adjacent[j][cw.spin] && cw.at->move(j)->landflags)
|
||||
c->landflags = 1;
|
||||
else {
|
||||
auto& da = currentmap->adjacent_dirs(cw);
|
||||
for(int j=0; j<S7; j++) if(cw.at->move(j) && cw.at->move(j)->landparam == c->landparam - 2 && !da[j] && cw.at->move(j)->landflags)
|
||||
c->landflags = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@ -1485,7 +1492,7 @@ EX bool good_for_wall(cell *c) {
|
||||
}
|
||||
|
||||
EX bool walls_not_implemented() {
|
||||
if(WDIM == 3 && !PURE) return true;
|
||||
// if(WDIM == 3 && !PURE) return true;
|
||||
if(sphere || quotient || nonisotropic || (kite::in() && !bt::in()) || experimental) return true;
|
||||
return WDIM == 3 && (cgflags & qIDEAL);
|
||||
}
|
||||
|
8
cell.cpp
8
cell.cpp
@ -75,6 +75,14 @@ struct hrmap {
|
||||
}
|
||||
return currentmap->iadj(c, i);
|
||||
}
|
||||
|
||||
/** \brief in 3D honeycombs, returns a vector<bool> v, where v[j] iff faces i and j are adjacent */
|
||||
virtual const vector<bool>& adjacent_dirs(cell *c, int i) { throw hr_exception("adjacent_dirs called unexpectedly"); }
|
||||
|
||||
/** \brief in 3D honeycombs, returns a cellwalker res at cw->move(j) such that the face pointed at by cw and res share an edge */
|
||||
virtual cellwalker strafe(cellwalker cw, int j) { throw hr_exception("strafe called unexpectedly"); }
|
||||
|
||||
const vector<bool>& adjacent_dirs(cellwalker cw) { return adjacent_dirs(cw.at, cw.spin); }
|
||||
};
|
||||
|
||||
/** hrmaps which are based on regular non-Euclidean 2D tilings, possibly quotient
|
||||
|
@ -105,6 +105,7 @@ struct subcellshape {
|
||||
vector<hyperpoint> vertices_only;
|
||||
vector<hyperpoint> vertices_only_local;
|
||||
vector<hyperpoint> face_centers;
|
||||
vector<vector<bool>> dirs_adjacent;
|
||||
hyperpoint cellcenter;
|
||||
transmatrix to_cellcenter;
|
||||
transmatrix from_cellcenter;
|
||||
@ -151,7 +152,7 @@ struct geometry_information {
|
||||
|
||||
ld adjcheck;
|
||||
ld strafedist;
|
||||
bool dirs_adjacent[32][32];
|
||||
vector<vector<bool>> dirs_adjacent;
|
||||
|
||||
ld ultra_mirror_dist, ultra_material_part, ultra_mirror_part;
|
||||
|
||||
|
71
reg3.cpp
71
reg3.cpp
@ -256,9 +256,13 @@ EX namespace reg3 {
|
||||
adjcheck = hdist(tC0(cgi.adjmoves[0]), tC0(cgi.adjmoves[1])) * 1.0001;
|
||||
|
||||
int numedges = 0;
|
||||
for(int a=0; a<S7; a++) for(int b=0; b<S7; b++) {
|
||||
dirs_adjacent[a][b] = a != b && hdist(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b])) < adjcheck;
|
||||
if(dirs_adjacent[a][b]) numedges++;
|
||||
dirs_adjacent.resize(S7);
|
||||
for(int a=0; a<S7; a++) {
|
||||
dirs_adjacent[a].resize(S7);
|
||||
for(int b=0; b<S7; b++) {
|
||||
dirs_adjacent[a][b] = a != b && hdist(tC0(cgi.adjmoves[a]), tC0(cgi.adjmoves[b])) < adjcheck;
|
||||
if(dirs_adjacent[a][b]) numedges++;
|
||||
}
|
||||
}
|
||||
DEBB(DF_GEOM, ("numedges = ", numedges));
|
||||
|
||||
@ -688,6 +692,16 @@ EX namespace reg3 {
|
||||
int shvid(cell *c) { return local_id.at(c).second; }
|
||||
|
||||
virtual transmatrix ray_iadj(cell *c, int i) override;
|
||||
|
||||
const vector<bool>& adjacent_dirs(cell *c, int i) {
|
||||
int id = local_id.at(c).second;
|
||||
return cgi.subshapes[id].dirs_adjacent[i];
|
||||
}
|
||||
|
||||
cellwalker strafe(cellwalker cw, int j) override {
|
||||
int id = local_id.at(cw.at).first;
|
||||
return cellwalker(cw.at->cmove(j), strafe_data[id][j][cw.spin]);
|
||||
}
|
||||
};
|
||||
|
||||
struct hrmap_quotient3 : hrmap_closed3 { };
|
||||
@ -987,7 +1001,7 @@ EX namespace reg3 {
|
||||
plane.insert(cw);
|
||||
for(int i=0; i<S7; i++)
|
||||
if(cgi.dirs_adjacent[i][cw.spin])
|
||||
make_plane(reg3::strafe(cw, i));
|
||||
make_plane(strafe(cw, i));
|
||||
}
|
||||
|
||||
|
||||
@ -1475,6 +1489,21 @@ EX namespace reg3 {
|
||||
vector<hyperpoint> get_vertices(cell* c) override {
|
||||
return cgi.vertices_only;
|
||||
}
|
||||
|
||||
const vector<bool>& adjacent_dirs(cell *c, int i) {
|
||||
return cgi.dirs_adjacent[i];
|
||||
}
|
||||
|
||||
cellwalker strafe(cellwalker cw, int j) override {
|
||||
hyperpoint hfront = tC0(cgi.adjmoves[cw.spin]);
|
||||
cw.at->cmove(j);
|
||||
transmatrix T = currentmap->adj(cw.at, j);
|
||||
for(int i=0; i<S7; i++) if(i != cw.at->c.spin(j))
|
||||
if(hdist(hfront, T * tC0(cgi.adjmoves[i])) < cgi.strafedist + .01)
|
||||
return cellwalker(cw.at->cmove(j), i);
|
||||
throw hr_exception("incorrect strafe");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct hrmap_sphere3 : hrmap_closed3 {
|
||||
@ -1940,6 +1969,30 @@ EX namespace reg3 {
|
||||
int aid = cell_id.at(c);
|
||||
return quotient_map->ray_iadj(quotient_map->acells[aid], i);
|
||||
}
|
||||
|
||||
const vector<bool>& adjacent_dirs(cell *c, int i) {
|
||||
if(PURE) return cgi.dirs_adjacent[i];
|
||||
int aid = cell_id.at(c);
|
||||
return quotient_map->adjacent_dirs(quotient_map->acells[aid], i);
|
||||
}
|
||||
|
||||
cellwalker strafe(cellwalker cw, int j) override {
|
||||
|
||||
hyperpoint hfront = tC0(cgi.adjmoves[cw.spin]);
|
||||
cw.at->cmove(j);
|
||||
transmatrix T = currentmap->adj(cw.at, j);
|
||||
cellwalker res1;
|
||||
for(int i=0; i<S7; i++) if(i != cw.at->c.spin(j))
|
||||
if(hdist(hfront, T * tC0(cgi.adjmoves[i])) < cgi.strafedist + .01)
|
||||
res1 = cellwalker(cw.at->cmove(j), i);
|
||||
|
||||
int aid = PURE ? cw.at->master->fieldval : cell_id.at(cw.at);
|
||||
auto res = quotient_map->strafe(cellwalker(quotient_map->acells[aid], cw.spin), j);
|
||||
cellwalker res2 = cellwalker(cw.at->cmove(j), res.spin);
|
||||
|
||||
if(PURE && res1 != res2) println(hlog, "h3: ", res1, " vs ", res2);
|
||||
return res2;
|
||||
}
|
||||
};
|
||||
|
||||
struct hrmap_h3_rule_alt : hrmap {
|
||||
@ -2267,16 +2320,6 @@ int dist_alt(cell *c) {
|
||||
// as possible to cw.spin. Assume that j and cw.spin are adjacent
|
||||
|
||||
#if MAXMDIM >= 4
|
||||
EX cellwalker strafe(cellwalker cw, int j) {
|
||||
hyperpoint hfront = tC0(cgi.adjmoves[cw.spin]);
|
||||
cw.at->cmove(j);
|
||||
transmatrix T = currentmap->adj(cw.at, j);
|
||||
for(int i=0; i<S7; i++) if(i != cw.at->c.spin(j))
|
||||
if(hdist(hfront, T * tC0(cgi.adjmoves[i])) < cgi.strafedist + .01)
|
||||
return cellwalker(cw.at->cmove(j), i);
|
||||
throw hr_exception("incorrect strafe");
|
||||
}
|
||||
|
||||
EX int matrix_order(const transmatrix A) {
|
||||
transmatrix T = A;
|
||||
int res = 1;
|
||||
|
Loading…
Reference in New Issue
Block a user