mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-11-23 21:07:17 +00:00
tailored allocation, and increased MAX_EDGE to 14
This commit is contained in:
parent
d6a614c854
commit
56c102de94
@ -410,7 +410,8 @@ struct hrmap_archimedean : hrmap {
|
|||||||
heptagon *getOrigin() { return origin; }
|
heptagon *getOrigin() { return origin; }
|
||||||
|
|
||||||
hrmap_archimedean() {
|
hrmap_archimedean() {
|
||||||
origin = new heptagon;
|
int N0 = isize(current.adjacent[0]);
|
||||||
|
origin = tailored_alloc<heptagon> (N0);
|
||||||
origin->s = hsOrigin;
|
origin->s = hsOrigin;
|
||||||
origin->emeraldval = 0;
|
origin->emeraldval = 0;
|
||||||
origin->zebraval = 0;
|
origin->zebraval = 0;
|
||||||
@ -418,23 +419,21 @@ struct hrmap_archimedean : hrmap {
|
|||||||
origin->fieldval = 0;
|
origin->fieldval = 0;
|
||||||
origin->rval0 = origin->rval1 = 0;
|
origin->rval0 = origin->rval1 = 0;
|
||||||
origin->cdata = NULL;
|
origin->cdata = NULL;
|
||||||
origin->c.clear();
|
|
||||||
origin->alt = NULL;
|
origin->alt = NULL;
|
||||||
origin->distance = 0;
|
origin->distance = 0;
|
||||||
|
|
||||||
parent_index_of(origin) = 0;
|
parent_index_of(origin) = 0;
|
||||||
id_of(origin) = 0;
|
id_of(origin) = 0;
|
||||||
origin->c7 = newCell(isize(current.adjacent[0]), origin);
|
origin->c7 = newCell(N0, origin);
|
||||||
|
|
||||||
heptagon *alt = NULL;
|
heptagon *alt = NULL;
|
||||||
|
|
||||||
if(hyperbolic) {
|
if(hyperbolic) {
|
||||||
dynamicval<eGeometry> g(geometry, gNormal);
|
dynamicval<eGeometry> g(geometry, gNormal);
|
||||||
alt = new heptagon;
|
alt = tailored_alloc<heptagon> (S7);
|
||||||
alt->s = hsOrigin;
|
alt->s = hsOrigin;
|
||||||
alt->emeraldval = 0;
|
alt->emeraldval = 0;
|
||||||
alt->zebraval = 0;
|
alt->zebraval = 0;
|
||||||
alt->c.clear();
|
|
||||||
alt->distance = 0;
|
alt->distance = 0;
|
||||||
alt->c7 = NULL;
|
alt->c7 = NULL;
|
||||||
alt->alt = alt;
|
alt->alt = alt;
|
||||||
@ -491,7 +490,7 @@ transmatrix adjcell_matrix(heptagon *h, int d);
|
|||||||
|
|
||||||
heptagon *build_child(heptspin p, pair<int, int> adj) {
|
heptagon *build_child(heptspin p, pair<int, int> adj) {
|
||||||
indenter ind;
|
indenter ind;
|
||||||
auto h = buildHeptagon1(new heptagon, p.at, p.spin, hstate(1), 0);
|
auto h = buildHeptagon1(tailored_alloc<heptagon> (isize(current.adjacent[adj.first])), p.at, p.spin, hstate(1), 0);
|
||||||
SDEBUG( printf("NEW %p.%d ~ %p.0\n", p.at, p.spin, h); )
|
SDEBUG( printf("NEW %p.%d ~ %p.0\n", p.at, p.spin, h); )
|
||||||
id_of(h) = adj.first;
|
id_of(h) = adj.first;
|
||||||
parent_index_of(h) = adj.second;
|
parent_index_of(h) = adj.second;
|
||||||
|
@ -741,7 +741,7 @@ bool buildBarrierNowall(cell *c, eLand l2, int forced_dir) {
|
|||||||
bool warpv = warped_version(c->land, l2);
|
bool warpv = warped_version(c->land, l2);
|
||||||
if(warpv && !archimedean && !pseudohept(c)) return false;
|
if(warpv && !archimedean && !pseudohept(c)) return false;
|
||||||
|
|
||||||
int ds[8];
|
int ds[MAX_EDGE];
|
||||||
for(int i=0; i<c->type; i++) ds[i] = i;
|
for(int i=0; i<c->type; i++) ds[i] = i;
|
||||||
for(int j=0; j<c->type; j++) swap(ds[j], ds[hrand(j+1)]);
|
for(int j=0; j<c->type; j++) swap(ds[j], ds[hrand(j+1)]);
|
||||||
|
|
||||||
|
@ -202,13 +202,12 @@ heptagon *createAlternateMap(cell *c, int rad, hstate firststate, int special) {
|
|||||||
if(polarb50(c) != 1) return NULL;
|
if(polarb50(c) != 1) return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
heptagon *alt = new heptagon;
|
heptagon *alt = tailored_alloc<heptagon> (S7);
|
||||||
allmaps.push_back(newAltMap(alt));
|
allmaps.push_back(newAltMap(alt));
|
||||||
//printf("new alt {%p}\n", alt);
|
//printf("new alt {%p}\n", alt);
|
||||||
alt->s = firststate;
|
alt->s = firststate;
|
||||||
alt->emeraldval = 0;
|
alt->emeraldval = 0;
|
||||||
alt->zebraval = 0;
|
alt->zebraval = 0;
|
||||||
alt->c.clear();
|
|
||||||
alt->distance = 0;
|
alt->distance = 0;
|
||||||
alt->c7 = NULL;
|
alt->c7 = NULL;
|
||||||
alt->alt = alt;
|
alt->alt = alt;
|
||||||
|
@ -77,7 +77,7 @@ namespace binary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
heptagon *build(heptagon *parent, int d, int d1, int t, int side, int delta) {
|
heptagon *build(heptagon *parent, int d, int d1, int t, int side, int delta) {
|
||||||
auto h = buildHeptagon1(new heptagon, parent, d, hsOrigin, d1);
|
auto h = buildHeptagon1(tailored_alloc<heptagon> (t), parent, d, hsOrigin, d1);
|
||||||
h->distance = parent->distance + delta;
|
h->distance = parent->distance + delta;
|
||||||
h->c7 = newCell(t, h);
|
h->c7 = newCell(t, h);
|
||||||
h->cdata = NULL;
|
h->cdata = NULL;
|
||||||
|
8
cell.cpp
8
cell.cpp
@ -22,10 +22,9 @@ int cellcount = 0;
|
|||||||
void initcell(cell *c); // from game.cpp
|
void initcell(cell *c); // from game.cpp
|
||||||
|
|
||||||
cell *newCell(int type, heptagon *master) {
|
cell *newCell(int type, heptagon *master) {
|
||||||
cell *c = new cell;
|
cell *c = tailored_alloc<cell> (type);
|
||||||
c->type = type;
|
c->type = type;
|
||||||
c->master = master;
|
c->master = master;
|
||||||
for(int i=0; i<MAX_EDGE; i++) c->move(i) = NULL;
|
|
||||||
initcell(c);
|
initcell(c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@ -52,7 +51,7 @@ hrmap *newAltMap(heptagon *o) { return new hrmap_alternate(o); }
|
|||||||
|
|
||||||
hrmap_hyperbolic::hrmap_hyperbolic() {
|
hrmap_hyperbolic::hrmap_hyperbolic() {
|
||||||
// printf("Creating hyperbolic map: %p\n", this);
|
// printf("Creating hyperbolic map: %p\n", this);
|
||||||
origin = new heptagon;
|
origin = tailored_alloc<heptagon> (S7);
|
||||||
heptagon& h = *origin;
|
heptagon& h = *origin;
|
||||||
h.s = hsOrigin;
|
h.s = hsOrigin;
|
||||||
h.emeraldval = a46 ? 0 : 98;
|
h.emeraldval = a46 ? 0 : 98;
|
||||||
@ -61,7 +60,6 @@ hrmap_hyperbolic::hrmap_hyperbolic() {
|
|||||||
h.fieldval = 0;
|
h.fieldval = 0;
|
||||||
h.rval0 = h.rval1 = 0;
|
h.rval0 = h.rval1 = 0;
|
||||||
h.cdata = NULL;
|
h.cdata = NULL;
|
||||||
h.c.clear();
|
|
||||||
h.alt = NULL;
|
h.alt = NULL;
|
||||||
h.distance = 0;
|
h.distance = 0;
|
||||||
isnonbitrunc = nonbitrunc;
|
isnonbitrunc = nonbitrunc;
|
||||||
@ -109,7 +107,7 @@ struct hrmap_spherical : hrmap {
|
|||||||
h.rval0 = h.rval1 = 0;
|
h.rval0 = h.rval1 = 0;
|
||||||
h.alt = NULL;
|
h.alt = NULL;
|
||||||
h.cdata = NULL;
|
h.cdata = NULL;
|
||||||
h.c.clear();
|
h.c.fullclear();
|
||||||
h.fieldval = i;
|
h.fieldval = i;
|
||||||
if(!irr::on) h.c7 = newCell(S7, &h);
|
if(!irr::on) h.c7 = newCell(S7, &h);
|
||||||
}
|
}
|
||||||
|
@ -69,14 +69,13 @@ template<class... T> auto iprintf(T... t) { for(int i=0; i<indent; i++) putchar(
|
|||||||
heptagon *buildHeptagon1(heptagon *h, heptagon *parent, int d, hstate s, int pard = 0, int fixdistance = COMPUTE) {
|
heptagon *buildHeptagon1(heptagon *h, heptagon *parent, int d, hstate s, int pard = 0, int fixdistance = COMPUTE) {
|
||||||
h->alt = NULL;
|
h->alt = NULL;
|
||||||
h->s = s;
|
h->s = s;
|
||||||
h->c.clear();
|
|
||||||
h->c.connect(pard, parent, d, false);
|
h->c.connect(pard, parent, d, false);
|
||||||
h->cdata = NULL;
|
h->cdata = NULL;
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fixdistance = COMPUTE) {
|
heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fixdistance = COMPUTE) {
|
||||||
heptagon *h = buildHeptagon1(new heptagon, parent, d, s, pard, fixdistance);
|
heptagon *h = buildHeptagon1(tailored_alloc<heptagon> (S7), parent, d, s, pard, fixdistance);
|
||||||
if(binarytiling || archimedean) return h;
|
if(binarytiling || archimedean) return h;
|
||||||
if(parent->c7) {
|
if(parent->c7) {
|
||||||
if(irr::on)
|
if(irr::on)
|
||||||
|
61
hyper.h
61
hyper.h
@ -320,30 +320,43 @@ struct gcell {
|
|||||||
#define NOBARRIERS 15
|
#define NOBARRIERS 15
|
||||||
#define MODFIXER 10090080
|
#define MODFIXER 10090080
|
||||||
|
|
||||||
#define MAX_EDGE 12
|
#define MAX_EDGE 14
|
||||||
|
|
||||||
template<class T> struct walker;
|
template<class T> struct walker;
|
||||||
|
|
||||||
template<class T> struct connection_table {
|
template<class T> struct connection_table {
|
||||||
|
|
||||||
|
// Assumption: class T has a field c of type connection_table<T>.
|
||||||
|
|
||||||
|
// NOTE: since aconnection_table may be allocated with
|
||||||
|
// less than MAX_EDGE neighbors (see tailored_alloc),
|
||||||
|
// the order of fields matters.
|
||||||
|
|
||||||
unsigned char spintable[6];
|
unsigned char spintable[6];
|
||||||
unsigned short mirrortable;
|
unsigned short mirrortable;
|
||||||
// neighbors; move[0] always goes towards origin, and then we go clockwise
|
|
||||||
T* move_table[MAX_EDGE];
|
T* move_table[MAX_EDGE];
|
||||||
|
unsigned char spintable_extra[2];
|
||||||
|
|
||||||
T* full() { T* x; return (T*)((char*)this - ((char*)(&(x->c)) - (char*)x)); }
|
T* full() { T* x; return (T*)((char*)this - ((char*)(&(x->c)) - (char*)x)); }
|
||||||
|
unsigned char& get_spinchar(int d) {
|
||||||
|
if(d < 12) return spintable[d>>1];
|
||||||
|
else return spintable_extra[(d-12)>>1];
|
||||||
|
}
|
||||||
void setspin(int d, int spin, bool mirror) {
|
void setspin(int d, int spin, bool mirror) {
|
||||||
spintable[d>>1] &= ~(15 << ((d&1) << 2));
|
unsigned char& c = get_spinchar(d);
|
||||||
spintable[d>>1] |= spin << ((d&1) << 2);
|
c &= ~(15 << ((d&1) << 2));
|
||||||
|
c |= spin << ((d&1) << 2);
|
||||||
if(mirror) mirrortable |= (1 << d);
|
if(mirror) mirrortable |= (1 << d);
|
||||||
else mirrortable &=~ (1 << d);
|
else mirrortable &=~ (1 << d);
|
||||||
}
|
}
|
||||||
// we are spin(i)-th neighbor of move[i]
|
// we are spin(i)-th neighbor of move[i]
|
||||||
int spin(int d) { return (spintable[d>>1] >> ((d&1)<<2)) & 15; }
|
int spin(int d) { return (get_spinchar(d) >> ((d&1)<<2)) & 15; }
|
||||||
bool mirror(int d) { return (mirrortable >> d) & 1; }
|
bool mirror(int d) { return (mirrortable >> d) & 1; }
|
||||||
int fix(int d) { return (d + MODFIXER) % full()->degree(); }
|
int fix(int d) { return (d + MODFIXER) % full()->degree(); }
|
||||||
T*& modmove(int i) { return move(fix(i)); }
|
T*& modmove(int i) { return move(fix(i)); }
|
||||||
T*& move(int i) { return move_table[i]; }
|
T*& move(int i) { return move_table[i]; }
|
||||||
unsigned char modspin(int i) { return spin(fix(i)); }
|
unsigned char modspin(int i) { return spin(fix(i)); }
|
||||||
void clear() {
|
void fullclear() {
|
||||||
for(int i=0; i<MAX_EDGE; i++) move_table[i] = NULL;
|
for(int i=0; i<MAX_EDGE; i++) move_table[i] = NULL;
|
||||||
}
|
}
|
||||||
void connect(int d0, T* c1, int d1, bool m) {
|
void connect(int d0, T* c1, int d1, bool m) {
|
||||||
@ -357,6 +370,29 @@ template<class T> struct connection_table {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Allocate a class T with a connection_table, but
|
||||||
|
// with only `degree` connections. Also set yet
|
||||||
|
// unknown connections to NULL.
|
||||||
|
|
||||||
|
// Generating the hyperbolic world consumes lots of
|
||||||
|
// RAM, so we really need to be careful on low memory devices.
|
||||||
|
|
||||||
|
template<class T> T* tailored_alloc(int degree) {
|
||||||
|
const T* sample = (T*) °ree;
|
||||||
|
T* result;
|
||||||
|
#ifndef NO_TAILORED_ALLOC
|
||||||
|
if(degree <= 12) {
|
||||||
|
int b = (char*)&sample->c.move_table[degree] - (char*) sample;
|
||||||
|
result = (T*) new char[b];
|
||||||
|
new (result) T();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
result = new T;
|
||||||
|
for(int i=0; i<degree; i++) result->c.move_table[i] = NULL;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wstep_t { wstep_t() {} } wstep;
|
static const struct wstep_t { wstep_t() {} } wstep;
|
||||||
static const struct wmirror_t { wmirror_t() {}} wmirror;
|
static const struct wmirror_t { wmirror_t() {}} wmirror;
|
||||||
static const struct rev_t { rev_t() {} } rev;
|
static const struct rev_t { rev_t() {} } rev;
|
||||||
@ -415,8 +451,6 @@ template<class T> struct walker {
|
|||||||
walker<T> mirrorat(int d) { return walker<T> (at, at->c.fix(d+d - spin), !mirrored); }
|
walker<T> mirrorat(int d) { return walker<T> (at, at->c.fix(d+d - spin), !mirrored); }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline int fix42(int a) { return (a+MODFIXER)% S42; }
|
|
||||||
|
|
||||||
struct cell;
|
struct cell;
|
||||||
|
|
||||||
// automaton state
|
// automaton state
|
||||||
@ -455,6 +489,11 @@ struct heptagon {
|
|||||||
~heptagon () { heptacount--; }
|
~heptagon () { heptacount--; }
|
||||||
heptagon *cmove(int d) { return createStep(this, d); }
|
heptagon *cmove(int d) { return createStep(this, d); }
|
||||||
inline int degree();
|
inline int degree();
|
||||||
|
|
||||||
|
// prevent accidental copying
|
||||||
|
heptagon(const heptagon&) = delete;
|
||||||
|
heptagon& operator=(const heptagon&) = delete;
|
||||||
|
// do not add any fields after connection_table (see tailored_alloc)
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cell : gcell {
|
struct cell : gcell {
|
||||||
@ -472,6 +511,12 @@ struct cell : gcell {
|
|||||||
cell*& move(int d) { return c.move(d); }
|
cell*& move(int d) { return c.move(d); }
|
||||||
cell*& modmove(int d) { return c.modmove(d); }
|
cell*& modmove(int d) { return c.modmove(d); }
|
||||||
cell* cmove(int d) { return createMov(this, d); }
|
cell* cmove(int d) { return createMov(this, d); }
|
||||||
|
cell() {}
|
||||||
|
|
||||||
|
// prevent accidental copying
|
||||||
|
cell(const cell&) = delete;
|
||||||
|
heptagon& operator=(const cell&) = delete;
|
||||||
|
// do not add any fields after connection_table (see tailored_alloc)
|
||||||
};
|
};
|
||||||
|
|
||||||
int heptagon::degree() { if(archimedean) return c7->type; else return S7; }
|
int heptagon::degree() { if(archimedean) return c7->type; else return S7; }
|
||||||
|
Loading…
Reference in New Issue
Block a user