mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-01-11 09:50:34 +00:00
irregular grids
This commit is contained in:
parent
4320119d02
commit
c8c1e3a346
@ -105,8 +105,10 @@ bool grailWasFound(cell *c) {
|
||||
|
||||
void generateAlts(heptagon *h, int levs, bool link_cdata) {
|
||||
if(!h->alt) return;
|
||||
preventbarriers(h->c7);
|
||||
for(int i=0; i<S7; i++) preventbarriers(h->c7->mov[i]);
|
||||
if(!irr::on) {
|
||||
preventbarriers(h->c7);
|
||||
for(int i=0; i<S7; i++) preventbarriers(h->c7->mov[i]);
|
||||
}
|
||||
if(gp::on)
|
||||
for(int i=0; i<S7; i++) preventbarriers(createStep(h, i)->c7);
|
||||
for(int i=0; i<S7; i++)
|
||||
@ -973,7 +975,7 @@ int wallchance(cell *c, bool deepOcean) {
|
||||
bool horo_ok() {
|
||||
// do the horocycles work in the current geometry?
|
||||
// (they work in ALL hyperbolic geometries currently!)
|
||||
return hyperbolic;
|
||||
return hyperbolic && !irr::on;
|
||||
}
|
||||
|
||||
bool gp_wall_test() {
|
||||
|
@ -6,7 +6,7 @@ namespace hr {
|
||||
double randd() { return (rand() + .5) / (RAND_MAX + 1.); }
|
||||
|
||||
double cellgfxdist(cell *c, int i) {
|
||||
if(gp::on) return hdist0(tC0(shmup::calc_relative_matrix(c->mov[i], c, i)));
|
||||
if(gp::on || irr::on) return hdist0(tC0(shmup::calc_relative_matrix(c->mov[i], c, i)));
|
||||
return nonbitrunc ? tessf * gp::scale : (c->type == 6 && (i&1)) ? hexhexdist : crossf;
|
||||
}
|
||||
|
||||
|
42
cell.cpp
42
cell.cpp
@ -73,7 +73,10 @@ hrmap_hyperbolic::hrmap_hyperbolic() {
|
||||
h.alt = NULL;
|
||||
h.distance = 0;
|
||||
isnonbitrunc = nonbitrunc;
|
||||
h.c7 = newCell(S7, origin);
|
||||
if(irr::on)
|
||||
irr::link_start(origin);
|
||||
else
|
||||
h.c7 = newCell(S7, origin);
|
||||
}
|
||||
|
||||
// --- spherical geometry ---
|
||||
@ -107,7 +110,7 @@ struct hrmap_spherical : hrmap {
|
||||
h.spintable = 0;
|
||||
h.fieldval = i;
|
||||
for(int i=0; i<S7; i++) h.move[i] = NULL;
|
||||
h.c7 = newCell(S7, &h);
|
||||
if(!irr::on) h.c7 = newCell(S7, &h);
|
||||
}
|
||||
if(S7 == 5)
|
||||
siblings = {1, 0, 10, 4, 3, 8, 9, 11, 5, 6, 2, 7};
|
||||
@ -174,6 +177,13 @@ struct hrmap_spherical : hrmap {
|
||||
dodecahedron[i+1]->setspin(2, 3-i);
|
||||
}
|
||||
}
|
||||
|
||||
if(irr::on) {
|
||||
irr::link_start(dodecahedron[0]);
|
||||
for(int i=0; i<spherecells(); i++)
|
||||
for(int j=0; j<S7; j++)
|
||||
irr::may_link_next(dodecahedron[i], j);
|
||||
}
|
||||
}
|
||||
|
||||
heptagon *getOrigin() { return dodecahedron[0]; }
|
||||
@ -717,7 +727,7 @@ struct hrmap_quotient : hrmap {
|
||||
h->fieldval = S7*i;
|
||||
h->rval0 = h->rval1 = 0; h->cdata = NULL;
|
||||
h->distance = 0;
|
||||
h->c7 = newCell(S7, h);
|
||||
if(!irr::on) h->c7 = newCell(S7, h);
|
||||
}
|
||||
for(int j=0; j<S7; j++) {
|
||||
int co = connections[i*S7+j];
|
||||
@ -738,6 +748,13 @@ struct hrmap_quotient : hrmap {
|
||||
allh[i]->move[j]->alt = createStep(allh[i]->alt, j); */
|
||||
}
|
||||
|
||||
if(irr::on) {
|
||||
irr::link_start(allh[0]);
|
||||
for(int i=0; i<TOT; i++)
|
||||
for(int j=0; j<S7; j++)
|
||||
irr::may_link_next(allh[i], j);
|
||||
}
|
||||
|
||||
celllister cl(gamestart(), 100, 100000000, NULL);
|
||||
celllist = cl.lst;
|
||||
}
|
||||
@ -827,6 +844,9 @@ cell *createMov(cell *c, int d) {
|
||||
}
|
||||
|
||||
if(c->mov[d]) return c->mov[d];
|
||||
else if(irr::on) {
|
||||
irr::link_cell(c, d);
|
||||
}
|
||||
else if(nonbitrunc && gp::on) {
|
||||
gp::extend_map(c, d);
|
||||
if(!c->mov[d]) {
|
||||
@ -951,7 +971,8 @@ void clearHexes(heptagon *at) {
|
||||
delete at->cdata;
|
||||
at->cdata = NULL;
|
||||
}
|
||||
if(at->c7) subcell(at->c7, clearcell);
|
||||
if(irr::on) irr::clear_links(at);
|
||||
else if(at->c7) subcell(at->c7, clearcell);
|
||||
}
|
||||
|
||||
void unlink_cdata(heptagon *h) {
|
||||
@ -1017,7 +1038,7 @@ void verifycell(cell *c) {
|
||||
}
|
||||
|
||||
void verifycells(heptagon *at) {
|
||||
if(gp::on) return;
|
||||
if(gp::on || irr::on) return;
|
||||
for(int i=0; i<S7; i++) if(at->move[i] && at->move[i]->move[at->spin(i)] && at->move[i]->move[at->spin(i)] != at) {
|
||||
printf("hexmix error %p [%d s=%d] %p %p\n", at, i, at->spin(i), at->move[i], at->move[i]->move[at->spin(i)]);
|
||||
}
|
||||
@ -1066,6 +1087,7 @@ int celldist(cell *c) {
|
||||
if(sphere) return celldistance(c, currentmap->gamestart());
|
||||
if(ctof(c)) return c->master->distance;
|
||||
if(gp::on) return gp::compute_dist(c, celldist);
|
||||
if(irr::on) return c->master->distance;
|
||||
int dx[MAX_S3];
|
||||
for(int u=0; u<S3; u++)
|
||||
dx[u] = createMov(c, u+u)->master->distance;
|
||||
@ -1400,7 +1422,7 @@ int getCdata(cell *c, int j) {
|
||||
int jj = 0;
|
||||
auto ar = gp::get_masters(c);
|
||||
for(int k=0; k<3; k++)
|
||||
jj += getHeptagonCdata(ar[k]->master)->val[j];
|
||||
jj += getHeptagonCdata(ar[k])->val[j];
|
||||
return jj;
|
||||
}
|
||||
}
|
||||
@ -1411,9 +1433,9 @@ int getBits(cell *c) {
|
||||
else if(c->type != 6) return getHeptagonCdata(c->master)->bits;
|
||||
else {
|
||||
auto ar = gp::get_masters(c);
|
||||
int b0 = getHeptagonCdata(ar[0]->master)->bits;
|
||||
int b1 = getHeptagonCdata(ar[1]->master)->bits;
|
||||
int b2 = getHeptagonCdata(ar[2]->master)->bits;
|
||||
int b0 = getHeptagonCdata(ar[0])->bits;
|
||||
int b1 = getHeptagonCdata(ar[1])->bits;
|
||||
int b2 = getHeptagonCdata(ar[2])->bits;
|
||||
return (b0 & b1) | (b1 & b2) | (b2 & b0);
|
||||
}
|
||||
}
|
||||
@ -1475,7 +1497,7 @@ int celldistance(cell *c1, cell *c2) {
|
||||
return 64;
|
||||
}
|
||||
|
||||
if(gp::on || euclid) {
|
||||
if(gp::on || euclid || irr::on) {
|
||||
|
||||
if(saved_distances.count(make_pair(c1,c2)))
|
||||
return saved_distances[make_pair(c1,c2)];
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "language.cpp"
|
||||
#include "cell.cpp"
|
||||
#include "goldberg.cpp"
|
||||
#include "irregular.cpp"
|
||||
#include "pattern2.cpp"
|
||||
#include "flags.cpp"
|
||||
#include "yendor.cpp"
|
||||
|
@ -3094,7 +3094,7 @@ namespace windmap {
|
||||
// cw.spin = 0;
|
||||
neighbors.emplace_back();
|
||||
auto &v = neighbors.back();
|
||||
if(gp::on)
|
||||
if(gp::on || irr::on)
|
||||
for(int l=0; l<S7; l++) {
|
||||
heptspin hs(cw.c->master, cw.spin);
|
||||
hs = hs + l + wstep;
|
||||
|
119
floorshapes.cpp
119
floorshapes.cpp
@ -218,9 +218,17 @@ void bshape_regular(floorshape &fsh, int id, int sides, int shift, ld size) {
|
||||
}
|
||||
}
|
||||
|
||||
namespace irr { void generate_floorshapes(); }
|
||||
|
||||
void generate_floorshapes() {
|
||||
|
||||
if(irr::on) {
|
||||
printf("generating irregular floorshapes...\n");
|
||||
irr::generate_floorshapes();
|
||||
printf("done\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(gp::on) {
|
||||
return;
|
||||
}
|
||||
@ -489,6 +497,103 @@ namespace gp {
|
||||
}
|
||||
}
|
||||
|
||||
namespace irr {
|
||||
|
||||
map<int, matrixlist> usedml;
|
||||
|
||||
void generate_floorshapes() {
|
||||
|
||||
if(irr::cells.empty()) return;
|
||||
|
||||
for(auto pfsh: all_escher_floorshapes) {
|
||||
auto& fsh = *pfsh;
|
||||
generate_matrices_scale(1, fsh.noftype);
|
||||
auto& m = hept_matrices;
|
||||
|
||||
/* if(siid == 0)
|
||||
for(auto& ma: m.v) ma.first = ma.first * pispin; */
|
||||
|
||||
fsh.b.resize(irr::sc);
|
||||
|
||||
for(int id=0; id<irr::sc; id++) {
|
||||
auto& vs = irr::cells[id];
|
||||
|
||||
int cor = isize(vs.vertices);
|
||||
m.n.sym = cor;
|
||||
|
||||
int i = 0;
|
||||
|
||||
for(int d=0; d<m.o.sym; d++) {
|
||||
hyperpoint center = hpxy(0,0);
|
||||
|
||||
for(int c=0; c<cor; c++) {
|
||||
hyperpoint nlcorner = vs.vertices[(d+c+1) % cor];
|
||||
hyperpoint nrcorner = vs.vertices[(d+c+2) % cor];
|
||||
|
||||
hyperpoint nfar = vs.jpoints[vs.neid[(d+c+1) % cor]];
|
||||
hyperpoint nlfar = nfar;
|
||||
hyperpoint nrfar = nfar;
|
||||
m.v[i].second[c] = build_matrix(center, nlcorner, nrcorner);
|
||||
m.v[i+1].second[c] = build_matrix(nfar, nlcorner, nrcorner);
|
||||
m.v[i+2].second[c] = build_matrix(nfar, nlcorner, nlfar);
|
||||
m.v[i+3].second[c] = build_matrix(nfar, nrcorner, nrfar);
|
||||
}
|
||||
|
||||
i += 4;
|
||||
}
|
||||
|
||||
usedml[id] = m;
|
||||
|
||||
m.n.sym = cor;
|
||||
bshape2(fsh.b[id], fsh.prio, fsh.shapeid2 ? fsh.shapeid2 : fsh.shapeid1, m);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto pfsh: all_plain_floorshapes) {
|
||||
auto& fsh = *pfsh;
|
||||
|
||||
ld sca = fsh.rad0 / shFullFloor.rad0;
|
||||
|
||||
fsh.b.resize(irr::sc);
|
||||
fsh.shadow.resize(irr::sc);
|
||||
|
||||
for(int i=0; i<irr::sc; i++) {
|
||||
auto& vs = irr::cells[i];
|
||||
vector<hyperpoint> cornerlist;
|
||||
|
||||
int cor = isize(vs.vertices);
|
||||
for(int j=0; j<cor; j++)
|
||||
cornerlist.push_back(rspintox(vs.vertices[j]) * xpush(hdist0(vs.vertices[j]) * sca) * C0);
|
||||
|
||||
bshape(fsh.b[i], fsh.prio);
|
||||
for(int i=0; i<=cor; i++) hpcpush(cornerlist[i%cor]);
|
||||
|
||||
bshape(fsh.shadow[i], fsh.prio);
|
||||
for(int i=0; i<=cor; i++)
|
||||
hpcpush(mid_at(hpxy(0,0), cornerlist[i%cor], SHADMUL));
|
||||
|
||||
cell fc;
|
||||
fc.type = cor;
|
||||
irr::cellindex[&fc] = i;
|
||||
|
||||
// printf("at = %d,%d cor = %d sca = %lf\n", li.relative.first, li.relative.second, cor, sca);
|
||||
|
||||
for(int k=0; k<SIDEPARS; k++)
|
||||
for(int c=0; c<cor; c++) {
|
||||
fsh.gpside[k][c].resize(irr::sc);
|
||||
bshape(fsh.gpside[k][c][i], fsh.prio);
|
||||
hpcpush(iddspin(&fc, c) * cornerlist[c]);
|
||||
hpcpush(iddspin(&fc, c) * cornerlist[(c+1)%cor]);
|
||||
chasmifyPoly(dlow_table[k], dhi_table[k], k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finishshape(); last = NULL;
|
||||
extra_vertices();
|
||||
}
|
||||
}
|
||||
|
||||
qfloorinfo qfi;
|
||||
qfloorinfo qfi_dc;
|
||||
|
||||
@ -521,6 +626,13 @@ void draw_shapevec(cell *c, const transmatrix& V, const vector<hpcshape> &shv, i
|
||||
int id = gp::get_plainshape_id(c);
|
||||
queuepolyat(V, shv[id], col, prio);
|
||||
}
|
||||
else if(irr::on) {
|
||||
int id = irr::cellindex[c];
|
||||
if(id < 0 || id >= isize(shv)) {
|
||||
return;
|
||||
}
|
||||
queuepolyat(V, shv[id], col, prio);
|
||||
}
|
||||
else if((euclid || gp::on) && ishex1(c))
|
||||
queuepolyat(V * pispin, shv[0], col, prio);
|
||||
else if(!(S7&1) && nonbitrunc) {
|
||||
@ -566,8 +678,13 @@ void viewmat() {
|
||||
gp::just_matrices = false;
|
||||
}
|
||||
// if(gp::on && !gp::usedml.count(cwt.c)) return;
|
||||
for(auto& v: (pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) {
|
||||
// for(auto& v: (pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) {
|
||||
// for(auto& v: (gp::on ? gp::usedml[cwt.c] : pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) {
|
||||
// hyperpoint h1 = gmatrix[cwt.c] * v.second[0] * hpxyz(1,0,0);
|
||||
id = irr::cellindex[cwt.c];
|
||||
for(auto& v: irr::usedml[id].v) {
|
||||
// for(auto& v: (gp::on ? gp::usedml[cwt.c] : pseudohept(cwt.c) ? hept_matrices : hex_matrices).v) {
|
||||
|
||||
hyperpoint h1 = gmatrix[cwt.c] * v.second[0] * hpxyz(1,0,0);
|
||||
hyperpoint h2 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,1,0);
|
||||
hyperpoint h3 = gmatrix[cwt.c] * v.second[0] * hpxyz(0,0,1);
|
||||
|
@ -170,6 +170,7 @@ void precalc() {
|
||||
base_distlimit = ginf[geometry].distlimit[nonbitrunc];
|
||||
|
||||
gp::compute_geometry();
|
||||
irr::compute_geometry();
|
||||
}
|
||||
|
||||
transmatrix ddi(ld dir, ld dist) {
|
||||
|
10
goldberg.cpp
10
goldberg.cpp
@ -857,16 +857,18 @@ namespace hr { namespace gp {
|
||||
return dmain + length(centerloc-at) - length(centerloc);
|
||||
}
|
||||
|
||||
array<cell*, 3> get_masters(cell *c) {
|
||||
array<heptagon*, 3> get_masters(cell *c) {
|
||||
if(gp::on) {
|
||||
auto li = get_local_info(c);
|
||||
be_in_triangle(li);
|
||||
auto cm = c->master;
|
||||
int i = li.last_dir;
|
||||
return make_array(cm->c7, createStep(cm, i)->c7, createStep(cm, fix7(i+1))->c7);
|
||||
return make_array(cm, createStep(cm, i), createStep(cm, fix7(i+1)));
|
||||
}
|
||||
else
|
||||
return make_array(c->mov[0], c->mov[2], c->mov[4]);
|
||||
else if(irr::on)
|
||||
return irr::get_masters(c);
|
||||
else
|
||||
return make_array(c->mov[0]->master, c->mov[2]->master, c->mov[4]->master);
|
||||
}
|
||||
|
||||
int compute_dist(cell *c, int master_function(cell*)) {
|
||||
|
28
graph.cpp
28
graph.cpp
@ -158,6 +158,7 @@ void drawSpeed(const transmatrix& V) {
|
||||
}
|
||||
|
||||
int ctof(cell *c) {
|
||||
if(irr::on) return irr::ctof(c);
|
||||
if(nonbitrunc && !gp::on) return 1;
|
||||
// if(euclid) return 0;
|
||||
return ishept(c) ? 1 : 0;
|
||||
@ -232,7 +233,14 @@ void drawLightning(const transmatrix& V) {
|
||||
}
|
||||
|
||||
int displaydir(cell *c, int d) {
|
||||
if(euclid)
|
||||
if(irr::on) {
|
||||
auto id = irr::cellindex[c];
|
||||
auto& vs = irr::cells[id];
|
||||
if(d < 0 || d >= c->type) return 0;
|
||||
auto& p = vs.jpoints[vs.neid[d]];
|
||||
return -int(atan2(p[1], p[0]) * S84 / 2 / M_PI + MODFIXER + .5);
|
||||
}
|
||||
else if(euclid)
|
||||
return - d * S84 / c->type;
|
||||
else
|
||||
return S42 - d * S84 / c->type;
|
||||
@ -2092,7 +2100,7 @@ bool drawMonster(const transmatrix& Vparam, int ct, cell *c, int col) {
|
||||
Vb = Vb * pispin;
|
||||
Vb = Vb * xpush(tentacle_length - cellgfxdist(c, c->mondir));
|
||||
}
|
||||
else if(gp::on) {
|
||||
else if(gp::on || irr::on) {
|
||||
transmatrix T = shmup::calc_relative_matrix(c->mov[c->mondir], c, c->mondir);
|
||||
Vb = Vb * T * rspintox(tC0(inverse(T))) * xpush(tentacle_length);
|
||||
}
|
||||
@ -3076,6 +3084,7 @@ bool noAdjacentChasms(cell *c) {
|
||||
|
||||
// does the current geometry allow nice duals
|
||||
bool has_nice_dual() {
|
||||
if(irr::on) return false;
|
||||
if(!nonbitrunc) return true;
|
||||
if((S7 & 1) == 0) return true;
|
||||
if(!gp::on) return false;
|
||||
@ -3171,8 +3180,8 @@ bool placeSidewall(cell *c, int i, int sidepar, const transmatrix& V, int col) {
|
||||
else prio = PPR_REDWALL-2+4*(sidepar-SIDE_SLEV);
|
||||
|
||||
transmatrix V2 = V * ddspin(c, i);
|
||||
|
||||
if(gp::on) {
|
||||
|
||||
if(gp::on || irr::on) {
|
||||
draw_shapevec(c, V2, qfi.fshape->gpside[sidepar][i], col, prio);
|
||||
return false;
|
||||
}
|
||||
@ -4024,7 +4033,7 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
|
||||
case laSwitch:
|
||||
set_floor(shSwitchFloor);
|
||||
if(ctof(c)) for(int i=0; i<c->type; i++)
|
||||
if(ctof(c) && !gp::on && !irr::on) for(int i=0; i<c->type; i++)
|
||||
queuepoly(Vf * ddspin(c, i, S6) * xpush(rhexf), shSwitchDisk, darkena(minf[active_switch()].color, fd, 0xFF));
|
||||
break;
|
||||
|
||||
@ -4709,7 +4718,14 @@ void drawcell(cell *c, transmatrix V, int spinv, bool mirrored) {
|
||||
|
||||
int prec = sphere ? 3 : 1;
|
||||
|
||||
if(gp::on) {
|
||||
if(irr::on) {
|
||||
int id = irr::cellindex[c];
|
||||
auto &vs = irr::cells[id];
|
||||
for(int t=0; t<c->type; t++)
|
||||
if(c->mov[t] && c->mov[t] < c)
|
||||
queueline(V * vs.vertices[t], V * vs.vertices[(1+t)%c->type], gridcolor(c, c->mov[t]), prec);
|
||||
}
|
||||
else if(gp::on) {
|
||||
vid.linewidth *= gp::scale * 2;
|
||||
if(isWarped(c) && has_nice_dual()) {
|
||||
if(pseudohept(c)) for(int t=0; t<c->type; t++)
|
||||
|
@ -75,7 +75,10 @@ heptagon *buildHeptagon(heptagon *parent, int d, hstate s, int pard = 0, int fix
|
||||
h->move[pard] = parent; tsetspin(h->spintable, pard, d);
|
||||
parent->move[d] = h; tsetspin(parent->spintable, d, pard);
|
||||
if(parent->c7) {
|
||||
h->c7 = newCell(S7, h);
|
||||
if(irr::on)
|
||||
irr::link_next(parent, d);
|
||||
else
|
||||
h->c7 = newCell(S7, h);
|
||||
h->rval0 = h->rval1 = 0; h->cdata = NULL;
|
||||
h->emeraldval = emerald_heptagon(parent->emeraldval, d);
|
||||
h->zebraval = zebra_heptagon(parent->zebraval, d);
|
||||
|
18
hyper.h
18
hyper.h
@ -78,7 +78,7 @@ void addMessage(string s, char spamtype = 0);
|
||||
#define S3 ginf[geometry].vertex
|
||||
#define hyperbolic_37 (S7 == 7 && S3 == 3)
|
||||
#define hyperbolic_not37 ((S7 > 7 || S3 > 3) && hyperbolic)
|
||||
#define weirdhyperbolic ((S7 > 7 || S3 > 3 || gp::on) && hyperbolic)
|
||||
#define weirdhyperbolic ((S7 > 7 || S3 > 3 || gp::on || irr::on) && hyperbolic)
|
||||
#define stdhyperbolic (S7 == 7 && S3 == 3 && !gp::on)
|
||||
|
||||
#define cgclass (ginf[geometry].cclass)
|
||||
@ -2549,6 +2549,20 @@ struct hrmap_hyperbolic : hrmap {
|
||||
void verify() { verifycells(origin); }
|
||||
};
|
||||
|
||||
namespace quotientspace { hrmap *new_map(); }
|
||||
namespace irr {
|
||||
extern bool on;
|
||||
void link_to_base(heptagon *h, heptspin base);
|
||||
void link_start(heptagon *h);
|
||||
void link_next(heptagon *h, int d);
|
||||
void may_link_next(heptagon *h, int d);
|
||||
void link_cell(cell *c, int d);
|
||||
void clear_links(heptagon *h);
|
||||
bool pseudohept(cell*);
|
||||
array<heptagon*, 3> get_masters(cell *c);
|
||||
bool ctof(cell* c);
|
||||
}
|
||||
|
||||
extern hrmap *currentmap;
|
||||
extern vector<hrmap*> allmaps;
|
||||
|
||||
@ -3149,7 +3163,7 @@ namespace gp {
|
||||
|
||||
int solve_triangle(int dmain, int d0, int d1, loc at);
|
||||
|
||||
array<cell*, 3> get_masters(cell *c);
|
||||
array<heptagon*, 3> get_masters(cell *c);
|
||||
}
|
||||
|
||||
int get_sightrange();
|
||||
|
16
hypgraph.cpp
16
hypgraph.cpp
@ -486,6 +486,8 @@ ld master_to_c7_angle() {
|
||||
}
|
||||
|
||||
transmatrix actualV(const heptspin& hs, const transmatrix& V) {
|
||||
if(irr::on)
|
||||
return V * spin(M_PI + 2 * M_PI / S7 * (hs.spin + irr::periodmap[hs.h].base.spin));
|
||||
return (hs.spin || nonbitrunc) ? V * spin(hs.spin*2*M_PI/S7 + master_to_c7_angle()) : V;
|
||||
}
|
||||
|
||||
@ -564,10 +566,22 @@ void drawrec(const heptspin& hs, hstate s, const transmatrix& V) {
|
||||
transmatrix V10;
|
||||
const transmatrix& V1 = hs.mirrored ? (V10 = V * Mirror) : V;
|
||||
|
||||
bool draw = c->pathdist < PINFD;
|
||||
|
||||
if(gp::on) {
|
||||
gp::drawrec(c, actualV(hs, V1));
|
||||
}
|
||||
|
||||
else if(irr::on) {
|
||||
auto& hi = irr::periodmap[hs.h];
|
||||
transmatrix V0 = actualV(hs, V1);
|
||||
auto& vc = irr::cells_of_heptagon[hi.base.h];
|
||||
for(int i=0; i<isize(vc); i++)
|
||||
if(dodrawcell(hi.subcells[i]) && in_qrange(V0 * irr::cells[vc[i]].pusher))
|
||||
draw = true,
|
||||
drawcell(hi.subcells[i], V0 * irr::cells[vc[i]].pusher, 0, false);
|
||||
}
|
||||
|
||||
else {
|
||||
if(dodrawcell(c)) {
|
||||
transmatrix V2 = actualV(hs, V1);
|
||||
@ -585,7 +599,7 @@ void drawrec(const heptspin& hs, hstate s, const transmatrix& V) {
|
||||
}
|
||||
}
|
||||
|
||||
if(c->pathdist < PINFD && in_qrange(V)) for(int d=0; d<S7; d++) {
|
||||
if(draw && in_qrange(V)) for(int d=0; d<S7; d++) {
|
||||
hstate s2 = transition(s, d);
|
||||
if(s2 == hsError) continue;
|
||||
heptspin hs2 = hs + d + wstep;
|
||||
|
530
irregular.cpp
Normal file
530
irregular.cpp
Normal file
@ -0,0 +1,530 @@
|
||||
namespace hr { namespace irr {
|
||||
|
||||
bool on;
|
||||
|
||||
int sc = 100;
|
||||
|
||||
struct cellinfo {
|
||||
cell *owner;
|
||||
vector<hyperpoint> jpoints;
|
||||
hyperpoint p;
|
||||
transmatrix pusher, rpusher;
|
||||
vector<int> neid;
|
||||
vector<int> spin;
|
||||
vector<hyperpoint> vertices;
|
||||
int localindex;
|
||||
bool is_pseudohept;
|
||||
int patterndir;
|
||||
};
|
||||
|
||||
map<cell*, int> cellindex;
|
||||
|
||||
vector<cellinfo> cells;
|
||||
|
||||
ld inner(hyperpoint h1, hyperpoint h2) {
|
||||
return
|
||||
hyperbolic ? h1[2] * h2[2] - h1[0] * h2[0] - h1[1] * h2[1] :
|
||||
h1[2] * h2[2] + h1[0] * h2[0] + h1[1] * h2[1];
|
||||
}
|
||||
|
||||
hyperpoint circumscribe(hyperpoint a, hyperpoint b, hyperpoint c) {
|
||||
using namespace hyperpoint_vec;
|
||||
hyperpoint h = C0;
|
||||
|
||||
b = b - a;
|
||||
c = c - a;
|
||||
|
||||
if(inner(b,b) < 0) {
|
||||
b = b / sqrt(-inner(b, b));
|
||||
c = c + b * inner(c, b);
|
||||
h = h + b * inner(h, b);
|
||||
}
|
||||
else {
|
||||
b = b / sqrt(inner(b, b));
|
||||
c = c - b * inner(c, b);
|
||||
h = h - b * inner(h, b);
|
||||
}
|
||||
|
||||
if(inner(c,c) < 0) {
|
||||
c = c / sqrt(-inner(c, c));
|
||||
h = h + c * inner(h, c);
|
||||
}
|
||||
else {
|
||||
c = c / sqrt(inner(c, c));
|
||||
h = h - c * inner(h, c);
|
||||
}
|
||||
|
||||
if(h[2] < 0) h[0] = -h[0], h[1] = -h[1], h[2] = -h[2];
|
||||
|
||||
ld i = inner(h, h);
|
||||
if(i > 0) h /= sqrt(i);
|
||||
else h /= -sqrt(-i);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
bool clockwise(hyperpoint h1, hyperpoint h2) {
|
||||
return h1[0] * h2[1] > h1[1] * h2[0];
|
||||
}
|
||||
|
||||
map<heptagon*, vector<int> > cells_of_heptagon;
|
||||
|
||||
int runlevel;
|
||||
vector<ld> edgelens, distlens;
|
||||
|
||||
void make_cells_of_heptagon() {
|
||||
cells_of_heptagon.clear();
|
||||
for(int i=0; i<isize(cells); i++) {
|
||||
auto &p1 = cells[i];
|
||||
auto &vc = cells_of_heptagon[p1.owner->master];
|
||||
p1.localindex = isize(vc);
|
||||
vc.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
hrmap *base;
|
||||
|
||||
bool gridmaking;
|
||||
|
||||
bool step(int delta) {
|
||||
|
||||
if(!gridmaking) return false;
|
||||
timetowait = 0;
|
||||
|
||||
auto& all = base->allcells();
|
||||
|
||||
auto t = SDL_GetTicks();
|
||||
while(SDL_GetTicks() < t + 250)
|
||||
switch(runlevel) {
|
||||
case 0: {
|
||||
|
||||
cells.clear();
|
||||
cells_of_heptagon.clear();
|
||||
|
||||
if(sc <= isize(all) * 2) {
|
||||
for(auto h: all) {
|
||||
cellinfo s; s.patterndir = -1;
|
||||
s.owner = h, s.p = spin(hrand(1000)) * xpush(.01) * C0;
|
||||
cells.emplace_back(s);
|
||||
}
|
||||
}
|
||||
runlevel++;
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: {
|
||||
while(isize(cells) < sc) {
|
||||
if(SDL_GetTicks() > t + 250) { make_cells_of_heptagon(); return false; }
|
||||
cellinfo s; s.patterndir = -1;
|
||||
ld bestval = 0;
|
||||
for(int j=0; j<10; j++) {
|
||||
int k = hrand(isize(all));
|
||||
cell *c = all[k];
|
||||
hyperpoint h = randomPointIn(c->type);
|
||||
ld mindist = 1e6;
|
||||
for(auto p: cells) {
|
||||
ld val = hdist(h, shmup::calc_relative_matrix(p.owner, c, h) * p.p);
|
||||
if(val < mindist) mindist = val;
|
||||
}
|
||||
if(mindist > bestval) bestval = mindist, s.owner = c, s.p = h;
|
||||
}
|
||||
// printf("%lf %p %s\n", bestval, s.owner, display(s.p));
|
||||
cells.emplace_back(s);
|
||||
}
|
||||
make_cells_of_heptagon();
|
||||
runlevel++;
|
||||
break;
|
||||
}
|
||||
|
||||
case 2: {
|
||||
|
||||
sort(cells.begin(), cells.end(), [] (cellinfo &s1, cellinfo &s2) { return hdist0(s1.p) < hdist0(s2.p); });
|
||||
make_cells_of_heptagon();
|
||||
|
||||
edgelens.clear();
|
||||
distlens.clear();
|
||||
|
||||
int stats[16];
|
||||
for(int k=0; k<16; k++) stats[k] = 0;
|
||||
|
||||
for(int i=0; i<sc; i++) {
|
||||
auto &p1 = cells[i];
|
||||
p1.vertices.clear();
|
||||
p1.neid.clear();
|
||||
|
||||
p1.pusher = rgpushxto0(p1.p);
|
||||
p1.rpusher = gpushxto0(p1.p);
|
||||
|
||||
p1.jpoints.clear();
|
||||
|
||||
for(int j=0; j<sc; j++) {
|
||||
auto &p2 = cells[j];
|
||||
p1.jpoints.push_back(p1.rpusher * shmup::calc_relative_matrix(p2.owner, p1.owner, p1.p) * p2.p);
|
||||
}
|
||||
|
||||
int j = 0;
|
||||
if(j == i) j = 1;
|
||||
|
||||
for(int k=0; k<sc; k++) if(k != i) {
|
||||
if(hdist(p1.jpoints[k], C0) < hdist(p1.jpoints[j], C0))
|
||||
j = k;
|
||||
}
|
||||
|
||||
hyperpoint t = mid(p1.jpoints[j], C0);
|
||||
// p1.vertices.push_back(p1.pusher * t);
|
||||
int j0 = j;
|
||||
int oldj = j;
|
||||
do {
|
||||
int best_k = -1;
|
||||
hyperpoint best_h;
|
||||
for(int k=0; k<sc; k++) if(k != i && k != j && k != oldj) {
|
||||
hyperpoint h = circumscribe(C0, p1.jpoints[j], p1.jpoints[k]);
|
||||
if(h[2] < 0) continue;
|
||||
if(!clockwise(t, h)) continue;
|
||||
if(best_k == -1)
|
||||
best_k = k, best_h = h;
|
||||
else if(clockwise(h, best_h))
|
||||
best_k = k, best_h = h;
|
||||
}
|
||||
p1.vertices.push_back(best_h);
|
||||
p1.neid.push_back(best_k);
|
||||
distlens.push_back(hdist0(best_h));
|
||||
oldj = j, j = best_k, t = best_h;
|
||||
if(j == -1) break;
|
||||
if(isize(p1.vertices) == 15) break;
|
||||
}
|
||||
while(j != j0);
|
||||
|
||||
for(int j=0; j<isize(p1.vertices); j++)
|
||||
edgelens.push_back(hdist(p1.vertices[j], p1.vertices[(j+1) % isize(p1.vertices)]));
|
||||
|
||||
stats[isize(p1.vertices)]++;
|
||||
}
|
||||
|
||||
for(int a=0; a<16; a++) printf("%3d ", stats[a]);
|
||||
if(isize(edgelens)) {
|
||||
printf("|");
|
||||
printf("%4d ", isize(edgelens));
|
||||
sort(edgelens.begin(), edgelens.end());
|
||||
for(int a=0; a<=8; a++) printf("%6.3lf", double(edgelens[(a * isize(edgelens) - 1) / 8]));
|
||||
printf(" | ");
|
||||
sort(distlens.begin(), distlens.end());
|
||||
for(int a=0; a<=8; a++) printf("%5.2lf", double(distlens[(a * isize(edgelens) - 1) / 8]));
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
runlevel++;
|
||||
break;
|
||||
}
|
||||
|
||||
case 3: {
|
||||
|
||||
for(int i=0; i<isize(cells); i++) if(isize(cells[i].vertices) > 8 || isize(cells[i].vertices) < 3) {
|
||||
cells[i] = cells.back();
|
||||
i--; cells.pop_back();
|
||||
}
|
||||
if(isize(cells) < sc*3/4) runlevel = 0;
|
||||
else if(isize(cells) < sc) runlevel = 1;
|
||||
else runlevel++;
|
||||
break;
|
||||
}
|
||||
|
||||
case 4: {
|
||||
|
||||
ld minedge = edgelens[isize(edgelens) / 2] / 5;
|
||||
if(edgelens[0] < minedge) {
|
||||
printf("rearranging\n");
|
||||
for(int i=0; i<isize(cells); i++) {
|
||||
auto& p1 = cells[i];
|
||||
using namespace hyperpoint_vec;
|
||||
hyperpoint h = hpxyz(0, 0, 0);
|
||||
for(auto v: p1.vertices) h = h + v;
|
||||
|
||||
for(int j=0; j<isize(p1.vertices); j++)
|
||||
if(hdist(p1.vertices[j], p1.vertices[(j+1) % isize(p1.vertices)]) < minedge)
|
||||
h = h + p1.vertices[j] + p1.vertices[(j+1) % isize(p1.vertices)];
|
||||
cells[i].p = p1.pusher * normalize(h);
|
||||
}
|
||||
runlevel = 2;
|
||||
break;
|
||||
}
|
||||
runlevel++;
|
||||
break;
|
||||
}
|
||||
|
||||
case 5: {
|
||||
|
||||
int notfound = 0;
|
||||
|
||||
for(int i=0; i<sc; i++) {
|
||||
auto &p1 = cells[i];
|
||||
int N = isize(p1.vertices);
|
||||
p1.spin.resize(N);
|
||||
for(int j=0; j<N; j++) {
|
||||
auto i1 = p1.neid[j];
|
||||
bool found = false;
|
||||
for(int k=0; k < isize(cells[i1].vertices); k++)
|
||||
if(cells[i1].neid[k] == i)
|
||||
found = true, p1.spin[j] = k;
|
||||
if(!found) notfound++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("notfound = %d\n", notfound);
|
||||
if(notfound) { runlevel = 0; break; }
|
||||
|
||||
int heptas = 0;
|
||||
for(auto p: cells_of_heptagon) {
|
||||
printf("%p: %d\n", p.first, isize(p.second));
|
||||
heptas++;
|
||||
}
|
||||
|
||||
if(heptas != isize(all)) {
|
||||
printf("heptas = %d\n", heptas);
|
||||
runlevel = 0; break;
|
||||
}
|
||||
|
||||
for(int i=0; i<sc; i++) {
|
||||
auto &p1 = cells[i];
|
||||
for(int j: p1.neid) {
|
||||
auto &p2 = cells[j];
|
||||
bool ok = p1.owner == p2.owner || isNeighbor(p1.owner, p2.owner);
|
||||
if(!ok) { printf("far edge\n"); runlevel = 0; return false; }
|
||||
}
|
||||
}
|
||||
runlevel = 10;
|
||||
|
||||
for(auto& s: cells) s.is_pseudohept = false;
|
||||
for(auto& s: cells) {
|
||||
s.is_pseudohept = true;
|
||||
for(int i: s.neid) if(cells[i].is_pseudohept) s.is_pseudohept = false;
|
||||
}
|
||||
|
||||
for(auto& s: cells) {
|
||||
int d = -1;
|
||||
ld dist = hcrossf / 2;
|
||||
ld dists[8];
|
||||
for(int i=0; i<S7; i++) {
|
||||
dists[i] = hdist(s.p, spin(hexshift - i * ALPHA) * xpush(-hcrossf) * C0);
|
||||
// shmup::calc_relative_matrix(s.owner->mov[i], s.owner, s.p) * C0);
|
||||
// spin(2 * M_PI * i / S7) * xpush(hcrossf) * C0);
|
||||
if(dists[i] < dist)
|
||||
d = i, dist = dists[i];
|
||||
}
|
||||
if(d != -1 && dists[(d+1) % S7] > dists[(d+S7-1) % S7])
|
||||
d = (d + S7 - 1) % S7;
|
||||
s.patterndir = d;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 10:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void compute_geometry() {
|
||||
if(irr::on) {
|
||||
ld scal = sqrt(isize(cells_of_heptagon) * 1. / sc);
|
||||
crossf *= scal;
|
||||
hepvdist *= scal;
|
||||
rhexf *= scal;
|
||||
}
|
||||
}
|
||||
|
||||
bool draw_cell_schematics(cell *c, transmatrix V) {
|
||||
if(gridmaking) {
|
||||
heptagon *h = c->master;
|
||||
for(int i: cells_of_heptagon[h]) {
|
||||
auto& p = cells[i];
|
||||
if(p.owner == c) {
|
||||
queuestr(V * rgpushxto0(p.p), .1, its(i), isize(p.vertices) > 8 ? 0xFF0000 : 0xFFFFFF);
|
||||
int N = isize(p.vertices);
|
||||
for(int j=0; j<N; j++)
|
||||
queueline(V * p.pusher * p.vertices[j], V * p.pusher * p.vertices[(1+j)%N], 0xFFFFFFFF);
|
||||
|
||||
queueline(V * p.p, V * C0, 0xFF0000FF);
|
||||
if(p.patterndir != -1)
|
||||
queueline(V * p.p, V * shmup::calc_relative_matrix(c->master->move[p.patterndir]->c7, c, p.p) * C0, 0x00FF00FF);
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct heptinfo {
|
||||
heptspin base;
|
||||
vector<cell*> subcells;
|
||||
};
|
||||
|
||||
map<heptagon*, heptinfo> periodmap;
|
||||
|
||||
void link_to_base(heptagon *h, heptspin base) {
|
||||
// printf("linking %p to %p/%d\n", h, base.h, base.spin);
|
||||
auto &hi = periodmap[h];
|
||||
hi.base = base;
|
||||
for(int k: cells_of_heptagon[base.h]) {
|
||||
cell *c = newCell(isize(cells[k].vertices), h);
|
||||
hi.subcells.push_back(c);
|
||||
cellindex[c] = k;
|
||||
}
|
||||
h->c7 = hi.subcells[0];
|
||||
}
|
||||
|
||||
void clear_links(heptagon *h) {
|
||||
auto& hi = periodmap[h];
|
||||
for(cell *c: hi.subcells) {
|
||||
for(int i=0; i<c->type; i++) if(c->mov[i]) c->mov[i]->mov[c->spin(i)] = NULL;
|
||||
cellindex.erase(c);
|
||||
delete c;
|
||||
}
|
||||
h->c7 = NULL;
|
||||
periodmap.erase(h);
|
||||
}
|
||||
|
||||
void link_start(heptagon *h) {
|
||||
link_to_base(h, heptspin(cells[0].owner->master, 0));
|
||||
}
|
||||
|
||||
void link_next(heptagon *parent, int d) {
|
||||
if(!periodmap.count(parent))
|
||||
link_to_base(parent, heptspin(cells[0].owner->master, 0));
|
||||
// printf("linking next: %p direction %d [s%d]\n", parent, d, parent->spin(d));
|
||||
auto *h = parent->move[d];
|
||||
heptspin hs = periodmap[parent].base + d + wstep - parent->spin(d);
|
||||
link_to_base(h, hs);
|
||||
}
|
||||
|
||||
void may_link_next(heptagon *parent, int d) {
|
||||
if(!periodmap.count(parent->move[d]))
|
||||
link_next(parent, d);
|
||||
}
|
||||
|
||||
|
||||
void link_cell(cell *c, int d) {
|
||||
// printf("linking cell: %p direction %d\n", c, d);
|
||||
int ci = cellindex[c];
|
||||
auto& sc = cells[ci];
|
||||
int ci2 = sc.neid[d];
|
||||
auto& sc2 = cells[ci2];
|
||||
|
||||
heptagon *master2 = NULL;
|
||||
|
||||
if(sc2.owner == sc.owner) {
|
||||
master2 = c->master;
|
||||
// printf("local\n");
|
||||
}
|
||||
else {
|
||||
int dirs = 0;
|
||||
int os = periodmap[c->master].base.spin;
|
||||
for(int d=0; d<S7; d++) if(sc2.owner->master == sc.owner->master->move[(os+d)%S7]) {
|
||||
heptspin hss(c->master, d);
|
||||
hss += wstep;
|
||||
master2 = hss.h;
|
||||
// printf("master2 is %p; base = %p; should be = %p\n", master2, periodmap[master2].base.h, sc2.owner->master);
|
||||
dirs++;
|
||||
}
|
||||
if(dirs != 1) { printf("dirs error\n"); exit(1); }
|
||||
}
|
||||
|
||||
cell *c2 = periodmap[master2].subcells[sc2.localindex];
|
||||
c->mov[d] = c2;
|
||||
tsetspin(c->spintable, d, sc.spin[d]);
|
||||
c2->mov[sc.spin[d]] = c;
|
||||
tsetspin(c2->spintable, sc.spin[d], d);
|
||||
}
|
||||
|
||||
void show_gridmaker() {
|
||||
cmode = sm::SIDE;
|
||||
gamescreen(0);
|
||||
dialog::init(XLAT("Irregular grid"));
|
||||
dialog::addSelItem(XLAT("activate"), its(runlevel), 'f');
|
||||
dialog::display();
|
||||
if(runlevel == 10) dialog::add_action([] {
|
||||
popScreen();
|
||||
pop_game();
|
||||
for(hrmap *& hm : allmaps) if(hm == base) hm = NULL;
|
||||
stop_game();
|
||||
irr::on = true;
|
||||
nonbitrunc = true;
|
||||
need_reset_geometry = true;
|
||||
gridmaking = false;
|
||||
start_game();
|
||||
});
|
||||
keyhandler = [] (int sym, int uni) {
|
||||
dialog::handleNavigation(sym, uni);
|
||||
// no exit
|
||||
};
|
||||
}
|
||||
|
||||
void create_map() {
|
||||
push_game();
|
||||
switch(geometry) {
|
||||
case gNormal:
|
||||
geometry = gKleinQuartic;
|
||||
break;
|
||||
|
||||
case gOctagon:
|
||||
geometry = gBolza2;
|
||||
break;
|
||||
|
||||
default: ;
|
||||
break;
|
||||
}
|
||||
|
||||
nonbitrunc = true;
|
||||
need_reset_geometry = true;
|
||||
start_game();
|
||||
base = currentmap;
|
||||
drawthemap();
|
||||
pushScreen(show_gridmaker);
|
||||
runlevel = 0;
|
||||
gridmaking = true;
|
||||
}
|
||||
|
||||
int readArgs() {
|
||||
using namespace arg;
|
||||
|
||||
if(0) ;
|
||||
else if(argis("-irr")) {
|
||||
PHASE(3);
|
||||
shift(); sc = argi();
|
||||
restart_game();
|
||||
create_map();
|
||||
}
|
||||
else return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool pseudohept(cell* c) {
|
||||
return cells[cellindex[c]].is_pseudohept;
|
||||
}
|
||||
|
||||
bool ctof(cell* c) {
|
||||
return cells[cellindex[c]].patterndir == -1;
|
||||
}
|
||||
|
||||
array<heptagon*, 3> get_masters(cell *c) {
|
||||
int d = cells[cellindex[c]].patterndir;
|
||||
heptspin s = periodmap[c->master].base;
|
||||
heptspin s0 = heptspin(c->master, 0) + (d - s.spin);
|
||||
return make_array(s0.h, (s0 + wstep).h, (s0 + 1 + wstep).h);
|
||||
}
|
||||
|
||||
auto hook =
|
||||
addHook(hooks_args, 100, readArgs) +
|
||||
addHook(hooks_drawcell, 100, draw_cell_schematics) +
|
||||
addHook(shmup::hooks_turn, 100, step);
|
||||
|
||||
}}
|
||||
|
||||
/*
|
||||
if(mouseover && !ctof(mouseover)) {
|
||||
for(auto h: gp::get_masters(mouseover))
|
||||
queueline(shmup::ggmatrix(h->c7)*C0, shmup::ggmatrix(mouseover)*C0, 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
*/
|
@ -210,14 +210,14 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
else {
|
||||
|
||||
if(d == 9) {
|
||||
cell *c2 = gp::on ? c->master->c7 : c;
|
||||
cell *c2 = (gp::on || irr::on) ? c->master->c7 : c;
|
||||
if(cdist50(c2) == 3 && polarb50(c2) == 1)
|
||||
c->wall = waPalace;
|
||||
}
|
||||
|
||||
if(d == 8 && sphere) {
|
||||
int gs = getHemisphere(c,0);
|
||||
if(gp::on) {
|
||||
if(gp::on || irr::on) {
|
||||
int v = 1;
|
||||
forCellEx(c2, c) if(getHemisphere(c2, 0) != gs)
|
||||
v = 2;
|
||||
@ -583,7 +583,7 @@ void giantLandSwitch(cell *c, int d, cell *from) {
|
||||
else if(v == 25 || v == 59 || v == 27 || v == 57)
|
||||
c->wall = waVineHalfB;
|
||||
else c->wall = waNone;
|
||||
if(gp::on && cellHalfvine(c)) {
|
||||
if((gp::on || irr::on) && cellHalfvine(c)) {
|
||||
c->wall = waNone;
|
||||
forCellCM(c2, c) if(emeraldval(c2) == (v^1))
|
||||
c->wall = waVinePlant;
|
||||
|
@ -1159,6 +1159,15 @@ land_validity_t& land_validity(eLand l) {
|
||||
if(isWarped(l) && a4 && gp::on)
|
||||
return dont_work;
|
||||
|
||||
if((isWarped(l) || l == laDual) && irr::on)
|
||||
return dont_work;
|
||||
|
||||
if(irr::on && among(l, laStorms, laPrairie, laBlizzard, laVolcano))
|
||||
return dont_work;
|
||||
|
||||
if(irr::on && among(l, laWhirlpool, laCamelot, laCaribbean, laClearing, laTemple, laHive, laMirror, laMirrorOld, laReptile, laKraken, laBurial))
|
||||
return dont_work;
|
||||
|
||||
// equidistant-based lands
|
||||
if(isEquidLand(l)) {
|
||||
// no equidistants supported in chaos mode
|
||||
|
@ -826,7 +826,7 @@ void setAppropriateOverview() {
|
||||
pushScreen(yendor::showMenu);
|
||||
else if(peace::on)
|
||||
pushScreen(peace::showMenu);
|
||||
else if((geometry != gNormal || gp::on) && !chaosmode && !(geometry == gEuclid && isCrossroads(specialland)) && !(weirdhyperbolic && specialland == laCrossroads4)) {
|
||||
else if((geometry != gNormal || gp::on || irr::on) && !chaosmode && !(geometry == gEuclid && isCrossroads(specialland)) && !(weirdhyperbolic && specialland == laCrossroads4)) {
|
||||
runGeometryExperiments();
|
||||
}
|
||||
else {
|
||||
|
103
pattern2.cpp
103
pattern2.cpp
@ -49,11 +49,13 @@ bool ishex2(cell *c) {
|
||||
else return c->type != S6;
|
||||
}
|
||||
|
||||
int emeraldval(heptagon *h) { return h->emeraldval >> 3; }
|
||||
|
||||
int emeraldval(cell *c) {
|
||||
if(euclid) return eupattern(c);
|
||||
if(sphere) return 0;
|
||||
if(ctof(c))
|
||||
return c->master->emeraldval >> 3;
|
||||
return emeraldval(c->master);
|
||||
else {
|
||||
auto ar = gp::get_masters(c);
|
||||
return emerald_hexagon(
|
||||
@ -96,9 +98,9 @@ int fiftyval(cell *c) {
|
||||
else {
|
||||
auto ar = gp::get_masters(c);
|
||||
return bitmajority(
|
||||
fiftyval(ar[0]),
|
||||
fiftyval(ar[1]),
|
||||
fiftyval(ar[2])) + 512;
|
||||
ar[0]->fiftyval,
|
||||
ar[1]->fiftyval,
|
||||
ar[2]->fiftyval) + 512;
|
||||
}
|
||||
}
|
||||
|
||||
@ -109,47 +111,47 @@ int cdist50(cell *c) {
|
||||
return "0123333332112332223322233211233333322"[eufifty(c)] - '0';
|
||||
else return "012333321112322232222321123"[eufifty(c)] - '0';
|
||||
}
|
||||
if(c->type != 6) return cdist50(fiftyval(c));
|
||||
if(ctof(c)) return cdist50(c->master->fiftyval);
|
||||
auto ar = gp::get_masters(c);
|
||||
int a0 = cdist50(ar[0]);
|
||||
int a1 = cdist50(ar[1]);
|
||||
int a2 = cdist50(ar[2]);
|
||||
int a0 = cdist50(ar[0]->fiftyval);
|
||||
int a1 = cdist50(ar[1]->fiftyval);
|
||||
int a2 = cdist50(ar[2]->fiftyval);
|
||||
if(a0 == 0 || a1 == 0 || a2 == 0) return 1;
|
||||
return a0+a1+a2-5;
|
||||
}
|
||||
|
||||
int land50(cell *c) {
|
||||
if(c->type != 6) return land50(fiftyval(c));
|
||||
else if(sphere || euclid) return 0;
|
||||
if(sphere || euclid) return 0;
|
||||
else if(ctof(c)) return land50(fiftyval(c));
|
||||
else {
|
||||
auto ar = gp::get_masters(c);
|
||||
for(int i=0; i<3; i++)
|
||||
if(cdist50(ar[i]) < 3) return land50(ar[i]);
|
||||
if(cdist50(ar[i]->fiftyval) < 3) return land50(ar[i]->fiftyval);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int polara50(cell *c) {
|
||||
if(c->type != 6) return polara50(fiftyval(c));
|
||||
else if(sphere || euclid || S7>7 || S6>6) return 0;
|
||||
else if(gp::on) return polara50(fiftyval(c->master->c7));
|
||||
if(sphere || euclid || S7>7 || S6>6) return 0;
|
||||
else if(gp::on || irr::on) return polara50(fiftyval(c->master->c7));
|
||||
else if(ctof(c)) return polara50(fiftyval(c));
|
||||
else {
|
||||
auto ar = gp::get_masters(c);
|
||||
for(int i=0; i<3; i++)
|
||||
if(cdist50(ar[i]) < 3) return polara50(ar[i]);
|
||||
if(cdist50(ar[i]->fiftyval) < 3) return polara50(ar[i]->fiftyval);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int polarb50(cell *c) {
|
||||
if(euclid) return true;
|
||||
if(c->type != 6) return polarb50(fiftyval(c));
|
||||
else if(sphere || euclid || S7>7 || S6>6) return true;
|
||||
else if(gp::on) return polarb50(fiftyval(c->master->c7));
|
||||
if(sphere || euclid || S7>7 || S6>6) return true;
|
||||
else if(gp::on || irr::on) return polarb50(fiftyval(c->master->c7));
|
||||
else if(ctof(c)) return polarb50(fiftyval(c));
|
||||
else {
|
||||
auto ar = gp::get_masters(c);
|
||||
for(int i=0; i<3; i++)
|
||||
if(cdist50(ar[i]) < 3) return polarb50(ar[i]);
|
||||
if(cdist50(ar[i]->fiftyval) < 3) return polarb50(ar[i]->fiftyval);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -158,30 +160,32 @@ int elhextable[28][3] = {
|
||||
{0,1,2}, {1,2,9}, {1,9,-1}, {1,8,-1}, {1,-1,-1}
|
||||
};
|
||||
|
||||
int fiftyval049(heptagon *h) {
|
||||
int i = h->fiftyval / 32;
|
||||
if(i <= 7) return i;
|
||||
if(quotient) return 0;
|
||||
vector<int> allcodes;
|
||||
for(int k=0; k<7; k++) {
|
||||
heptagon *h2 = createStep(h, k);
|
||||
if(polara50(h2->fiftyval) == polara50(h->fiftyval) && polarb50(h2->fiftyval) == polarb50(h->fiftyval))
|
||||
allcodes.push_back(fiftyval049(h2));
|
||||
}
|
||||
int d = allcodes[1] - allcodes[0];
|
||||
if(d == -1 || d == 6) swap(allcodes[0], allcodes[1]);
|
||||
// printf("%d,%d: %d\n", allcodes[0], allcodes[1], allcodes[0] + 7);
|
||||
return allcodes[0] + 7;
|
||||
}
|
||||
|
||||
int fiftyval049(cell *c) {
|
||||
if(euclid) return fiftyval(c) / 32;
|
||||
else if(ctof(c)) {
|
||||
int i = fiftyval(c) / 32;
|
||||
if(i <= 7) return i;
|
||||
if(quotient) return 0;
|
||||
vector<int> allcodes;
|
||||
for(int k=0; k<7; k++) {
|
||||
cell *c2 = createStep(c->master, k)->c7;
|
||||
if(polara50(c2) == polara50(c) && polarb50(c2) == polarb50(c))
|
||||
allcodes.push_back(fiftyval049(c2));
|
||||
}
|
||||
int d = allcodes[1] - allcodes[0];
|
||||
if(d == -1 || d == 6) swap(allcodes[0], allcodes[1]);
|
||||
// printf("%d,%d: %d\n", allcodes[0], allcodes[1], allcodes[0] + 7);
|
||||
return allcodes[0] + 7;
|
||||
}
|
||||
else if(ctof(c)) return fiftyval049(c->master);
|
||||
else if(sphere) return 0;
|
||||
else {
|
||||
int a[3], qa=0;
|
||||
int pa = polara50(c), pb = polarb50(c);
|
||||
auto ar = gp::get_masters(c);
|
||||
for(int i=0; i<3; i++)
|
||||
if(polara50(ar[i]) == pa && polarb50(ar[i]) == pb)
|
||||
if(polara50(ar[i]->fiftyval) == pa && polarb50(ar[i]->fiftyval) == pb)
|
||||
a[qa++] = fiftyval049(ar[i]);
|
||||
// 0-1-2
|
||||
sort(a, a+qa);
|
||||
@ -248,6 +252,7 @@ int val46(cell *c);
|
||||
|
||||
int zebra40(cell *c) {
|
||||
if(euclid) return eupattern(c);
|
||||
else if(irr::on) return c->master->zebraval/10;
|
||||
else if(a46) {
|
||||
int v = val46(c);
|
||||
if(v<4) return v;
|
||||
@ -285,9 +290,9 @@ int zebra40(cell *c) {
|
||||
else {
|
||||
int ii[3], z;
|
||||
auto ar = gp::get_masters(c);
|
||||
ii[0] = (ar[0]->master->zebraval/10);
|
||||
ii[1] = (ar[1]->master->zebraval/10);
|
||||
ii[2] = (ar[2]->master->zebraval/10);
|
||||
ii[0] = (ar[0]->zebraval/10);
|
||||
ii[1] = (ar[1]->zebraval/10);
|
||||
ii[2] = (ar[2]->zebraval/10);
|
||||
for(int r=0; r<2; r++)
|
||||
if(ii[1] < ii[0] || ii[2] < ii[0])
|
||||
z = ii[0], ii[0] = ii[1], ii[1] = ii[2], ii[2] = z;
|
||||
@ -304,14 +309,14 @@ int zebra40(cell *c) {
|
||||
}
|
||||
|
||||
int zebra3(cell *c) {
|
||||
if(c->type != 6) return (c->master->zebraval/10)/4;
|
||||
else if(sphere || S7>7 || S6>6) return 0;
|
||||
if(ctof(c)) return (c->master->zebraval/10)/4;
|
||||
else if(euclid || sphere || S7>7 || S6>6) return 0;
|
||||
else {
|
||||
int ii[3];
|
||||
auto ar = gp::get_masters(c);
|
||||
ii[0] = (ar[0]->master->zebraval/10)/4;
|
||||
ii[1] = (ar[1]->master->zebraval/10)/4;
|
||||
ii[2] = (ar[2]->master->zebraval/10)/4;
|
||||
ii[0] = (ar[0]->zebraval/10)/4;
|
||||
ii[1] = (ar[1]->zebraval/10)/4;
|
||||
ii[2] = (ar[2]->zebraval/10)/4;
|
||||
if(ii[0] == ii[1]) return ii[0];
|
||||
if(ii[1] == ii[2]) return ii[1];
|
||||
if(ii[2] == ii[0]) return ii[2];
|
||||
@ -328,7 +333,7 @@ pair<int, bool> fieldval(cell *c) {
|
||||
|
||||
int fieldval_uniq(cell *c) {
|
||||
if(sphere) {
|
||||
if(ctof(c)) return c->master->fieldval;
|
||||
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;
|
||||
}
|
||||
else if(torus) {
|
||||
@ -338,7 +343,7 @@ int fieldval_uniq(cell *c) {
|
||||
auto p = cell_to_pair(c);
|
||||
return gmod(p.first * torusconfig::dx + p.second * torusconfig::dy, torusconfig::qty);
|
||||
}
|
||||
if(ctof(c) || gp::on) return c->master->fieldval/S7;
|
||||
if(ctof(c) || gp::on || irr::on) return c->master->fieldval/S7;
|
||||
else {
|
||||
int z = 0;
|
||||
for(int u=0; u<S6; u+=2)
|
||||
@ -348,7 +353,7 @@ int fieldval_uniq(cell *c) {
|
||||
}
|
||||
|
||||
int fieldval_uniq_rand(cell *c, int randval) {
|
||||
if(sphere || torus || euclid)
|
||||
if(sphere || torus || euclid || gp::on || irr::on)
|
||||
// we do not care in these cases
|
||||
return fieldval_uniq(c);
|
||||
if(ctof(c)) return currfp.gmul(c->master->fieldval, randval)/7;
|
||||
@ -708,7 +713,8 @@ namespace patterns {
|
||||
}
|
||||
|
||||
void val_all(cell *c, patterninfo &si, int sub, int pat) {
|
||||
if(a46) val46(c, si, sub, pat);
|
||||
if(irr::on) si.symmetries = 1;
|
||||
else if(a46) val46(c, si, sub, pat);
|
||||
else if(a38) val38(c, si, sub, pat);
|
||||
else if(sphere) valSibling(c, si, sub, pat);
|
||||
else if(euclid4) valEuclid4(c, si, sub);
|
||||
@ -1005,6 +1011,7 @@ namespace patterns {
|
||||
}
|
||||
|
||||
int geosupport_threecolor() {
|
||||
if(irr::on) return 0;
|
||||
if(!nonbitrunc && S3 == 3) {
|
||||
if(S7 % 2) return 1;
|
||||
return 2;
|
||||
@ -1019,6 +1026,7 @@ int geosupport_threecolor() {
|
||||
int geosupport_graveyard() {
|
||||
// always works in bitrunc geometries
|
||||
if(!nonbitrunc) return 2;
|
||||
if(irr::on) return 0;
|
||||
|
||||
// always works in patterns supporting three-color
|
||||
int tc = max(geosupport_threecolor(), gp_threecolor());
|
||||
@ -1130,6 +1138,7 @@ int pattern_threecolor(cell *c) {
|
||||
// in the 'pure heptagonal' tiling, returns true for a set of cells
|
||||
// which roughly corresponds to the heptagons in the normal tiling
|
||||
bool pseudohept(cell *c) {
|
||||
if(irr::on) return irr::pseudohept(c);
|
||||
if(gp::on && gp_threecolor() == 2)
|
||||
return gp::pseudohept_val(c) == 0;
|
||||
if(gp::on && gp_threecolor() == 1 && (S7&1) && (S3 == 3))
|
||||
|
@ -3313,7 +3313,12 @@ void destroyBoats(cell *c) {
|
||||
}
|
||||
|
||||
transmatrix master_relative(cell *c, bool get_inverse) {
|
||||
if(gp::on) {
|
||||
if(irr::on) {
|
||||
int id = irr::cellindex[c];
|
||||
ld alpha = 2 * M_PI / S7 * irr::periodmap[c->master].base.spin;
|
||||
return get_inverse ? irr::cells[id].rpusher * spin(-alpha-master_to_c7_angle()): spin(alpha + master_to_c7_angle()) * irr::cells[id].pusher;
|
||||
}
|
||||
else if(gp::on) {
|
||||
if(c == c->master->c7) {
|
||||
return spin((get_inverse?-1:1) * master_to_c7_angle());
|
||||
}
|
||||
|
@ -1029,10 +1029,10 @@ namespace gamestack {
|
||||
bool pushed() { return isize(gd); }
|
||||
|
||||
void push() {
|
||||
if(geometry) {
|
||||
/* if(geometry) {
|
||||
printf("ERROR: push implemented only in non-hyperbolic geometry\n");
|
||||
exit(1);
|
||||
}
|
||||
} */
|
||||
gamedata gdn;
|
||||
gdn.hmap = currentmap;
|
||||
gdn.cwt = cwt;
|
||||
|
Loading…
Reference in New Issue
Block a user