diff --git a/floorshapes.cpp b/floorshapes.cpp index 33d66906..9fea4d0e 100644 --- a/floorshapes.cpp +++ b/floorshapes.cpp @@ -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); } } diff --git a/landgen.cpp b/landgen.cpp index dff2b908..f28b24c8 100644 --- a/landgen.cpp +++ b/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); diff --git a/pattern2.cpp b/pattern2.cpp index 5bd5da33..57d4daf1 100644 --- a/pattern2.cpp +++ b/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'); diff --git a/syntetic.cpp b/syntetic.cpp index cb287b21..f909c1cf 100644 --- a/syntetic.cpp +++ b/syntetic.cpp @@ -8,10 +8,18 @@ namespace synt { vector faces = {3, 6, 6, 6}; vector adj = {1, 0, 2, 3}; vector invert = {false, false, true, false}; +vector nflags; + +static const int sfPH = 1; +static const int sfLINE = 2; + +bool have_ph, have_line, have_symmetry; int repetition = 1; int N; +vector flags; + vector>> adjacent; vector>> triangles; @@ -41,13 +49,46 @@ ld edgelength; vector 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& get_adj(heptagon *h, int cid); +pair& get_triangle(heptagon *h, int cid); +pair& get_triangle(const pair& p, int delta = 0); +pair& get_adj(const pair& 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 [%d %d]\n", at, inv); - if(faces[at] != faces[i]) printf("error!\n"); } } for(int i=0; i", 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= 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; jc7, 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& get_adj(heptagon *h, int cid); -pair& get_triangle(heptagon *h, int cid); -pair& get_triangle(const pair& 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& 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& 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& get_triangle(const pair& p) { - return triangles[p.first][p.second]; - } - -pair& get_adj(const pair& p, int delta = 0) { - return adjacent[p.first][(p.second + delta) % isize(adjacent[p.first])]; +pair& get_adj(const pair& p, int delta) { + return adjacent[p.first][(p.second + delta + MODFIXER) % isize(adjacent[p.first])]; } pair& get_triangle(const pair& 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]; + } + } + } } \ No newline at end of file