mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-04-23 11:13:13 +00:00
tes:: football colorability detected/applied
This commit is contained in:
parent
905c4e3afb
commit
b87a936a61
173
arbitrile.cpp
173
arbitrile.cpp
@ -77,6 +77,8 @@ struct shape {
|
||||
vector<int> vertex_period;
|
||||
/** list of angles at vertices in the tesfile convention */
|
||||
vector<vector<ld>> vertex_angles;
|
||||
/** football types */
|
||||
int football_type;
|
||||
};
|
||||
|
||||
struct slider {
|
||||
@ -98,8 +100,10 @@ struct intslider {
|
||||
struct arbi_tiling {
|
||||
|
||||
int order;
|
||||
/* have_line and have_ph: line and ph flags have been marked for tiles */
|
||||
bool have_line, have_ph;
|
||||
/* line flags have been marked for tiles */
|
||||
bool have_line;
|
||||
/* pseudohept flags have been marked for tiles (1), or the tiling is football-colorable (2), or neither (0) */
|
||||
int have_ph;
|
||||
/* is the tree structure given in the tes file */
|
||||
bool have_tree;
|
||||
/* is the valence data reliable */
|
||||
@ -130,6 +134,7 @@ struct arbi_tiling {
|
||||
vector<string> options;
|
||||
|
||||
int min_valence, max_valence;
|
||||
bool is_football_colorable;
|
||||
|
||||
geometryinfo1& get_geometry();
|
||||
eGeometryClass get_class() { return get_geometry().kind; }
|
||||
@ -577,6 +582,164 @@ EX void compute_vertex_valence(arb::arbi_tiling& ac) {
|
||||
}
|
||||
}
|
||||
|
||||
bool extended_football = true;
|
||||
|
||||
EX void check_football_colorability(arbi_tiling& c) {
|
||||
for(auto&sh: c.shapes) for(auto v: sh.vertex_valence)
|
||||
if(v % 3) return;
|
||||
|
||||
for(int i=0; i<3; i++) {
|
||||
for(auto&sh: c.shapes) sh.football_type = 3;
|
||||
|
||||
vector<int> aqueue;
|
||||
|
||||
c.shapes[0].football_type = i;
|
||||
aqueue = {0};
|
||||
bool bad = false;
|
||||
for(int qi=0; qi<isize(aqueue); qi++) {
|
||||
int sid = aqueue[qi];
|
||||
|
||||
auto& sh = c.shapes[sid];
|
||||
|
||||
for(int j=0; j<sh.size(); j++) {
|
||||
auto &co = sh.connections[j];
|
||||
auto t = sh.football_type;
|
||||
if(c.have_ph && ((sh.flags & arcm::sfPH) != (t==2))) bad = true;
|
||||
|
||||
auto assign = [&] (int tt) {
|
||||
auto& t1 = c.shapes[co.sid].football_type;
|
||||
if(t1 == 3) {
|
||||
t1 = tt;
|
||||
aqueue.push_back(co.sid);
|
||||
}
|
||||
else {
|
||||
if(t1 != tt) bad = true;
|
||||
}
|
||||
};
|
||||
|
||||
if(t < 2) {
|
||||
if((j & 1) == t) assign(2); else assign((co.eid & 1) ? 0 : 1);
|
||||
}
|
||||
else {
|
||||
assign((co.eid & 1) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!bad) {
|
||||
c.have_ph = 2;
|
||||
for(auto& sh: c.shapes) if(sh.football_type == 2) sh.flags |= arcm::sfPH;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(extended_football) {
|
||||
for(auto&sh: c.shapes)
|
||||
sh.football_type = 0;
|
||||
|
||||
for(int i=0; i<3*isize(c.shapes); i++) {
|
||||
for(auto&sh: c.shapes) {
|
||||
int &res = sh.football_type;
|
||||
int siz = sh.size();
|
||||
if(sh.apeirogonal) siz -= 2;
|
||||
else if(siz & 1) res |= 3;
|
||||
if((sh.cycle_length & 1) && !sh.apeirogonal) {
|
||||
if(res & 3) res |= 3;
|
||||
}
|
||||
if(sh.apeirogonal && (siz & 1)) {
|
||||
if(res & 3) res |= 3;
|
||||
}
|
||||
if(sh.flags & arcm::sfPH) res |= 3;
|
||||
for(int i=0; i<sh.size(); i++) {
|
||||
auto co = sh.connections[i];
|
||||
co.eid %= c.shapes[co.sid].cycle_length;
|
||||
if(res & 1) {
|
||||
if(i&1) {
|
||||
if(co.eid & 1)
|
||||
c.shapes[co.sid].football_type |= 1;
|
||||
else
|
||||
c.shapes[co.sid].football_type |= 2;
|
||||
}
|
||||
else
|
||||
c.shapes[co.sid].football_type |= 4;
|
||||
}
|
||||
if(res & 2) {
|
||||
if(!(i&1)) {
|
||||
if(co.eid & 1)
|
||||
c.shapes[co.sid].football_type |= 1;
|
||||
else
|
||||
c.shapes[co.sid].football_type |= 2;
|
||||
}
|
||||
else
|
||||
c.shapes[co.sid].football_type |= 4;
|
||||
}
|
||||
if(res & 4) {
|
||||
if(co.eid & 1)
|
||||
c.shapes[co.sid].football_type |= 2;
|
||||
else
|
||||
c.shapes[co.sid].football_type |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.is_football_colorable = true;
|
||||
for(auto&sh: c.shapes)
|
||||
if(sh.football_type == 7)
|
||||
c.is_football_colorable = false;
|
||||
|
||||
if(c.is_football_colorable) {
|
||||
vector<array<int, 3> > new_indices(isize(c.shapes), make_array(-1, -1, -1));
|
||||
auto oldshapes = c.shapes;
|
||||
c.shapes.clear();
|
||||
for(int i=0; i<isize(oldshapes); i++)
|
||||
for(int t=0; t<3; t++)
|
||||
if(!(oldshapes[i].football_type & (1<<t))) {
|
||||
if(t == 1 && (oldshapes[i].cycle_length & 1)) continue;
|
||||
new_indices[i][t] = isize(c.shapes);
|
||||
c.shapes.push_back(oldshapes[i]);
|
||||
c.shapes.back().football_type = t;
|
||||
if(t == 2) c.shapes.back().flags |= arcm::sfPH;
|
||||
}
|
||||
|
||||
for(int i=0; i<isize(oldshapes); i++)
|
||||
for(int t=0; t<3; t++) {
|
||||
int ni = new_indices[i][t];
|
||||
if(ni == -1) continue;
|
||||
auto& sh = c.shapes[ni];
|
||||
for(int j=0; j<isize(sh); j++) {
|
||||
auto &co = sh.connections[j];
|
||||
auto assign = [&] (int tt) {
|
||||
auto ni1 = new_indices[co.sid][tt];
|
||||
if(ni1 == -1 && tt == 1) {
|
||||
ni1 = new_indices[co.sid][0];
|
||||
co.eid += oldshapes[co.sid].cycle_length;
|
||||
co.eid %= isize(oldshapes[co.sid]);
|
||||
}
|
||||
co.sid = ni1;
|
||||
};
|
||||
|
||||
co.eid %= oldshapes[co.sid].cycle_length;
|
||||
if(t < 2) {
|
||||
if((j & 1) == t) assign(2); else assign((co.eid & 1) ? 0 : 1);
|
||||
}
|
||||
else {
|
||||
assign((co.eid & 1) ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
if((sh.cycle_length&1) && (t < 2)) sh.cycle_length *= 2;
|
||||
if(debugflags & DF_GEOM)
|
||||
println(hlog, tie(i,t), " becomes ", ni, " with connections ", sh.connections, " and cycle length = ", sh.cycle_length);
|
||||
}
|
||||
|
||||
c.have_ph = 2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for(auto&sh: c.shapes) sh.football_type = 3;
|
||||
}
|
||||
|
||||
EX void add_connection(arbi_tiling& c, int ai, int as, int bi, int bs, int m) {
|
||||
int as0 = as, bs0 = bs;
|
||||
auto& ash = c.shapes[ai];
|
||||
@ -602,7 +765,9 @@ EX void set_defaults(arb::arbi_tiling& c, bool keep_sliders, string fname) {
|
||||
c.range = 0;
|
||||
c.boundary_ratio = 1;
|
||||
c.floor_scale = .5;
|
||||
c.have_ph = c.have_line = false;
|
||||
c.have_ph = 0;
|
||||
c.have_line = false;
|
||||
c.is_football_colorable = false;
|
||||
c.have_tree = false;
|
||||
c.have_valence = false;
|
||||
c.yendor_backsteps = 0;
|
||||
@ -920,6 +1085,8 @@ EX void load(const string& fname, bool load_as_slided IS(false), bool keep_slide
|
||||
}
|
||||
if(!c.have_tree) compute_vertex_valence(c);
|
||||
|
||||
check_football_colorability(c);
|
||||
|
||||
if(c.have_tree) rulegen::verify_parsed_treestates(c);
|
||||
|
||||
if(!load_as_slided) slided = current;
|
||||
|
@ -885,7 +885,7 @@ void geometry_information::generate_floorshapes() {
|
||||
ms.c.connect(j, &models[co.sid], co.eid, co.mirror);
|
||||
}
|
||||
}
|
||||
for(int i=0; i<n; i++) generate_floorshapes_for(i, &models[i], 0, 0);
|
||||
for(int i=0; i<n; i++) generate_floorshapes_for(i, &models[i], c.shapes[i].football_type < 2, c.shapes[i].football_type == 0);
|
||||
}
|
||||
|
||||
else if(geometry == gBinary4) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user