1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2025-02-20 04:50:10 +00:00

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

View File

@ -402,36 +402,35 @@ EX void fixWormBug(cell *c) {
if(c->monst == moHexSnakeTail) c->monst = moHexSnake; 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) { EX cell *wormhead(cell *c) {
// cell *cor = c; // cell *cor = c;
findhead: int cnt = 0;
if(c->monst == moTentacle || c->monst == moWorm || c->monst == moHexSnake || while(cnt < iteration_limit) {
c->monst == moWormwait || c->monst == moTentacleEscaping || c->monst == moTentaclewait || if(isWormhead(c->monst))
c->monst == moDragonHead) return c; return c;
for(int i=0; i<c->type; i++) cell *c1 = worm_tohead(c);
if(c->move(i) && isWorm(c->move(i)->monst) && c->move(i)->mondir == c->c.spin(i)) { if(!c1) break;
c = c->move(i); goto findhead; c = c1;
cnt++;
} }
fixWormBug(c); fixWormBug(c);
return c; return c;
} }
EX int wormpos(cell *c) { /** currently works for worms only */
// 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
EX bool sameMonster(cell *c1, cell *c2) { EX bool sameMonster(cell *c1, cell *c2) {
if(!c1 || !c2) return false; if(!c1 || !c2) return false;
if(c1 == c2) return true; 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 pard = 3; // to do: randomize
else if(S3 == 4) else if(S3 == 4)
pard = 3; 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->move(d)) return h->move(d);
if(h->s == hsOrigin) { if(h->s == hsOrigin) {

View File

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

View File

@ -288,6 +288,18 @@ struct cdata {
int bits; 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 /** in bitruncated/irregular/Goldberg geometries, heptagons form the
* underlying regular tiling (not necessarily heptagonal); in pure * underlying regular tiling (not necessarily heptagonal); in pure
* geometries, they correspond 1-1 to tiles; in 'masterless' geometries * geometries, they correspond 1-1 to tiles; in 'masterless' geometries