mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-22 14:00:13 +00:00
dual tilings
This commit is contained in:
parent
d95fc4b8d4
commit
829850a701
@ -423,7 +423,8 @@ struct hrmap_archimedean : hrmap {
|
||||
heptagon *getOrigin() { return origin; }
|
||||
|
||||
hrmap_archimedean() {
|
||||
int N0 = isize(current.adjacent[0]);
|
||||
int id = DUAL ? current.N * 2 : 0;;
|
||||
int N0 = isize(current.adjacent[id]);
|
||||
origin = tailored_alloc<heptagon> (N0);
|
||||
origin->s = hsOrigin;
|
||||
origin->emeraldval = 0;
|
||||
@ -435,9 +436,9 @@ struct hrmap_archimedean : hrmap {
|
||||
origin->alt = NULL;
|
||||
origin->distance = 0;
|
||||
|
||||
parent_index_of(origin) = 0;
|
||||
id_of(origin) = 0;
|
||||
origin->c7 = newCell(N0, origin);
|
||||
parent_index_of(origin) = DUAL ? 1 : 0;
|
||||
id_of(origin) = id;
|
||||
origin->c7 = newCell(DUAL ? N0/2 : N0, origin);
|
||||
|
||||
heptagon *alt = NULL;
|
||||
|
||||
@ -458,20 +459,28 @@ struct hrmap_archimedean : hrmap {
|
||||
archimedean_gmatrix[origin] = make_pair(alt, T);
|
||||
altmap[alt].emplace_back(origin, T);
|
||||
|
||||
if(current.real_faces == 0) {
|
||||
create_adjacent(origin, 0);
|
||||
if(current.real_faces == 0 && DUAL) {
|
||||
heptspin hs(origin, 0);
|
||||
heptagon *hnew = build_child(hs, current.get_adj(hs));
|
||||
for(int s=1; s<2*current.N; s++)
|
||||
origin->c.connect(s, hnew, s, false);
|
||||
}
|
||||
else if(current.real_faces == 0) {
|
||||
create_adjacent(origin, 0);
|
||||
heptagon *o0 = origin->move(0);
|
||||
create_adjacent(origin, 1);
|
||||
heptagon *o1 = origin->move(1);
|
||||
for(int s=1; s<2*current.N; s+=2)
|
||||
origin->move(0)->c.connect(s, origin->move(1), 2*current.N-s, false);
|
||||
o0->c.connect(s, o1, 2*current.N-s, false);
|
||||
for(int s=2; s<2*current.N; s+=2) {
|
||||
heptspin hs(origin->move(0), s);
|
||||
heptspin hs(o0, s);
|
||||
heptagon *hnew = build_child(hs, current.get_adj(hs));
|
||||
// no need to specify archimedean_gmatrix and altmap
|
||||
hnew->c.connect(1, heptspin(origin->move(1), 2*current.N-s));
|
||||
hnew->c.connect(1, heptspin(o1, 2*current.N-s));
|
||||
}
|
||||
origin->move(1)->c.connect(1, origin->move(0), 2*current.N-1, false);
|
||||
o1->c.connect(1, o0, 2*current.N-1, false);
|
||||
}
|
||||
else if(origin->c7->type == 2) {
|
||||
else if(origin->degree() == 2) {
|
||||
create_adjacent(origin, 0);
|
||||
create_adjacent(origin, 1);
|
||||
origin->move(0)->c.connect(1, origin->move(1), 2*current.N-1, false);
|
||||
@ -508,9 +517,9 @@ heptagon *build_child(heptspin p, pair<int, int> adj) {
|
||||
id_of(h) = adj.first;
|
||||
parent_index_of(h) = adj.second;
|
||||
int nei = neighbors_of(h);
|
||||
h->c7 = newCell(nei, h);
|
||||
h->c7 = newCell(DUAL ? nei/2 : nei, h);
|
||||
h->distance = p.at->distance + 1;
|
||||
if(adj.first < 2*current.N) {
|
||||
if(adj.first < 2*current.N && !DUAL) {
|
||||
int s = 0;
|
||||
heptspin hs(p);
|
||||
while(id_of(hs.at->move(0)) >= 2 * current.N) {
|
||||
@ -607,7 +616,7 @@ void create_adjacent(heptagon *h, int d) {
|
||||
|
||||
for(auto& p: altmap[alt]) if(intval(p.second * C0, T * C0) < 1e-4) {
|
||||
SDEBUG( printf("cell found: %p\n", p.first); )
|
||||
for(int d2=0; d2<p.first->c7->type; d2++) {
|
||||
for(int d2=0; d2<p.first->degree(); d2++) {
|
||||
heptspin hs(p.first, d2);
|
||||
auto& t2 = current.get_triangle(p.first, d2);
|
||||
transmatrix T1 = T * spin(M_PI + t2.first);
|
||||
@ -682,12 +691,13 @@ void draw() {
|
||||
int id = id_of(h);
|
||||
int S = isize(current.triangles[id]);
|
||||
|
||||
if(BITRUNCATED || id < 2*current.N) {
|
||||
if(id < 2*current.N ? !DUAL : !PURE) {
|
||||
if(!dodrawcell(h->c7)) continue;
|
||||
drawcell(h->c7, V, 0, false);
|
||||
}
|
||||
|
||||
for(int i=0; i<S; i++) {
|
||||
if(DUAL && (i&1)) continue;
|
||||
h->cmove(i);
|
||||
if(PURE && id >= 2*current.N && h->move(i) && id_of(h->move(i)) >= 2*current.N) continue;
|
||||
enqueue(h->move(i), V * adjcell_matrix(h, i));
|
||||
@ -701,10 +711,12 @@ transmatrix relative_matrix(heptagon *h2, heptagon *h1) {
|
||||
return inverse(gmatrix0[h1->c7]) * gmatrix0[h2->c7];
|
||||
transmatrix gm = Id, where = Id;
|
||||
while(h1 != h2) {
|
||||
for(int i=0; i<neighbors_of(h1); i++) if(h1->move(i) == h2) {
|
||||
return gm * adjcell_matrix(h1, i) * where;
|
||||
for(int i=0; i<neighbors_of(h1); i++) {
|
||||
if(h1->move(i) == h2) {
|
||||
return gm * adjcell_matrix(h1, i) * where;
|
||||
}
|
||||
}
|
||||
else if(h1->distance > h2->distance) {
|
||||
if(h1->distance > h2->distance) {
|
||||
gm = gm * adjcell_matrix(h1, 0);
|
||||
h1 = h1->move(0);
|
||||
}
|
||||
@ -789,6 +801,7 @@ int readArgs() {
|
||||
|
||||
if(0) ;
|
||||
else if(argis("-symbol")) {
|
||||
PHASE(2);
|
||||
archimedean_tiling at;
|
||||
shift(); at.parse(args());
|
||||
if(at.errors) {
|
||||
@ -801,6 +814,7 @@ int readArgs() {
|
||||
}
|
||||
}
|
||||
else if(argis("-dgeom")) debug_geometry = true;
|
||||
else if(argis("-dual")) { PHASE(2); set_variation(eVariation::dual); }
|
||||
else return 1;
|
||||
return 0;
|
||||
}
|
||||
@ -819,7 +833,8 @@ int archimedean_tiling::support_threecolor() {
|
||||
}
|
||||
|
||||
int archimedean_tiling::support_threecolor_bitruncated() {
|
||||
return N % 2 == 0 ? 2 : 0;
|
||||
for(int i: current.faces) if(i % 2) return 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
int archimedean_tiling::support_football() {
|
||||
@ -842,6 +857,8 @@ bool pseudohept(int id) {
|
||||
}
|
||||
|
||||
bool chessvalue(cell *c) {
|
||||
if(DUAL)
|
||||
return c->master->rval1 - 1;
|
||||
return c->master->fieldval & 1;
|
||||
}
|
||||
|
||||
@ -971,10 +988,19 @@ archimedean_tiling edited;
|
||||
|
||||
bool symbol_editing;
|
||||
|
||||
void next_variation() {
|
||||
set_variation(
|
||||
PURE ? eVariation::dual :
|
||||
DUAL ? eVariation::bitruncated :
|
||||
eVariation::pure);
|
||||
need_reset_geometry = true;
|
||||
start_game();
|
||||
}
|
||||
|
||||
void enable(archimedean_tiling& arct) {
|
||||
stop_game();
|
||||
if(!archimedean) set_variation(eVariation::pure);
|
||||
set_geometry(gArchimedean);
|
||||
set_variation(eVariation::pure);
|
||||
patterns::whichPattern = patterns::PAT_NONE;
|
||||
#if CAP_TEXTURE
|
||||
if(texture::config.tstate == texture::tsActive && texture::cgroup == cpThree)
|
||||
@ -985,6 +1011,7 @@ void enable(archimedean_tiling& arct) {
|
||||
patterns::whichPattern = patterns::PAT_CHESS;
|
||||
#endif
|
||||
current = arct;
|
||||
need_reset_geometry = true;
|
||||
start_game();
|
||||
}
|
||||
|
||||
@ -1108,10 +1135,7 @@ void show() {
|
||||
|
||||
if(archimedean) {
|
||||
dialog::addSelItem(XLAT("variations"), gp::operation_name(), 'v');
|
||||
dialog::add_action([] () {
|
||||
set_variation(PURE ? eVariation::bitruncated : eVariation::pure);
|
||||
start_game();
|
||||
});
|
||||
dialog::add_action(next_variation);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1151,8 +1175,8 @@ string archimedean_tiling::world_size() {
|
||||
denom = denom / g * f;
|
||||
}
|
||||
int anom = 0, adenom = 1;
|
||||
if(BITRUNCATED) anom = 1, adenom = 1;
|
||||
for(int f: faces) {
|
||||
if(BITRUNCATED || DUAL) anom = 1, adenom = 1;
|
||||
if(!DUAL) for(int f: faces) {
|
||||
int g = gcd(adenom, f);
|
||||
anom = (anom * f + adenom) / g;
|
||||
adenom = adenom / g * f;
|
||||
@ -1172,6 +1196,10 @@ string archimedean_tiling::world_size() {
|
||||
return s;
|
||||
}
|
||||
|
||||
int degree(heptagon *h) {
|
||||
return isize(current.adjacent[id_of(h)]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
17
cell.cpp
17
cell.cpp
@ -796,14 +796,25 @@ cell *createMov(cell *c, int d) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if(PURE && archimedean) {
|
||||
if(arcm::id_of(c->master) <= arcm::current.N * 2) {
|
||||
else if(archimedean && PURE) {
|
||||
if(arcm::id_of(c->master) < arcm::current.N * 2) {
|
||||
heptspin hs = heptspin(c->master, d) + wstep + 2 + wstep + 1;
|
||||
c->c.connect(d, hs.at->c7, hs.spin, hs.mirrored);
|
||||
}
|
||||
else c->c.connect(d, c, d, false);
|
||||
}
|
||||
else if(PURE || archimedean) {
|
||||
else if(archimedean && DUAL) {
|
||||
if(arcm::id_of(c->master) >= arcm::current.N * 2) {
|
||||
heptagon *h2 = createStep(c->master, d*2);
|
||||
int d1 = c->master->c.spin(d*2);
|
||||
c->c.connect(d, h2->c7, d1/2, false);
|
||||
}
|
||||
else {
|
||||
printf("bad connection\n");
|
||||
c->c.connect(d,c,d,false);
|
||||
}
|
||||
}
|
||||
else if(archimedean || PURE) {
|
||||
heptagon *h2 = createStep(c->master, d);
|
||||
c->c.connect(d, h2->c7,c->master->c.spin(d),false);
|
||||
}
|
||||
|
@ -3199,7 +3199,7 @@ namespace windmap {
|
||||
// cw.spin = 0;
|
||||
neighbors.emplace_back();
|
||||
auto &v = neighbors.back();
|
||||
if(NONSTDVAR && !sphere)
|
||||
if(NONSTDVAR && !sphere && !archimedean)
|
||||
for(int l=0; l<S7; l++) {
|
||||
heptspin hs(cw.at->master, cw.spin);
|
||||
hs = hs + l + wstep;
|
||||
|
@ -500,6 +500,8 @@ void generate_floorshapes() {
|
||||
for(int i=0; i<2*ac.N + 2; i++) {
|
||||
arcm::id_of(&master) = i;
|
||||
model.type = isize(ac.triangles[i]);
|
||||
if(DUAL) model.type /= 2, arcm::parent_index_of(&master) = !(i&1);
|
||||
|
||||
if(BITRUNCATED)
|
||||
generate_floorshapes_for(i, &model, !arcm::pseudohept(i), arcm::pseudohept(i) ? 0 : 1^(i&1));
|
||||
else if(geosupport_football() == 2)
|
||||
|
@ -288,8 +288,6 @@ void showEuclideanMenu() {
|
||||
dialog::addSelItem(XLAT("variations"), XLAT("does not matter"), 'v');
|
||||
else if(binarytiling)
|
||||
dialog::addSelItem(XLAT("width"), fts(vid.binary_width), 'v');
|
||||
else if(archimedean)
|
||||
dialog::addSelItem(XLAT("variations"), XLAT("Not implemented."), 'v');
|
||||
else
|
||||
dialog::addSelItem(XLAT("variations"), gp::operation_name(), 'v');
|
||||
|
||||
@ -343,6 +341,7 @@ void showEuclideanMenu() {
|
||||
spf += its(i);
|
||||
}
|
||||
if(BITRUNCATED) spf = "[" + spf + "]," + its(arcm::current.N * 2) + "," + its(arcm::current.N * 2);
|
||||
if(DUAL) spf = its(arcm::current.N) + "^[" + spf + "]";
|
||||
}
|
||||
else if(binarytiling)
|
||||
spf = "6,[6,7],7";
|
||||
@ -434,7 +433,8 @@ void showEuclideanMenu() {
|
||||
else if(uni == 'z')
|
||||
showquotients = !showquotients;
|
||||
else if(uni == 'v') {
|
||||
if(euclid6 || archimedean) ;
|
||||
if(euclid6) ;
|
||||
else if(archimedean) arcm::next_variation();
|
||||
else if(binarytiling) {
|
||||
dialog::editNumber(vid.binary_width, 0, 2, 0.1, 1, XLAT("binary tiling width"), "");
|
||||
dialog::reaction = [] () {
|
||||
|
@ -408,6 +408,10 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
|
||||
hyperpoint h1 = xspinpush0(-t1.first, t1.second * 3 / cf * (ac.real_faces == 0 ? 0.999 : 1));
|
||||
return mid3(C0, h0, h1);
|
||||
}
|
||||
if(DUAL) {
|
||||
auto& t0 = ac.get_triangle(c->master, 2*cid-1);
|
||||
return xspinpush0(-t0.first, t0.second * 3 / cf * (ac.real_faces == 0 ? 0.999 : 1));
|
||||
}
|
||||
}
|
||||
if(PURE) {
|
||||
return ddspin(c,cid,M_PI/S7) * xpush0(hcrossf * 3 / cf);
|
||||
@ -447,6 +451,11 @@ hyperpoint nearcorner(cell *c, int i) {
|
||||
auto& t = ac.get_triangle(c->master, i);
|
||||
return xspinpush0(-t.first, t.second);
|
||||
}
|
||||
if(DUAL) {
|
||||
auto &ac = arcm::current;
|
||||
auto& t = ac.get_triangle(c->master, i * 2);
|
||||
return xspinpush0(-t.first, t.second);
|
||||
}
|
||||
}
|
||||
if(binarytiling) {
|
||||
ld yx = log(2) / 2;
|
||||
@ -505,9 +514,10 @@ hyperpoint farcorner(cell *c, int i, int which) {
|
||||
int n1 = isize(ac.adjacent[id1]);
|
||||
return spin(-t.first - M_PI / c->type) * xpush(ac.inradius[id/2] + ac.inradius[id1/2]) * xspinpush0(M_PI + M_PI/n1*(which?3:-3), ac.circumradius[id1/2]);
|
||||
}
|
||||
if(BITRUNCATED) {
|
||||
if(BITRUNCATED || DUAL) {
|
||||
int mul = DUAL ? 2 : 1;
|
||||
auto &ac = arcm::current;
|
||||
auto adj = ac.get_adj(c->master, i);
|
||||
auto adj = ac.get_adj(c->master, i * mul);
|
||||
heptagon h; cell cx; cx.master = &h;
|
||||
arcm::id_of(&h) = adj.first;
|
||||
arcm::parent_index_of(&h) = adj.second;
|
||||
@ -516,7 +526,7 @@ hyperpoint farcorner(cell *c, int i, int which) {
|
||||
|
||||
auto& t2 = arcm::current.get_triangle(adj);
|
||||
|
||||
return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first) * get_corner_position(&cx, which ? -1 : 2);
|
||||
return spin(-t1.first) * xpush(t1.second) * spin(M_PI + t2.first) * get_corner_position(&cx, which ? -mul : 2*mul);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -627,6 +627,8 @@ namespace hr { namespace gp {
|
||||
string operation_name() {
|
||||
if(IRREGULAR)
|
||||
return XLAT("irregular");
|
||||
else if(DUAL)
|
||||
return XLAT("dual");
|
||||
else if(PURE)
|
||||
return XLAT("OFF");
|
||||
else if(BITRUNCATED)
|
||||
|
@ -240,6 +240,10 @@ ld displayspin(cell *c, int d) {
|
||||
auto& t1 = arcm::current.get_triangle(c->master, d-1);
|
||||
return -(t1.first + M_PI / c->type);
|
||||
}
|
||||
else if(DUAL) {
|
||||
auto& t1 = arcm::current.get_triangle(c->master, 2*d);
|
||||
return -t1.first;
|
||||
}
|
||||
else { /* BITRUNCATED */
|
||||
auto& t1 = arcm::current.get_triangle(c->master, d);
|
||||
return -t1.first;
|
||||
|
5
hyper.h
5
hyper.h
@ -137,6 +137,7 @@ void addMessage(string s, char spamtype = 0);
|
||||
#define IRREGULAR (variation == eVariation::irregular)
|
||||
#define PURE (variation == eVariation::pure)
|
||||
#define BITRUNCATED (variation == eVariation::bitruncated)
|
||||
#define DUAL (variation == eVariation::dual)
|
||||
|
||||
#define CHANGED_VARIATION (variation != ginf[geometry].default_variation)
|
||||
|
||||
@ -530,7 +531,9 @@ struct cell : gcell {
|
||||
// do not add any fields after connection_table (see tailored_alloc)
|
||||
};
|
||||
|
||||
int heptagon::degree() { if(archimedean) return c7->type; else return S7; }
|
||||
namespace arcm { int degree(heptagon *h); }
|
||||
|
||||
int heptagon::degree() { if(archimedean) return arcm::degree(this); else return S7; }
|
||||
|
||||
typedef walker<heptagon> heptspin;
|
||||
typedef walker<cell> cellwalker;
|
||||
|
@ -807,11 +807,12 @@ void optimizeview() {
|
||||
if(binarytiling || archimedean) {
|
||||
turn = -1, best = View[2][2];
|
||||
for(int i=0; i<viewctr.at->c7->type; i++) {
|
||||
heptagon *h2 = createStep(viewctr.at, i);
|
||||
int i1 = i * (DUAL ? 2 : 1);
|
||||
heptagon *h2 = createStep(viewctr.at, i1);
|
||||
transmatrix T = (binarytiling) ? binary::relative_matrix(h2, viewctr.at) : arcm::relative_matrix(h2, viewctr.at);
|
||||
hyperpoint H = View * tC0(T);
|
||||
ld quality = euclid ? hdist0(H) : H[2];
|
||||
if(quality < best) best = quality, turn = i, TB = T;
|
||||
if(quality < best) best = quality, turn = i1, TB = T;
|
||||
}
|
||||
if(turn >= 0) {
|
||||
View = View * TB;
|
||||
|
23
pattern2.cpp
23
pattern2.cpp
@ -1065,13 +1065,17 @@ namespace patterns {
|
||||
}
|
||||
|
||||
bool geosupport_chessboard() {
|
||||
return (archimedean && PURE) ? arcm::current.support_chessboard() : (VALENCE % 2 == 0);
|
||||
return
|
||||
(archimedean && PURE) ? arcm::current.support_chessboard() :
|
||||
(archimedean && DUAL) ? arcm::current.support_threecolor_bitruncated() :
|
||||
(VALENCE % 2 == 0);
|
||||
}
|
||||
|
||||
int geosupport_threecolor() {
|
||||
if(IRREGULAR) return 0;
|
||||
if(archimedean && PURE) return arcm::current.support_threecolor();
|
||||
if(archimedean && BITRUNCATED) return arcm::current.support_threecolor_bitruncated();
|
||||
if(archimedean && DUAL) return 0; // it sometimes does support threecolor, but it can be obtained in other ways then
|
||||
if(BITRUNCATED && S3 == 3) {
|
||||
if(S7 % 2) return 1;
|
||||
return 2;
|
||||
@ -1086,8 +1090,11 @@ int geosupport_threecolor() {
|
||||
int geosupport_football() {
|
||||
// always works in bitrunc geometries
|
||||
if(BITRUNCATED) return 2;
|
||||
|
||||
if(archimedean && DUAL) return false;
|
||||
// it sometimes does support football, but it can be obtained in other ways then
|
||||
|
||||
if(archimedean) return arcm::current.support_football();
|
||||
if(archimedean /* PURE */) return arcm::current.support_football();
|
||||
|
||||
if(IRREGULAR) return irr::bitruncations_performed ? 2 : 1;
|
||||
|
||||
@ -1225,8 +1232,12 @@ bool kraken_pseudohept(cell *c) {
|
||||
return ishept(c);
|
||||
else if(IRREGULAR)
|
||||
return c->type != 6;
|
||||
else if(archimedean)
|
||||
else if(archimedean && PURE)
|
||||
return c->type == isize(arcm::current.triangles[0]);
|
||||
else if(archimedean && BITRUNCATED)
|
||||
return pseudohept(c);
|
||||
else if(archimedean && DUAL)
|
||||
return true;
|
||||
else if(!euclid && S3 == 3 && !(S7&1) && gp_threecolor() == 1)
|
||||
return ishept(c);
|
||||
else
|
||||
@ -1868,12 +1879,12 @@ namespace patterns {
|
||||
return;
|
||||
}
|
||||
if(archimedean) {
|
||||
if(whichPattern == PAT_COLORING) {
|
||||
if(whichPattern == PAT_COLORING && geosupport_threecolor()) {
|
||||
if(subpattern_flags & SPF_FOOTBALL) cgroup = cpFootball;
|
||||
else cgroup = cpThree;
|
||||
}
|
||||
else if(whichPattern == PAT_CHESS && arcm::current.support_chessboard()) cgroup = cpChess;
|
||||
else if(whichPattern == 0 && (subpattern_flags & SPF_FOOTBALL) && arcm::current.support_football()) cgroup = cpFootball;
|
||||
else if(whichPattern == PAT_CHESS && geosupport_chessboard()) cgroup = cpChess;
|
||||
else if(whichPattern == PAT_TYPES && (subpattern_flags & SPF_FOOTBALL) && geosupport_football()) cgroup = cpFootball;
|
||||
return;
|
||||
}
|
||||
for(int i=0; i<isize(cpatterns); i++)
|
||||
|
@ -1148,6 +1148,8 @@ void set_geometry(eGeometry target) {
|
||||
if(gp::param.second && gp::param.second != gp::param.first)
|
||||
gp::param.second = 0;
|
||||
}
|
||||
if(DUAL && geometry != gArchimedean)
|
||||
variation = ginf[geometry].default_variation;
|
||||
if(geometry == gBinaryTiling) variation = eVariation::pure;
|
||||
|
||||
need_reset_geometry = true;
|
||||
|
Loading…
x
Reference in New Issue
Block a user