fixed incorrect pushing in some geometries (also caused crash when next to Thumper in Solv)

This commit is contained in:
Zeno Rogue 2019-07-30 13:54:32 +02:00
parent 6682c760a9
commit b773ecc9d9
2 changed files with 57 additions and 14 deletions

View File

@ -4143,6 +4143,49 @@ int pickDownDirection(cell *c, flagtype mf) {
return downs[hrand(qdowns)];
}
vector<int> reverse_directions(cell *c, int dir) {
int d = c->degree();
switch(geometry) {
case gBinary3:
if(dir < 4) return {8};
else if(dir >= 8) return {0, 1, 2, 3};
else return {dir ^ 1};
case gHoroTris:
if(dir < 4) return {7};
else if(dir == 4) return {5, 6};
else if(dir == 5) return {6, 4};
else if(dir == 6) return {4, 5};
else return {0, 1, 2, 3};
case gHoroRec:
if(dir < 2) return {6};
else if(dir == 6) return {0, 1};
else return {dir^1};
case gKiteDart3: {
if(dir < 4) return {dir ^ 2};
if(dir >= 6) return {4, 5};
vector<int> res;
for(int i=6; i<c->type; i++) res.push_back(i);
return res;
}
case gHoroHex: {
if(dir < 6) return {12, 13};
if(dir >= 12) return {0, 1, 2, 3, 4, 5};
const int dt[] = {0,0,0,0,0,0,10,11,9,8,6,7,0,0};
return {dt[dir]};
}
default:
if(d & 1)
return { gmod(dir + c->type/2, c->type), gmod(dir + (c->type+1)/2, c->type) };
else
return { gmod(dir + c->type/2, c->type) };
}
}
template<class T>
cell *determinePush(cellwalker who, cell *c2, int subdir, const T& valid, int& pushdir) {
if(subdir != 1 && subdir != -1) {
@ -4154,13 +4197,11 @@ cell *determinePush(cellwalker who, cell *c2, int subdir, const T& valid, int& p
}
cellwalker push = who;
push += wstep;
if(WDIM == 3 && binarytiling && !sol) {
for(int a=0; a<4; a++) {
if(push.spin < 4) push.spin = 8;
else if(push.spin >= 8) push.spin = a;
else push.spin ^= 1;
push += wstep;
if(valid(push.at)) return push.at;
if(binarytiling) {
auto rd = reverse_directions(push.at, push.spin);
for(int i: rd) {
push.spin = i;
if(valid(push.cpeek())) return push.cpeek();
}
return c2;
}

16
hyper.h
View File

@ -622,6 +622,11 @@ int hrand(int x);
// automatically adjust monster generation for 3D geometries
int hrand_monster(int x);
vector<int> reverse_directions(struct cell *c, int i);
// unused for heptagons
vector<int> reverse_directions(struct heptagon *c, int i) { return {i}; }
template<class T> struct walker {
T *at;
int spin;
@ -648,13 +653,10 @@ template<class T> struct walker {
return (*this);
}
walker<T>& operator += (rev_t) {
int d = at->degree();
if(WDIM == 3 && binarytiling) {
if(spin < 4) spin = 8;
else if(spin >= 8) spin = 0;
else spin ^= 1;
}
return (*this) += d/2 + ((d&1)?hrand(2):0);
auto rd = reverse_directions(at, spin);
if(rd.size() == 1) spin = rd[0];
else spin = rd[hrand(rd.size())];
return (*this);
}
walker<T>& operator += (revstep_t) {
(*this) += rev; return (*this) += wstep;