mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 17:10:36 +00:00
subrule 3D maps implemented
This commit is contained in:
parent
7252b04626
commit
6bc3dc9d6f
2
cell.cpp
2
cell.cpp
@ -677,7 +677,7 @@ EX int updir(heptagon *h) {
|
|||||||
#endif
|
#endif
|
||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
if(WDIM == 3 && reg3::in_rule()) {
|
if(WDIM == 3 && reg3::in_rule()) {
|
||||||
for(int i=0; i<S7; i++) if(h->move(i) && h->move(i)->distance < h->distance)
|
for(int i=0; i<h->type; i++) if(h->move(i) && h->move(i)->distance < h->distance)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -117,10 +117,11 @@ void expansion_analyzer::preliminary_grouping() {
|
|||||||
#if MAXMDIM >= 4
|
#if MAXMDIM >= 4
|
||||||
rootid = reg3::rule_get_root(0);
|
rootid = reg3::rule_get_root(0);
|
||||||
auto& chi = reg3::rule_get_children();
|
auto& chi = reg3::rule_get_children();
|
||||||
N = isize(chi) / S7;
|
auto& chpos = reg3::rule_get_childpos();
|
||||||
|
N = isize(chpos) - 1;
|
||||||
children.resize(N);
|
children.resize(N);
|
||||||
int k = 0;
|
int k = 0;
|
||||||
for(int i=0; i<N; i++) for(int j=0; j<S7; j++) {
|
for(int i=0; i<N; i++) for(int j=0; j<chpos[i+1]-chpos[i]; j++) {
|
||||||
int ck = chi[k];
|
int ck = chi[k];
|
||||||
if(ck < -1) ck += (1<<16);
|
if(ck < -1) ck += (1<<16);
|
||||||
if(ck >= 0)
|
if(ck >= 0)
|
||||||
|
193
reg3.cpp
193
reg3.cpp
@ -1292,6 +1292,7 @@ EX namespace reg3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
EX bool minimize_quotient_maps = false;
|
EX bool minimize_quotient_maps = false;
|
||||||
|
EX bool subrule = false;
|
||||||
|
|
||||||
EX bool strafe_test = false;
|
EX bool strafe_test = false;
|
||||||
|
|
||||||
@ -1846,32 +1847,38 @@ EX namespace reg3 {
|
|||||||
ruleset() : fp(0) {}
|
ruleset() : fp(0) {}
|
||||||
|
|
||||||
void load_ruleset(string fname) {
|
void load_ruleset(string fname) {
|
||||||
string buf;
|
|
||||||
#if ISANDROID || ISIOS
|
|
||||||
buf = get_asset(fname);
|
|
||||||
#else
|
|
||||||
FILE *f = fopen(fname.c_str(), "rb");
|
|
||||||
if(!f) f = fopen((rsrcdir + fname).c_str(), "rb");
|
|
||||||
buf.resize(1000000);
|
|
||||||
int qty = fread(&buf[0], 1, 1000000, f);
|
|
||||||
buf.resize(qty);
|
|
||||||
fclose(f);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
shstream ins(decompress_string(buf));
|
shstream ins(decompress_string(read_file_as_string(fname)));
|
||||||
dynamicval<bool> q(fieldpattern::use_quotient_fp, true);
|
dynamicval<bool> q(fieldpattern::use_quotient_fp, true);
|
||||||
hread_fpattern(ins, fp);
|
hread_fpattern(ins, fp);
|
||||||
|
|
||||||
hread(ins, root);
|
hread(ins, root);
|
||||||
hread(ins, children);
|
hread(ins, children);
|
||||||
hread(ins, other);
|
hread(ins, other);
|
||||||
}
|
// hread(ins, childpos);
|
||||||
|
|
||||||
void default_childpos(int t) {
|
int t = S7;
|
||||||
int qty = isize(children) / t;
|
int qty = isize(children) / t;
|
||||||
for(int i=0; i<=qty; i++) childpos.push_back(i * t);
|
for(int i=0; i<=qty; i++) childpos.push_back(i * t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void load_ruleset_new(string fname) {
|
||||||
|
|
||||||
|
shstream ins(decompress_string(read_file_as_string(fname)));
|
||||||
|
ins.read(ins.vernum);
|
||||||
|
mapstream::load_geometry(ins);
|
||||||
|
ins.read(fieldpattern::use_rule_fp);
|
||||||
|
ins.read(fieldpattern::use_quotient_fp);
|
||||||
|
ins.read(reg3::minimize_quotient_maps);
|
||||||
|
|
||||||
|
hread_fpattern(ins, fp);
|
||||||
|
|
||||||
|
hread(ins, root);
|
||||||
|
hread(ins, children);
|
||||||
|
hread(ins, other);
|
||||||
|
hread(ins, childpos);
|
||||||
|
}
|
||||||
|
|
||||||
/** \brief address = (fieldvalue, state) */
|
/** \brief address = (fieldvalue, state) */
|
||||||
typedef pair<int, int> address;
|
typedef pair<int, int> address;
|
||||||
|
|
||||||
@ -1995,7 +2002,6 @@ EX namespace reg3 {
|
|||||||
hrmap_h3_rule() {
|
hrmap_h3_rule() {
|
||||||
|
|
||||||
load_ruleset(get_rule_filename());
|
load_ruleset(get_rule_filename());
|
||||||
default_childpos(S7);
|
|
||||||
quotient_map = gen_quotient_map(is_minimized(), fp);
|
quotient_map = gen_quotient_map(is_minimized(), fp);
|
||||||
find_mappings();
|
find_mappings();
|
||||||
|
|
||||||
@ -2157,6 +2163,144 @@ EX namespace reg3 {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int lev;
|
||||||
|
|
||||||
|
struct hrmap_h3_subrule : hrmap, ruleset {
|
||||||
|
|
||||||
|
heptagon *origin;
|
||||||
|
hrmap_quotient3 *quotient_map;
|
||||||
|
hrmap_quotient3 *qmap() { return quotient_map; }
|
||||||
|
|
||||||
|
int connection(int fv, int d) override {
|
||||||
|
return quotient_map->local_id[quotient_map->acells[fv]->move(d)].first;
|
||||||
|
}
|
||||||
|
|
||||||
|
hrmap_h3_subrule() {
|
||||||
|
|
||||||
|
println(hlog, "loading a subrule ruleset");
|
||||||
|
|
||||||
|
load_ruleset_new(get_rule_filename());
|
||||||
|
quotient_map = gen_quotient_map(is_minimized(), fp);
|
||||||
|
int t = quotient_map->acells[0]->type;
|
||||||
|
find_mappings();
|
||||||
|
|
||||||
|
origin = init_heptagon(t);
|
||||||
|
heptagon& h = *origin;
|
||||||
|
h.s = hsOrigin;
|
||||||
|
h.fieldval = 0;
|
||||||
|
h.fiftyval = root[0];
|
||||||
|
h.c7 = newCell(t, origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
heptagon *getOrigin() override {
|
||||||
|
return origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
heptagon *create_step(heptagon *parent, int d) override {
|
||||||
|
dynamicval<int> rl(lev, lev+1);
|
||||||
|
if(lev > 10) println(hlog, "create_step called for ", tie(parent, d), " in distance ", parent->distance);
|
||||||
|
indenter ind(lev > 10 ? 2 : 0);
|
||||||
|
int id = parent->fiftyval;
|
||||||
|
if(id < 0) id += (1<<16);
|
||||||
|
if(lev > 30) throw hr_exception("create_step deep recursion");
|
||||||
|
|
||||||
|
int qid = parent->fieldval;
|
||||||
|
|
||||||
|
int d2 = quotient_map->acells[qid]->c.spin(d);
|
||||||
|
int qid2 = quotient_map->local_id[quotient_map->acells[qid]->move(d)].first;
|
||||||
|
|
||||||
|
if(lev > 10) println(hlog, tie(id, qid, d2, qid2));
|
||||||
|
|
||||||
|
heptagon *res = nullptr;
|
||||||
|
|
||||||
|
int id1 = children[childpos[id]+d];
|
||||||
|
int pos = otherpos[childpos[id]+d];
|
||||||
|
if(id1 < -1) id1 += (1<<16);
|
||||||
|
|
||||||
|
if(id1 != -1) {
|
||||||
|
int t = childpos[id1+1] - childpos[id1];
|
||||||
|
res = init_heptagon(t);
|
||||||
|
res->c7 = newCell(t, res);
|
||||||
|
res->fieldval = qid2;
|
||||||
|
res->distance = parent->distance + 1;
|
||||||
|
res->fiftyval = id1;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(other[pos] == ('A' + d) && other[pos+1] == ',') {
|
||||||
|
vector<int> possible;
|
||||||
|
for(auto s: nonlooping_earlier_states[address{qid, id}]) possible.push_back(s.second);
|
||||||
|
println(hlog, "possible size = ", isize(possible));
|
||||||
|
if(possible.empty()) throw hr_exception("impossible");
|
||||||
|
id1 = hrand_elt(possible, 0);
|
||||||
|
|
||||||
|
int t = childpos[id1+1] - childpos[id1];
|
||||||
|
res = init_heptagon(t);
|
||||||
|
res->alt = parent->alt;
|
||||||
|
res->fieldval = qid2;
|
||||||
|
res->distance = parent->distance - 1;
|
||||||
|
println(hlog, tie(qid, id), " => ", tie(qid2, id1));
|
||||||
|
res->fiftyval = id1;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
if(lev > 10) println(hlog, "path = ", other.substr(pos, 20));
|
||||||
|
heptagon *at = parent;
|
||||||
|
while(other[pos] != ',') {
|
||||||
|
int dir = (other[pos++] & 31) - 1;
|
||||||
|
at = at->cmove(dir);
|
||||||
|
if(lev > 10) println(hlog, "currently at ", at, " in distance ", at->distance);
|
||||||
|
}
|
||||||
|
res = at;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!res) throw hr_exception("res missing");
|
||||||
|
|
||||||
|
if(res->move(d2)) println(hlog, "res conflict: ", heptspin(res,d2), " already connected to ", heptspin(res,d2)+wstep, " and should be connected to ", heptspin(parent,d));
|
||||||
|
|
||||||
|
res->c.connect(d2, parent, d, false);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
~hrmap_h3_subrule() {
|
||||||
|
if(quotient_map) delete quotient_map;
|
||||||
|
clearfrom(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
transmatrix adj(heptagon *h, int d) override {
|
||||||
|
return quotient_map->adj(quotient_map->acells[h->fieldval], d);
|
||||||
|
}
|
||||||
|
|
||||||
|
transmatrix relative_matrixh(heptagon *h2, heptagon *h1, const hyperpoint& hint) override {
|
||||||
|
return relative_matrix_recursive(h2, h1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int shvid(cell *c) override {
|
||||||
|
return quotient_map->shvid(quotient_map->acells[c->master->fieldval]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int wall_offset(cell *c) override {
|
||||||
|
return quotient_map->wall_offset(quotient_map->acells[c->master->fieldval]);
|
||||||
|
}
|
||||||
|
|
||||||
|
subcellshape& get_cellshape(cell *c) override {
|
||||||
|
return quotient_map->get_cellshape(quotient_map->acells[c->master->fieldval]);
|
||||||
|
}
|
||||||
|
|
||||||
|
transmatrix ray_iadj(cell *c, int i) override {
|
||||||
|
return quotient_map->ray_iadj(quotient_map->acells[c->master->fieldval], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
cellwalker strafe(cellwalker cw, int j) override {
|
||||||
|
int aid = cw.at->master->fieldval;
|
||||||
|
auto ress = quotient_map->strafe(cellwalker(quotient_map->acells[aid], cw.spin), j);
|
||||||
|
return cellwalker(cw.at->cmove(j), ress.spin);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool link_alt(heptagon *h, heptagon *alt, hstate firststate, int dir) override {
|
||||||
|
return ruleset_link_alt(h, alt, firststate, dir);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct hrmap_h3_rule_alt : hrmap {
|
struct hrmap_h3_rule_alt : hrmap {
|
||||||
|
|
||||||
heptagon *origin;
|
heptagon *origin;
|
||||||
@ -2202,12 +2346,22 @@ EX bool in_rule() {
|
|||||||
return reg3_rule_available && get_rule_filename() != "";
|
return reg3_rule_available && get_rule_filename() != "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ruleset& get_ruleset() {
|
||||||
|
if(subrule) return *((hrmap_h3_subrule*)currentmap);
|
||||||
|
if(in_rule()) return *((hrmap_h3_rule*)currentmap);
|
||||||
|
throw hr_exception("get_ruleset called but not in rule");
|
||||||
|
}
|
||||||
|
|
||||||
EX int rule_get_root(int i) {
|
EX int rule_get_root(int i) {
|
||||||
return ((hrmap_h3_rule*)currentmap)->root[i];
|
return get_ruleset().root[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
EX const vector<short>& rule_get_children() {
|
EX const vector<short>& rule_get_children() {
|
||||||
return ((hrmap_h3_rule*)currentmap)->children;
|
return get_ruleset().children;
|
||||||
|
}
|
||||||
|
|
||||||
|
EX const vector<int>& rule_get_childpos() {
|
||||||
|
return get_ruleset().childpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
EX hrmap* new_map() {
|
EX hrmap* new_map() {
|
||||||
@ -2215,6 +2369,7 @@ EX hrmap* new_map() {
|
|||||||
if(geometry == gSeifertWeber) return new seifert_weber::hrmap_singlecell(108*degree);
|
if(geometry == gSeifertWeber) return new seifert_weber::hrmap_singlecell(108*degree);
|
||||||
if(geometry == gHomologySphere) return new seifert_weber::hrmap_singlecell(36*degree);
|
if(geometry == gHomologySphere) return new seifert_weber::hrmap_singlecell(36*degree);
|
||||||
if(quotient && !sphere) return new hrmap_field3(&currfp);
|
if(quotient && !sphere) return new hrmap_field3(&currfp);
|
||||||
|
if(subrule) return new hrmap_h3_subrule;
|
||||||
if(in_rule()) return new hrmap_h3_rule;
|
if(in_rule()) return new hrmap_h3_rule;
|
||||||
if(sphere) return new hrmap_sphere3;
|
if(sphere) return new hrmap_sphere3;
|
||||||
return new hrmap_h3;
|
return new hrmap_h3;
|
||||||
@ -2334,6 +2489,8 @@ EX bool pseudohept(cell *c) {
|
|||||||
return c->master->fieldval % 31 == 0;
|
return c->master->fieldval % 31 == 0;
|
||||||
return c->master->fieldval == 0;
|
return c->master->fieldval == 0;
|
||||||
}
|
}
|
||||||
|
auto ms = dynamic_cast<hrmap_h3_subrule*> (currentmap);
|
||||||
|
if(ms) return c->master->fieldval == 0;
|
||||||
if(m && hyperbolic) {
|
if(m && hyperbolic) {
|
||||||
heptagon *h = m->reg_gmatrix[c->master].first;
|
heptagon *h = m->reg_gmatrix[c->master].first;
|
||||||
return (h->zebraval == 1) && (h->distance & 1);
|
return (h->zebraval == 1) && (h->distance & 1);
|
||||||
|
22
rulegen3.cpp
22
rulegen3.cpp
@ -169,7 +169,10 @@ void genhoneycomb(string fname) {
|
|||||||
}
|
}
|
||||||
println(hlog);
|
println(hlog);
|
||||||
|
|
||||||
|
vector<int> childpos;
|
||||||
|
|
||||||
for(int i=0; i<numclass; i++) {
|
for(int i=0; i<numclass; i++) {
|
||||||
|
childpos.push_back(isize(data));
|
||||||
auto& ts = treestates[representative[i]];
|
auto& ts = treestates[representative[i]];
|
||||||
for(int j=0; j<isize(ts.rules); j++) {
|
for(int j=0; j<isize(ts.rules); j++) {
|
||||||
int j1 = gmod(j - ts.giver.spin, isize(ts.rules));
|
int j1 = gmod(j - ts.giver.spin, isize(ts.rules));
|
||||||
@ -194,9 +197,16 @@ void genhoneycomb(string fname) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
childpos.push_back(isize(data));
|
||||||
|
|
||||||
shstream ss;
|
shstream ss;
|
||||||
|
|
||||||
|
ss.write(ss.get_vernum());
|
||||||
|
mapstream::save_geometry(ss);
|
||||||
|
ss.write(fieldpattern::use_rule_fp);
|
||||||
|
ss.write(fieldpattern::use_quotient_fp);
|
||||||
|
ss.write(reg3::minimize_quotient_maps);
|
||||||
|
|
||||||
auto& fp = currfp;
|
auto& fp = currfp;
|
||||||
hwrite_fpattern(ss, fp);
|
hwrite_fpattern(ss, fp);
|
||||||
|
|
||||||
@ -209,6 +219,8 @@ void genhoneycomb(string fname) {
|
|||||||
hwrite(ss, data);
|
hwrite(ss, data);
|
||||||
println(hlog, "side_data = ", side_data);
|
println(hlog, "side_data = ", side_data);
|
||||||
hwrite(ss, side_data);
|
hwrite(ss, side_data);
|
||||||
|
println(hlog, "childpos = ", childpos);
|
||||||
|
hwrite(ss, childpos);
|
||||||
|
|
||||||
println(hlog, "compress_string");
|
println(hlog, "compress_string");
|
||||||
string s = compress_string(ss.s);
|
string s = compress_string(ss.s);
|
||||||
@ -226,7 +238,7 @@ int readRuleArgs3() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if(argis("-urq")) {
|
else if(argis("-urq")) {
|
||||||
// -urq 7 to generate honeycombs
|
// -urq 7 to prepare honeycomb generation
|
||||||
stop_game();
|
stop_game();
|
||||||
shift(); int i = argi();
|
shift(); int i = argi();
|
||||||
reg3::reg3_rule_available = (i & 8) ? 0 : 1;
|
reg3::reg3_rule_available = (i & 8) ? 0 : 1;
|
||||||
@ -235,9 +247,13 @@ int readRuleArgs3() {
|
|||||||
reg3::minimize_quotient_maps = (i & 4) ? 1 : 0;
|
reg3::minimize_quotient_maps = (i & 4) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(argis("-subrule")) {
|
else if(argis("-subrule")) {
|
||||||
|
stop_game();
|
||||||
shift(); reg3::other_rule = args();
|
shift(); reg3::other_rule = args();
|
||||||
shift(); reg3::subrule = argi();
|
shstream ins(decompress_string(read_file_as_string(args())));
|
||||||
|
ins.read(ins.vernum);
|
||||||
|
mapstream::load_geometry(ins);
|
||||||
|
reg3::subrule = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
else return 1;
|
else return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user