1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-11-27 14:37:16 +00:00

arcm:: all patterns work

This commit is contained in:
Zeno Rogue 2018-08-20 15:24:44 +02:00
parent ad8ef53d84
commit cd91148459
9 changed files with 101 additions and 61 deletions

View File

@ -54,7 +54,7 @@ struct archimedean_tiling {
pair<int, int>& get_adj(const pair<int, int>& p, int delta = 0);
int support_threecolor();
int support_graveyard();
int support_football();
bool support_chessboard();
};
@ -396,6 +396,7 @@ heptagon *build_child(heptagon *parent, int d, int id, int pindex) {
h->distance = parent->distance + 1;
if(id < 2*current.N)
h->fieldval = parent->move(0)->fieldval + (d/2);
h->fiftyval = isize(archimedean_gmatrix);
return h;
}
@ -630,20 +631,19 @@ auto hook =
#endif
int archimedean_tiling::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;
// if(nonbitrunc)
return (isize(faces) == 3 && invert[0] && invert[1] && invert[2] && faces[0] % 2 == 0 && faces[1] % 2 == 0 && faces[2] % 2 == 0) ? 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 archimedean_tiling::support_graveyard() {
if(!nonbitrunc) return 2;
int archimedean_tiling::support_football() {
// if(!nonbitrunc) return 2;
return
isize(faces) == 3 && faces[0] % 2 == 0 ? 2 :
have_ph ? 1 :
(isize(faces) == 3 && invert[0] && invert[1] && invert[2] && faces[1] % 2 == 0 && faces[2] % 2 == 0) ? 2 :
0;
}
@ -709,10 +709,10 @@ vector<string> samples = {
"(3,3,3,3,5)(1,2)(0,4)(3)",
/* prisms */
"(4,4,3)",
"(4,4,5)",
"(4,4,6)",
"(4,4,7)",
"(3,4,4)",
"(5,4,4)",
"(6,4,4)",
"(7,4,4)",
/* sample antiprisms */
"(3,3,3,4)(1)(2)",
@ -754,6 +754,13 @@ void enable(archimedean_tiling& arct) {
stop_game();
if(geometry != gArchimedean) targetgeometry = gArchimedean, stop_game_and_switch_mode(rg::geometry);
nonbitrunc = true; need_reset_geometry = true;
patterns::whichPattern = 0;
if(texture::config.tstate == texture::tsActive && texture::cgroup == cpThree)
patterns::whichPattern = patterns::PAT_COLORING;
if(texture::config.tstate == texture::tsActive && texture::cgroup == cpFootball)
patterns::whichPattern = 0, patterns::subpattern_flags = patterns::SPF_FOOTBALL;
if(texture::config.tstate == texture::tsActive && texture::cgroup == cpChess)
patterns::whichPattern = patterns::PAT_CHESS;
current = arct;
start_game();
}
@ -792,8 +799,14 @@ void show() {
dialog::addBreak(100);
if(edited.errors)
dialog::addInfo(edited.errormsg, 0xFF0000);
else if(texture::config.tstate == texture::tsActive &&
((texture::cgroup == cpThree && edited.support_threecolor() < 2) ||
(texture::cgroup == cpFootball && edited.support_football() < 2) ||
(texture::cgroup == cpChess && !edited.support_chessboard())))
dialog::addInfo(XLAT("Pattern incompatible."), 0xC0C000);
else
dialog::addInfo(XLAT("OK"), 0x00FF00);
dialog::addBreak(100);
dialog::addSelItem(XLAT("full angle"), fts(edited.euclidean_angle_sum * 180) + "°", 0);
dialog::addBreak(100);
@ -808,18 +821,26 @@ void show() {
edited.parse();
});
dialog::addBreak(100);
for(int i=0; i<10; i++) {
int j = i + spos;
if(j >= isize(tilings)) continue;
auto &ps = tilings[j];
dialog::addSelItem(ps.symbol, fts(ps.euclidean_angle_sum * 180) + "°", 'a' + i);
int nextpos = spos;
int shown = 0;
while(nextpos < isize(tilings) && shown < 10) {
auto &ps = tilings[nextpos++];
if(texture::config.tstate == texture::tsActive && texture::cgroup == cpThree && ps.support_threecolor() < 2)
continue;
if(texture::config.tstate == texture::tsActive && texture::cgroup == cpFootball && ps.support_football() < 2)
continue;
if(texture::config.tstate == texture::tsActive && texture::cgroup == cpChess && !ps.support_chessboard())
continue;
dialog::addSelItem(ps.symbol, fts(ps.euclidean_angle_sum * 180) + "°", 'a' + shown);
dialog::add_action([&] () { enable(ps); });
shown++;
}
dialog::addItem(XLAT("next page"), '-');
dialog::add_action([] () {
if(spos + 10 >= isize(tilings))
if(shown == 0) nextpos = 0;
dialog::add_action([nextpos] () {
if(nextpos >= isize(tilings))
spos = 0;
else spos += 10;
else spos = nextpos;
});
if(archimedean) {

View File

@ -108,7 +108,7 @@ void generate_matrices_scale(ld scale, int noft) {
mesher ohept = msh(gNormal, 7, hexf7, hcrossf7, hcrossf7, M_PI/7, 1);
if(nonbitrunc) {
mesher nall = msh(geometry, S7, rhexf, tessf, tessf, -M_PI, scale);
bool use = geosupport_graveyard() < 2;
bool use = geosupport_football() < 2;
if(use && noft == 1) {
mesher opure = msh(gNormal, 7, 0.620672, 1.090550, 1.090550, M_PI/7, 1);
generate_matrices(hept_matrices, opure, nall);
@ -399,7 +399,7 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
if(!gp::on && !irr::on && !binarytiling && !archimedean) {
generate_matrices_scale(fsh.scale, fsh.noftype);
if(nonbitrunc && geosupport_graveyard() < 2 && fsh.shapeid2) {
if(nonbitrunc && geosupport_football() < 2 && fsh.shapeid2) {
if(id == 0) bshape2(fsh.b[0], fsh.prio, fsh.shapeid2, hept_matrices);
if(id == 1) bshape2(fsh.b[1], fsh.prio, fsh.shapeid2, hept_matrices);
}
@ -408,7 +408,7 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
if(id == 1) bshape2(fsh.b[1], fsh.prio, fsh.shapeid1, hept_matrices);
}
generate_matrices_scale(fsh.scale * SHADMUL, fsh.noftype);
if(nonbitrunc && geosupport_graveyard() < 2 && fsh.shapeid2) {
if(nonbitrunc && geosupport_football() < 2 && fsh.shapeid2) {
if(id == 0) bshape2(fsh.shadow[0], fsh.prio, fsh.shapeid2, hept_matrices);
if(id == 1) bshape2(fsh.shadow[1], fsh.prio, fsh.shapeid2, hept_matrices);
}
@ -421,7 +421,7 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
else {
generate_matrices_scale(fsh.scale, fsh.noftype);
auto& m = (siid && geosupport_graveyard() == 2) ? hex_matrices : hept_matrices;
auto& m = (siid && geosupport_football() == 2) ? hex_matrices : hept_matrices;
int cor = c->type;
@ -452,7 +452,7 @@ void generate_floorshapes_for(int id, cell *c, int siid, int sidir) {
}
if(i != isize(m.v)) printf("warning: i=%d sm=%d\n", i, isize(m.v));
bshape2((ii?fsh.shadow:fsh.b)[id], fsh.prio, (fsh.shapeid2 && geosupport_graveyard() < 2) ? fsh.shapeid2 : siid?fsh.shapeid0:fsh.shapeid1, m);
bshape2((ii?fsh.shadow:fsh.b)[id], fsh.prio, (fsh.shapeid2 && geosupport_football() < 2) ? fsh.shapeid2 : siid?fsh.shapeid0:fsh.shapeid1, m);
}
}
}
@ -490,8 +490,8 @@ void generate_floorshapes() {
for(int i=0; i<2*ac.N + (nonbitrunc ? 0 : 2); i++) {
arcm::id_of(&master) = i;
model.type = isize(ac.triangles[i]);
if(geosupport_graveyard() == 2)
generate_floorshapes_for(i, &model, !arcm::pseudohept(i), i/2);
if(geosupport_football() == 2)
generate_floorshapes_for(i, &model, !arcm::pseudohept(i), i >= 4 ? 1 : 0);
else
generate_floorshapes_for(i, &model, 0, 0);
}
@ -544,7 +544,7 @@ namespace gp {
// if(pattern_threecolor(createMov(c, fixdir(si.dir, c))) != (siid+1)%3) printf("threecolor mismatch direction\n");
sidir = (fixdir(si.dir, c)) & 1;
}
else if(geosupport_graveyard() == 2) {
else if(geosupport_football() == 2) {
siid = !pseudohept(c);
sidir = !ishex1(c);
}
@ -649,6 +649,11 @@ void viewmat() {
hyperpoint cn = V * nearcorner(cwt.at, i);
hyperpoint cf0 = V * farcorner(cwt.at, i, 0);
hyperpoint cf1 = V * farcorner(cwt.at, i, 1);
queuestr(ci, 20, its(i), 0x0000FF, 1);
if(vid.grid)
queuestr(cn, 20, its(i), 0x00FF00, 1);
else
queuestr(gmatrix[cwt.at->move(i)] * C0, 20, its(i), 0x00FFFF, 1);
queueline(V * C0, ci, 0xFFFFFFFF, 3);
queueline(ci, ci1, 0xFFFF00FF, 3);
queueline(ci, cn, 0xFF00FFFF, 3);

View File

@ -7720,7 +7720,7 @@ bool movepcto(int d, int subdir, bool checkonly) {
if(checkonly) return false;
if(nonAdjacent(cwt.at,c2))
addMessage(XLAT(
geosupport_graveyard() < 2 ?
geosupport_football() < 2 ?
"You cannot move between the cells without dots here!" :
"You cannot move between the triangular cells here!"
));

View File

@ -392,7 +392,7 @@ hyperpoint get_corner_position(cell *c, int cid, ld cf) {
if(archimedean) {
auto &ac = arcm::current;
if(arcm::id_of(c->master) >= ac.N*2) return C0;
auto& t = ac.get_triangle(c->master, cid);
auto& t = ac.get_triangle(c->master, cid-1);
return xspinpush0(-t.first, t.second * 3 / cf);
}
if(nonbitrunc) {
@ -453,9 +453,9 @@ hyperpoint nearcorner(cell *c, int i) {
}
if(archimedean) {
auto &ac = arcm::current;
auto& t = ac.get_triangle(c->master, i);
auto& t = ac.get_triangle(c->master, i-1);
int id = arcm::id_of(c->master);
int id1 = ac.get_adj(ac.get_adj(c->master, i), -2).first;
int id1 = ac.get_adj(ac.get_adj(c->master, i-1), -2).first;
return xspinpush0(-t.first - M_PI / c->type, ac.inradius[id/2] + ac.inradius[id1/2]);
}
if(binarytiling) {
@ -507,9 +507,9 @@ hyperpoint farcorner(cell *c, int i, int which) {
return nearcorner(c, (i+which) % c->type); // lazy
if(archimedean) {
auto &ac = arcm::current;
auto& t = ac.get_triangle(c->master, i);
auto& t = ac.get_triangle(c->master, i-1);
int id = arcm::id_of(c->master);
auto id1 = ac.get_adj(ac.get_adj(c->master, i), -2).first;
auto id1 = ac.get_adj(ac.get_adj(c->master, i-1), -2).first;
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]);
}

View File

@ -3122,7 +3122,7 @@ void floorShadow(cell *c, const transmatrix& V, int col) {
void set_maywarp_floor(cell *c) {
bool warp = isWarped(c);
if(warp && !shmup::on && geosupport_graveyard() == 2) {
if(warp && !shmup::on && geosupport_football() == 2) {
auto si = patterns::getpatterninfo(c, 0, 0);
if(si.id == 0 || si.id == 1)
set_floor(shTriheptaFloor);
@ -4187,8 +4187,8 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
auto si = patterns::getpatterninfo0(c);
for(int i=0; i<c->type; i += si.symmetries) {
queuepoly(V * applyPatterndir(c,si), shAsymmetric, darkena(0x000000, 0, 0xC0));
for(int i=(si.dir + MODFIXER) % si.symmetries; i<c->type; i += si.symmetries) {
queuepoly(V * ddspin(c, i) * (si.reflect?Mirror:Id), shAsymmetric, darkena(0x000000, 0, 0xC0));
si.dir += si.symmetries;
}
@ -4355,7 +4355,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
case waClosePlate: case waOpenPlate: {
transmatrix V2 = V;
if(wmescher && geosupport_graveyard() == 2 && pseudohept(c)) V2 = V * spin(M_PI / c->type);
if(wmescher && geosupport_football() == 2 && pseudohept(c)) V2 = V * spin(M_PI / c->type);
draw_floorshape(c, V2, shMFloor, darkena(winf[c->wall].color, 0, 0xFF));
draw_floorshape(c, V2, shMFloor2, (!wmblack) ? darkena(fcol, 1, 0xFF) : darkena(0,1,0xFF));
break;

View File

@ -3516,7 +3516,7 @@ void queuechr(int x, int y, int shift, int size, char chr, int col, int frame =
int zebra3(cell *c);
int geosupport_threecolor();
int geosupport_graveyard();
int geosupport_football();
bool ishex1(cell *c);
namespace fieldpattern { int fieldval_uniq(cell *c); int fieldval_uniq_rand(cell *c, int d); }
bool warptype(cell *c);

View File

@ -1271,7 +1271,7 @@ land_validity_t& land_validity(eLand l) {
return unbounded_only;
// Graveyard pattern does not work on non-bitrunc weird geometries
if((l == laGraveyard && !randomPatternsMode) || l == laRuins || l == laRedRock) switch(geosupport_graveyard()) {
if((l == laGraveyard && !randomPatternsMode) || l == laRuins || l == laRedRock) switch(geosupport_football()) {
case 0:
return dont_work;
case 1:
@ -1280,7 +1280,7 @@ land_validity_t& land_validity(eLand l) {
}
// Warped Coast does not work on non-bitrunc S3s (except standard heptagonal where we have to keep it)
if(l == laWarpCoast && (S3==3) && geosupport_graveyard() != 2) {
if(l == laWarpCoast && (S3==3) && geosupport_football() != 2) {
return ugly_version;
}

View File

@ -339,6 +339,8 @@ pair<int, bool> fieldval(cell *c) {
}
int fieldval_uniq(cell *c) {
if(archimedean && sphere)
return c->master->fiftyval;
if(sphere) {
if(ctof(c) || gp::on || irr::on) return c->master->fieldval;
else return createMov(c, 0)->master->fieldval + 256 * createMov(c,2)->master->fieldval + (1<<16) * createMov(c,4)->master->fieldval;
@ -868,8 +870,7 @@ namespace patterns {
}
if(euclid6 && (sub & SPF_FULLSYM))
si.symmetries = 1;
if(S7 == 4)
applyAlt(si, sub, PAT_COLORING);
applyAlt(si, sub, PAT_COLORING);
}
patterninfo getpatterninfo(cell *c, char pat, int sub) {
@ -894,12 +895,10 @@ namespace patterns {
}
if(archimedean && pat == 0) {
si.id = pseudohept(c); si.symmetries = 1;
si.reflect = false; si.dir = 0;
return si;
}
if(archimedean && pat == PAT_SIBLING) {
if(sub & SPF_FOOTBALL) {
val_threecolors(c, si, sub);
return si;
}
int id = arcm::id_of(c->master);
auto& ca = arcm::current;
si.id = ca.tilegroup[id];
@ -1019,7 +1018,7 @@ namespace patterns {
if(euclid)
// use the torus ID
si.id = fieldpattern::fieldval_uniq(c);
else if(nonbitrunc)
else if(nonbitrunc && !archimedean)
// use the actual field codes
si.id = fieldpattern::fieldval(c).first;
else
@ -1042,7 +1041,7 @@ namespace patterns {
else val_threecolors(c, si, sub);
}
else if(pat == PAT_COLORING && (S7 == 4 || euclid || (a38 && gp_threecolor() == 1))) {
else if(pat == PAT_COLORING && (S7 == 4 || euclid || (a38 && gp_threecolor() == 1) || archimedean)) {
val_threecolors(c, si, sub);
}
@ -1081,11 +1080,11 @@ int geosupport_threecolor() {
return 0;
}
int geosupport_graveyard() {
int geosupport_football() {
// always works in bitrunc geometries
if(!nonbitrunc) return 2;
if(archimedean) return arcm::current.support_graveyard();
if(archimedean) return arcm::current.support_football();
if(irr::on) return irr::bitruncations_performed ? 2 : 1;
@ -1493,10 +1492,10 @@ namespace patterns {
if(geosupport_chessboard())
dialog::addBoolItem(XLAT("chessboard"), (whichPattern == PAT_CHESS), PAT_CHESS);
if(a38 || a46 || euclid || S3 == 4 || S7 == 4)
if(geosupport_threecolor() == 2)
dialog::addBoolItem(XLAT("coloring"), (whichPattern == PAT_COLORING), PAT_COLORING);
if(sphere)
if(sphere_narcm)
dialog::addBoolItem(XLAT("siblings"), (whichPattern == PAT_SIBLING), PAT_SIBLING);
if(euclid)
@ -1545,7 +1544,7 @@ namespace patterns {
if(euclid && among(whichPattern, PAT_COLORING, 0) && !archimedean)
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
if(archimedean && arcm::current.have_symmetry && whichPattern == PAT_SIBLING)
if(archimedean && arcm::current.have_symmetry && whichPattern == 0)
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
if(whichPattern == PAT_SINGLETYPE) {
@ -1564,7 +1563,7 @@ namespace patterns {
dialog::addBoolItem(XLAT("extra symmetries"), subpattern_flags & SPF_EXTRASYM, '=');
}
if((a38 || (sphere && S7 == 4) || euclid4 || a46) && !nonbitrunc) {
if((whichPattern == PAT_COLORING) || (whichPattern == 0 && archimedean)) {
dialog::addBoolItem(XLAT("alternate coloring"), subpattern_flags & SPF_ALTERNATE, '\'');
dialog::addBoolItem(XLAT("football pattern"), subpattern_flags & SPF_FOOTBALL, '*');
}
@ -1611,13 +1610,13 @@ namespace patterns {
else if(uni == '\'') {
subpattern_flags ^= SPF_ALTERNATE;
subpattern_flags &= ~SPF_FOOTBALL;
// subpattern_flags &= ~SPF_FOOTBALL;
texture::config.remap();
}
else if(uni == '*') {
subpattern_flags ^= SPF_FOOTBALL;
subpattern_flags &= ~SPF_ALTERNATE;
// subpattern_flags &= ~SPF_ALTERNATE;
texture::config.remap();
}
@ -1828,6 +1827,19 @@ namespace patterns {
void computeCgroup() {
cgroup = cpUnknown;
if(whichPattern == PAT_SINGLETYPE) {
cgroup = cpSingle;
return;
}
if(archimedean) {
if(whichPattern == PAT_COLORING) {
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;
return;
}
for(int i=0; i<isize(cpatterns); i++)
for(int j=0; j<isize(cpatterns[i].geometries); j++) {
auto &g = cpatterns[i].geometries[j];

View File

@ -287,6 +287,8 @@ int getTriangleID(cell *c, patterns::patterninfo& si, hyperpoint h) {
int goldbergcode(cell *c, const patterns::patterninfo& si) {
if(irr::on)
return irr::cellindex[c] << 8;
else if(archimedean)
return arcm::id_of(c->master) << 8;
else if(!gp::on) return 0;
else if(c == c->master->c7) return (fixdir(si.dir, c) << 8);
else return (get_code(gp::get_local_info(c)) << 16) | (fixdir(si.dir, c) << 8);