mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
synt:: graveyard and three-color and line patterns
This commit is contained in:
parent
29a9980fc3
commit
f738bb7002
@ -493,7 +493,7 @@ void generate_floorshapes() {
|
||||
for(int i=0; i<2*synt::N + (nonbitrunc ? 0 : 2); i++) {
|
||||
synt::id_of(&master) = i;
|
||||
model.type = isize(synt::triangles[i]);
|
||||
generate_floorshapes_for(i, &model, i >= 2*synt::N, 0);
|
||||
generate_floorshapes_for(i, &model, !synt::pseudohept(i), i/2);
|
||||
}
|
||||
}
|
||||
|
||||
|
14
landgen.cpp
14
landgen.cpp
@ -480,7 +480,9 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
else
|
||||
v = 6;
|
||||
}
|
||||
else if(torus || hyperbolic_not37 || quotient) {
|
||||
else if(syntetic && synt::have_line)
|
||||
v = synt::linespattern(c) ? 24 : 16;
|
||||
else if(torus || hyperbolic_not37 || quotient || syntetic) {
|
||||
v = hrand(100) < 25 ? 24 : 16;
|
||||
}
|
||||
else if(euclid) {
|
||||
@ -541,7 +543,9 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
case laZebra:
|
||||
if(d==8) {
|
||||
if(torus) ;
|
||||
else if(euclid) {
|
||||
else if(syntetic && synt::have_line)
|
||||
c->wall = synt::linespattern(c) ? waTrapdoor : waNone;
|
||||
else if(euclid && !syntetic) {
|
||||
int x,y;
|
||||
tie(x,y) = cell_to_pair(c);
|
||||
if(y&1) c->wall = waTrapdoor;
|
||||
@ -561,13 +565,15 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
case laWineyard:
|
||||
if(d==8) {
|
||||
if(torus) ;
|
||||
else if(euclid) {
|
||||
else if(syntetic && synt::have_line)
|
||||
c->wall = synt::linespattern(c) ? waVinePlant : waNone;
|
||||
else if(euclid && !syntetic) {
|
||||
int x,y;
|
||||
tie(x,y) = cell_to_pair(c);
|
||||
int dy = gmod(y, 3);
|
||||
if(dy == 1) c->wall = waVinePlant;
|
||||
}
|
||||
else if(a4 || sphere)
|
||||
else if(a4 || sphere || syntetic)
|
||||
c->wall = hrand(100) < 50 ? waNone : waVinePlant;
|
||||
else {
|
||||
int v = emeraldval(c);
|
||||
|
12
pattern2.cpp
12
pattern2.cpp
@ -1053,12 +1053,16 @@ int geosupport_threecolor() {
|
||||
return 2;
|
||||
if(a46 && nonbitrunc)
|
||||
return 1;
|
||||
if(syntetic) return synt::support_threecolor();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int geosupport_graveyard() {
|
||||
// always works in bitrunc geometries
|
||||
if(!nonbitrunc) return 2;
|
||||
|
||||
if(syntetic) return synt::support_graveyard();
|
||||
|
||||
if(irr::on) return irr::bitruncations_performed ? 2 : 1;
|
||||
|
||||
// always works in patterns supporting three-color
|
||||
@ -1073,6 +1077,7 @@ int geosupport_graveyard() {
|
||||
}
|
||||
|
||||
int pattern_threecolor(cell *c) {
|
||||
if(syntetic) return synt::threecolor(synt::id_of(c->master));
|
||||
if(S3 == 3 && !(S7&1) && gp_threecolor() == 1 && c->master->c7 != c) {
|
||||
auto li = gp::get_local_info(c);
|
||||
int rel = (li.relative.first - li.relative.second + MODFIXER) % 3;
|
||||
@ -1173,7 +1178,7 @@ int pattern_threecolor(cell *c) {
|
||||
bool pseudohept(cell *c) {
|
||||
if(irr::on) return irr::pseudohept(c);
|
||||
if(binarytiling) return c->type & c->master->distance & 1;
|
||||
if(syntetic) return synt::id_of(c->master) < 2 * isize(synt::faces);
|
||||
if(syntetic) return synt::pseudohept(synt::id_of(c->master));
|
||||
if(gp::on && gp_threecolor() == 2)
|
||||
return gp::pseudohept_val(c) == 0;
|
||||
if(gp::on && gp_threecolor() == 1 && (S7&1) && (S3 == 3))
|
||||
@ -1215,6 +1220,8 @@ namespace patterns {
|
||||
char whichCanvas = 0;
|
||||
|
||||
int generateCanvas(cell *c) {
|
||||
if(whichCanvas == 'A' && syntetic)
|
||||
return distcolors[synt::tilegroup[synt::id_of(c->master)] & 7];
|
||||
if(whichCanvas == 'C' && hyperbolic) {
|
||||
using namespace fieldpattern;
|
||||
int z = currfp.getdist(fieldval(c), make_pair(0,false));
|
||||
@ -1389,6 +1396,9 @@ namespace patterns {
|
||||
dialog::addSelItem(XLAT("field pattern N"), "field", 'N');
|
||||
dialog::addSelItem(XLAT("field pattern S"), "field", 'S');
|
||||
}
|
||||
|
||||
if(syntetic)
|
||||
dialog::addSelItem(XLAT("Archimedean"), "Archimedean", 'A');
|
||||
|
||||
dialog::addBreak(100);
|
||||
dialog::addBoolItem(XLATN(winf[waInvisibleFloor].name), canvas_invisible, 'i');
|
||||
|
182
syntetic.cpp
182
syntetic.cpp
@ -8,10 +8,18 @@ namespace synt {
|
||||
vector<int> faces = {3, 6, 6, 6};
|
||||
vector<int> adj = {1, 0, 2, 3};
|
||||
vector<bool> invert = {false, false, true, false};
|
||||
vector<int> nflags;
|
||||
|
||||
static const int sfPH = 1;
|
||||
static const int sfLINE = 2;
|
||||
|
||||
bool have_ph, have_line, have_symmetry;
|
||||
|
||||
int repetition = 1;
|
||||
int N;
|
||||
|
||||
vector<int> flags;
|
||||
|
||||
vector<vector<pair<int, int>>> adjacent;
|
||||
|
||||
vector<vector<pair<ld, ld>>> triangles;
|
||||
@ -41,13 +49,46 @@ ld edgelength;
|
||||
|
||||
vector<ld> inradius, circumradius, alphas;
|
||||
|
||||
int matches[30][30];
|
||||
int periods[30];
|
||||
int tilegroup[30], groupoffset[30], tilegroups;
|
||||
|
||||
int gcd(int x, int y) { return x ? gcd(y%x, x) : y; }
|
||||
|
||||
int errors;
|
||||
|
||||
pair<int, int>& get_adj(heptagon *h, int cid);
|
||||
pair<ld, ld>& get_triangle(heptagon *h, int cid);
|
||||
pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta = 0);
|
||||
pair<int, int>& get_adj(const pair<int, int>& p, int delta = 0);
|
||||
|
||||
void make_match(int a, int i, int b, int j) {
|
||||
if(periods[a] != periods[b])
|
||||
errors++;
|
||||
if(matches[a][b] == -1)
|
||||
matches[a][b] = j - i, matches[b][a] = i - j;
|
||||
else
|
||||
periods[a] = periods[b] = gcd(matches[a][b] - (j-i), periods[a]);
|
||||
}
|
||||
|
||||
void prepare() {
|
||||
|
||||
errors = 0;
|
||||
|
||||
/* build the 'adjacent' table */
|
||||
|
||||
N = isize(faces);
|
||||
int M = 2 * N + 2;
|
||||
adjacent.clear();
|
||||
adjacent.resize(2*N+2);
|
||||
adjacent.resize(M);
|
||||
|
||||
have_symmetry = false;
|
||||
for(int i=0; i<N; i++) if(invert[i]) have_symmetry = true;
|
||||
|
||||
for(int i=0; i<M; i++) for(int j=0; j<M; j++) matches[i][j] = i==j ? 0 : -1;
|
||||
|
||||
for(int i=0; i<M; i++) periods[i] = i<2*N ? faces[i/2] : N;
|
||||
|
||||
for(int i=0; i<N; i++) {
|
||||
for(int oi=0; oi<1; oi++) {
|
||||
int at = (i+oi)%N;
|
||||
@ -62,24 +103,14 @@ void prepare() {
|
||||
else at = (at+N-1) % N;
|
||||
}
|
||||
printf("-> [%d %d]\n", at, inv);
|
||||
if(faces[at] != faces[i]) printf("error!\n");
|
||||
}
|
||||
}
|
||||
for(int i=0; i<N; i++) {
|
||||
adjacent[2*N].emplace_back(2*i, 0);
|
||||
int ai = (i+1) % N;
|
||||
adjacent[2*N].emplace_back(2*N+int(invert[ai]), (2*adj[ai]+2*N-1) % (2*N));
|
||||
}
|
||||
|
||||
for(int i=0; i<2*N+2; i++) {
|
||||
printf("prelim adjacent %2d:", i);
|
||||
for(int j=0; j<isize(adjacent[i]); j++) {
|
||||
auto p = adjacent[i][j];
|
||||
printf(" (%d,%d)", p.first, p.second);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
for(int d=0; d<=2*N; d+=2) {
|
||||
int s = isize(adjacent[d]);
|
||||
for(int i=0; i<s; i++) {
|
||||
@ -87,7 +118,7 @@ void prepare() {
|
||||
adjacent[d+1].emplace_back(orig.first ^ 1, orig.second);
|
||||
}
|
||||
}
|
||||
for(int d=0; d<2*N+2; d++) {
|
||||
for(int d=0; d<M; d++) {
|
||||
int s = isize(adjacent[d]);
|
||||
for(int i=0; i<s; i++) {
|
||||
auto& orig = adjacent[d][i];
|
||||
@ -95,20 +126,17 @@ void prepare() {
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<2*N+2; i++) {
|
||||
for(int i=0; i<M; i++) {
|
||||
printf("adjacent %2d:", i);
|
||||
for(int j=0; j<isize(adjacent[i]); j++) {
|
||||
auto p = adjacent[i][j];
|
||||
printf(" (%d,%d)", p.first, p.second);
|
||||
auto q = adjacent[p.first][p.second];
|
||||
printf(" <%d,%d>", q.first, q.second);
|
||||
if(isize(adjacent[q.first]) != isize(adjacent[i])) printf(" {error}");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/* verify all the triangles */
|
||||
for(int i=0; i<2*N+2; i++) {
|
||||
for(int i=0; i<M; i++) {
|
||||
for(int j=0; j<isize(adjacent[i]); j++) {
|
||||
int ai = i, aj = j;
|
||||
printf("triangle ");
|
||||
@ -118,10 +146,55 @@ void prepare() {
|
||||
aj++; if(aj >= isize(adjacent[ai])) aj = 0;
|
||||
}
|
||||
printf("-> [%d %d]\n", ai, aj);
|
||||
if(isize(adjacent[ai]) != isize(adjacent[i])) printf("error!\n");
|
||||
make_match(i, j, ai, aj);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<2*N; i++) {
|
||||
for(int j=0; j<isize(adjacent[i]); j++) {
|
||||
auto aa = make_pair(i, j);
|
||||
aa = get_adj(aa, 1);
|
||||
aa = get_adj(aa, 2);
|
||||
aa = get_adj(aa, 1);
|
||||
aa = get_adj(aa, 2);
|
||||
make_match(i, j, aa.first, aa.second);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<M; i++) for(int j=0; j<M; j++) if(matches[i][j] != -1)
|
||||
for(int l=0; l<M; l++) for(int k=0; k<M; k++) if(matches[j][k] != -1) {
|
||||
make_match(i, 0, k, matches[i][j] + matches[j][k]);
|
||||
make_match(i, 0, k, matches[i][j] + matches[j][k] + gcd(periods[i], periods[j]));
|
||||
}
|
||||
for(int i=0; i<M; i++) tilegroup[i] = -1;
|
||||
tilegroups = 0;
|
||||
for(int i=0; i<M; i+=(have_symmetry?1:2)) if(tilegroup[i] == -1) {
|
||||
if(periods[i] < 0) periods[i] = -periods[i];
|
||||
for(int j=0; j<M; j++) if(matches[i][j] != -1)
|
||||
tilegroup[j] = tilegroups, groupoffset[j] = matches[i][j] % periods[i];
|
||||
tilegroups++;
|
||||
}
|
||||
|
||||
flags.clear();
|
||||
flags.resize(M);
|
||||
for(int i=0; i<M; i++)
|
||||
for(int j=0; j<2*N; j++)
|
||||
if(tilegroup[i] == tilegroup[j]) flags[i] |= nflags[j/2];
|
||||
|
||||
if(!have_ph) {
|
||||
if(nonbitrunc) {
|
||||
for(int i=0; i<M; i++) if(tilegroup[i] == 0) flags[i] |= sfPH;
|
||||
}
|
||||
else {
|
||||
for(int z=2*N; z<2*N+2; z++) flags[z] |= sfPH;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<M; i+=(have_symmetry?1:2)) {
|
||||
printf("tiling group of %2d: [%2d]%2d+Z%2d\n", i, tilegroup[i], groupoffset[i], periods[i]);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
ld sum = 0;
|
||||
for(int f: faces) sum += (f-2.) / f;
|
||||
if(sum < 1.999999) ginf[gSyntetic].cclass = gcSphere;
|
||||
@ -167,7 +240,7 @@ void prepare() {
|
||||
printf("computed edgelength = %lf\n", double(edgelength));
|
||||
|
||||
triangles.clear();
|
||||
triangles.resize(2*N+2);
|
||||
triangles.resize(M);
|
||||
for(int i=0; i<N; i++) for(int j=0; j<2; j++)
|
||||
for(int k=0; k<faces[i]; k++)
|
||||
triangles[2*i+j].emplace_back(2*M_PI/faces[i], circumradius[i]);
|
||||
@ -228,6 +301,7 @@ void initialize(heptagon *h) {
|
||||
base_distlimit = 0;
|
||||
celllister cl(h->c7, 1000, 200, NULL);
|
||||
base_distlimit = cl.dists.back();
|
||||
if(sphere) base_distlimit = 15;
|
||||
};
|
||||
|
||||
transmatrix adjcell_matrix(heptagon *h, int d);
|
||||
@ -259,11 +333,12 @@ void connectHeptagons(heptagon *h, int i, heptspin hs) {
|
||||
exit(1);
|
||||
}
|
||||
h->c.connect(i, hs);
|
||||
}
|
||||
|
||||
pair<int, int>& get_adj(heptagon *h, int cid);
|
||||
pair<ld, ld>& get_triangle(heptagon *h, int cid);
|
||||
pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta = 0);
|
||||
auto p = get_adj(h, i);
|
||||
if(tilegroup[p.first] != tilegroup[id_of(hs.at)])
|
||||
printf("should merge %d %d\n", p.first, id_of(hs.at));
|
||||
// heptagon *hnew = build_child(h, d, get_adj(h, d).first, get_adj(h, d).second);
|
||||
}
|
||||
|
||||
void create_adjacent(heptagon *h, int d) {
|
||||
|
||||
@ -323,23 +398,19 @@ void enqueue(heptagon *h, const transmatrix& T) {
|
||||
}
|
||||
|
||||
pair<ld, ld>& get_triangle(heptagon *h, int cid) {
|
||||
return triangles[id_of(h)][(parent_index_of(h) + cid) % neighbors_of(h)];
|
||||
return triangles[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
||||
}
|
||||
|
||||
pair<int, int>& get_adj(heptagon *h, int cid) {
|
||||
return adjacent[id_of(h)][(parent_index_of(h) + cid) % neighbors_of(h)];
|
||||
return adjacent[id_of(h)][(parent_index_of(h) + cid + MODFIXER) % neighbors_of(h)];
|
||||
}
|
||||
|
||||
pair<ld, ld>& get_triangle(const pair<int, int>& p) {
|
||||
return triangles[p.first][p.second];
|
||||
}
|
||||
|
||||
pair<int, int>& get_adj(const pair<int, int>& p, int delta = 0) {
|
||||
return adjacent[p.first][(p.second + delta) % isize(adjacent[p.first])];
|
||||
pair<int, int>& get_adj(const pair<int, int>& p, int delta) {
|
||||
return adjacent[p.first][(p.second + delta + MODFIXER) % isize(adjacent[p.first])];
|
||||
}
|
||||
|
||||
pair<ld, ld>& get_triangle(const pair<int, int>& p, int delta) {
|
||||
return triangles[p.first][(p.second + delta) % isize(adjacent[p.first])];
|
||||
return triangles[p.first][(p.second + delta + MODFIXER) % isize(adjacent[p.first])];
|
||||
}
|
||||
|
||||
transmatrix adjcell_matrix(heptagon *h, int d) {
|
||||
@ -414,10 +485,16 @@ void parse_symbol(string s) {
|
||||
auto isnumber = [&] () { char p = peek(); return p >= '0' && p <= '9'; };
|
||||
auto read_number = [&] () { int result = 0; while(isnumber()) result = 10 * result + peek() - '0', at++; return result; };
|
||||
|
||||
faces.clear();
|
||||
faces.clear(); nflags.clear();
|
||||
have_line = false;
|
||||
have_ph = false;
|
||||
while(true) {
|
||||
if(peek() == ')' || peek() == '^' || (peek() == '(' && isize(faces)) || peek() == 0) break;
|
||||
else if(isnumber()) faces.push_back(read_number());
|
||||
else if((peek() == 'L' || peek() == 'l') && faces.size())
|
||||
nflags.back() |= sfLINE, have_line = true;
|
||||
else if((peek() == 'H' || peek() == 'h') && faces.size())
|
||||
nflags.back() |= sfPH, have_ph = true;
|
||||
else if(isnumber()) faces.push_back(read_number()), nflags.push_back(0);
|
||||
else at++;
|
||||
}
|
||||
repetition = 1;
|
||||
@ -464,6 +541,41 @@ auto hook =
|
||||
addHook(hooks_args, 100, readArgs);
|
||||
#endif
|
||||
|
||||
int support_threecolor() {
|
||||
if(nonbitrunc)
|
||||
return
|
||||
(isize(faces) == 3 && faces[0] % 2 == 0 && faces[1] % 2 == 0 && faces[2] % 2 == 0 && tilegroup[N*2] == 3) ? 2 :
|
||||
tilegroup[N*2] > 1 ? 1 :
|
||||
0;
|
||||
for(int i: faces) if(faces[i] % 2) return tilegroup[N*2] > 1 ? 1 : 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
int support_graveyard() {
|
||||
if(!nonbitrunc) return 2;
|
||||
return
|
||||
isize(synt::faces) == 3 && synt::faces[0] % 2 == 0 ? 2 :
|
||||
synt::have_ph ? 1 :
|
||||
0;
|
||||
}
|
||||
|
||||
bool pseudohept(int id) {
|
||||
return flags[id] & synt::sfPH;
|
||||
}
|
||||
|
||||
bool linespattern(cell *c) {
|
||||
return flags[id_of(c->master)] & synt::sfLINE;
|
||||
}
|
||||
|
||||
int threecolor(int id) {
|
||||
if(nonbitrunc)
|
||||
return tilegroup[id];
|
||||
else {
|
||||
if(support_threecolor() == 2) return id < N * 2 ? (id&1) : 2;
|
||||
return tilegroup[id];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user