location.cpp now defines constants global_distance_limit and iteration_limit

This commit is contained in:
Zeno Rogue 2020-03-01 14:36:35 +01:00
parent c1c4cea31f
commit b0eb4e816b
5 changed files with 48 additions and 36 deletions

View File

@ -917,7 +917,7 @@ EX namespace clearing {
// printf("R %4d C %4d\n", celldistAlt(bd.root), celldistAlt(c));
if(celldistAlt(c) > celldistAlt(bd.root)) {
stepcount++;
if(stepcount > 100000000) {
if(stepcount > iteration_limit) {
printf("buggy #1\n");
bd.buggy = true;
return;
@ -937,7 +937,7 @@ EX namespace clearing {
}
else {
bd.dist--;
if(bd.dist < -100000000) {
if(bd.dist < -iteration_limit) {
for(int i=0; i<steps; i++)
onpath[i]->item = itBuggy;
for(int i=0; i<(int) rpath.size(); i++)
@ -2562,7 +2562,7 @@ EX namespace dragon {
EX cell *target; // actually for all Orb of Control
void pullback(cell *c) {
int maxlen = 1000;
int maxlen = iteration_limit;
while(maxlen-->0) {
auto mi = moveimon(c).rev();
mountmove(mi, true);
@ -2579,7 +2579,7 @@ EX namespace dragon {
EX cell *findhead(cell *c) {
cell *cor = c;
int maxlen=1000;
int maxlen=iteration_limit;
findhead:
if(maxlen--<0) return c;
if(c->monst == moDragonHead) return c;
@ -2608,7 +2608,7 @@ EX namespace dragon {
EX int bodypart(cell *c, cell *head) {
int i = 0, j = 0;
int maxlen = 1000;
int maxlen = iteration_limit;
while(maxlen-->0) {
if(head == c) i = j;
j++;
@ -2627,7 +2627,7 @@ EX namespace dragon {
int delay = false;
kills[moDragonHead]++;
int penalty = 0;
int maxlen = 1000;
int maxlen = iteration_limit;
while(maxlen-->0) {
changes.ccell(c);
makeflame(c, 5, false);
@ -2657,7 +2657,7 @@ EX namespace dragon {
EX int totalhp(cell *c) {
int total = 0;
int maxlen = 1000;
int maxlen = iteration_limit;
while(maxlen-->0) {
if(!isDragon(c->monst)) {
if(!history::includeHistory) printf("dragon bug #4\n");
@ -2673,7 +2673,7 @@ EX namespace dragon {
#define SWAPBITFIELD(x,y,t) { t bak=x; x=y; y=bak; }
void pullfront(cell *c, cell *until) {
int maxlen = 1000;
int maxlen = iteration_limit;
static vector<cell*> allcells;
allcells.clear();
while(maxlen-->0) {

View File

@ -401,37 +401,36 @@ EX void fixWormBug(cell *c) {
if(c->monst == moTentacletail || c->monst == moTentacleGhost) c->monst = moTentacle;
if(c->monst == moHexSnakeTail) c->monst = moHexSnake;
}
EX bool isWormhead(eMonster m) {
return among(m,
moTentacle, moWorm, moHexSnake, moWormwait, moTentacleEscaping,
moTentaclewait, moDragonHead);
}
EX cell *worm_tohead(cell *c) {
for(int i=0; i<c->type; i++)
if(c->move(i) && isWorm(c->move(i)->monst) && c->move(i)->mondir == c->c.spin(i))
return c->move(i);
return nullptr;
}
EX cell *wormhead(cell *c) {
// cell *cor = c;
findhead:
if(c->monst == moTentacle || c->monst == moWorm || c->monst == moHexSnake ||
c->monst == moWormwait || c->monst == moTentacleEscaping || c->monst == moTentaclewait ||
c->monst == moDragonHead) return c;
for(int i=0; i<c->type; i++)
if(c->move(i) && isWorm(c->move(i)->monst) && c->move(i)->mondir == c->c.spin(i)) {
c = c->move(i); goto findhead;
}
int cnt = 0;
while(cnt < iteration_limit) {
if(isWormhead(c->monst))
return c;
cell *c1 = worm_tohead(c);
if(!c1) break;
c = c1;
cnt++;
}
fixWormBug(c);
return c;
}
}
EX int wormpos(cell *c) {
// cell *cor = c;
int cnt = 0;
findhead:
if(c->monst == moTentacle || c->monst == moWorm || c->monst == moHexSnake ||
c->monst == moWormwait || c->monst == moTentacleEscaping || c->monst == moTentaclewait ||
c->monst == moDragonHead) return cnt;
for(int i=0; i<c->type; i++)
if(c->move(i) && isWorm(c->move(i)->monst) && c->move(i)->mondir == c->c.spin(i)) {
c = c->move(i); cnt++; goto findhead;
}
fixWormBug(c);
return cnt;
}
// currently works for worms only
/** currently works for worms only */
EX bool sameMonster(cell *c1, cell *c2) {
if(!c1 || !c2) return false;
if(c1 == c2) return true;

View File

@ -237,7 +237,7 @@ heptagon *hrmap_standard::create_step(heptagon *h, int d) {
pard = 3; // to do: randomize
else if(S3 == 4)
pard = 3;
buildHeptagon(h, 0, h->distance < -32500 ? hsOrigin : hsA, pard);
buildHeptagon(h, 0, h->distance < -global_distance_limit - 200 ? hsOrigin : hsA, pard);
}
if(h->move(d)) return h->move(d);
if(h->s == hsOrigin) {

View File

@ -2899,7 +2899,8 @@ EX void setdist(cell *c, int d, cell *from) {
if(d == 7) repairLandgen(c);
// the number of tiles in the standard geometry has about 7553 digits!
if(c->master->distance > 32000 || c->master->distance < -32000) {
int gdist = abs(c->master->distance);
if(gdist > global_distance_limit) {
c->wall = waNone;
c->item = itOrbSafety;
}

View File

@ -288,6 +288,18 @@ struct cdata {
int bits;
};
/** Limit on the 'distance' value in heptagon. This value is signed (negative distances are used
in horocycle implementation. Distance is currently a short, and we need a bit of breathing room.
It would not be a technical problem to use a larger type, but 32000 is close to what fits in
the memory of a normal computer. Farlands appear close to this limit.
*/
constexpr int global_distance_limit = 32000;
/** This value is used in iterative algorithms to prevent infinite loops created by incorrect
data (e.g., circular dragon). It should be larger than global_distance_limit */
constexpr int iteration_limit = 10000000;
/** in bitruncated/irregular/Goldberg geometries, heptagons form the
* underlying regular tiling (not necessarily heptagonal); in pure
* geometries, they correspond 1-1 to tiles; in 'masterless' geometries