An option to play on a disk (and use bounded space rules). Also renamed 'bounded' flag to 'closed' or similar, and improved Halloween

This commit is contained in:
Zeno Rogue 2022-05-21 13:08:42 +02:00
parent 9bc0623022
commit 793148729b
40 changed files with 218 additions and 171 deletions

View File

@ -112,6 +112,7 @@ EX bool wrongMode(char flags) {
if(flags != rg::special_geometry && flags != rg::special_geometry_nicewalls) {
if(!BITRUNCATED) return true;
if(geometry != gNormal) return true;
if(disksize) return true;
}
if(shmup::on != (flags == rg::shmup || flags == rg::racing)) return true;
@ -225,10 +226,10 @@ EX void achievement_collection2(eItem it, int q) {
if(randomPatternsMode) return;
LATE( achievement_collection2(it, q); )
if(it == itTreat && q == 50 && (geometry == gSphere || geometry == gElliptic) && BITRUNCATED)
if(it == itTreat && q == 50 && (geometry == gSphere || geometry == gElliptic) && BITRUNCATED && !disksize)
achievement_gain("HALLOWEEN1", rg::special_geometry);
if(it == itTreat && q == 100 && (geometry == gSphere || geometry == gElliptic) && BITRUNCATED)
if(it == itTreat && q == 100 && (geometry == gSphere || geometry == gElliptic) && BITRUNCATED && !disksize)
achievement_gain("HALLOWEEN2", rg::special_geometry);
if(q == 1) {
@ -309,12 +310,12 @@ EX void achievement_collection2(eItem it, int q) {
// 32
if(it == itHolyGrail) {
if(q == 1) achievement_gain("GRAIL2");
if(PURE && geometry == gNormal)
if(PURE && geometry == gNormal && !disksize)
achievement_gain("GRAILH", rg::special_geometry_nicewalls);
#if CAP_CRYSTAL
if(PURE && cryst && ginf[gCrystal].sides == 8 && ginf[gCrystal].vertex == 4 && !crystal::used_compass_inside)
if(PURE && cryst && ginf[gCrystal].sides == 8 && ginf[gCrystal].vertex == 4 && !crystal::used_compass_inside && !disksize)
achievement_gain("GRAIL4D", rg::special_geometry);
if(BITRUNCATED && cryst && ginf[gCrystal].sides == 8 && ginf[gCrystal].vertex == 3 && !crystal::used_compass_inside)
if(BITRUNCATED && cryst && ginf[gCrystal].sides == 8 && ginf[gCrystal].vertex == 3 && !crystal::used_compass_inside && !disksize)
achievement_gain("GRAIL4D2", rg::special_geometry);
#endif
if(q == 3) achievement_gain("GRAIL3");
@ -599,7 +600,7 @@ EX void achievement_count(const string& s, int current, int prev) {
achievement_gain("LIGHTNING2");
if(s == "LIGHTNING" && current-prev >= 10)
achievement_gain("LIGHTNING3");
if(s == "MIRAGE" && current >= 35 && geometry == gEuclid)
if(s == "MIRAGE" && current >= 35 && geometry == gEuclid && !disksize)
achievement_gain("MIRAGE", rg::special_geometry);
if(s == "ORB" && current >= 10)
achievement_gain("ORB3");
@ -633,6 +634,7 @@ EX void achievement_score(int cat, int number) {
if(cheater) return;
if(casual) return;
LATE( achievement_score(cat, number); )
if(disksize) return;
if(cat == LB_HALLOWEEN) {
if(geometry != gSphere && geometry != gElliptic)
return;
@ -943,7 +945,7 @@ EX string get_rich_presence_text() {
return "Guided Tour";
string res;
if(geometry != gNormal || !BITRUNCATED)
if(geometry != gNormal || !BITRUNCATED || disksize)
res = res + full_geometry_name() + " ";
if(land_structure != default_land_structure()) res += land_structure_name(false) + " ";

View File

@ -659,21 +659,21 @@ EX void load(const string& fname, bool load_as_slided IS(false), bool keep_slide
ep.force_eat(")");
ginf[gArbitrary].g = curv > 0 ? giSphere2 : curv < 0 ? giHyperb2 : giEuclid2;
ginf[gArbitrary].sides = 7;
set_flag(ginf[gArbitrary].flags, qBOUNDED, curv > 0);
set_flag(ginf[gArbitrary].flags, qCLOSED, curv > 0);
set_flag(ginf[gArbitrary].flags, qAFFINE, false);
geom3::apply_always3();
}
else if(ep.eat("e2.")) {
ginf[gArbitrary].g = giEuclid2;
ginf[gArbitrary].sides = 7;
set_flag(ginf[gArbitrary].flags, qBOUNDED, false);
set_flag(ginf[gArbitrary].flags, qCLOSED, false);
set_flag(ginf[gArbitrary].flags, qAFFINE, false);
geom3::apply_always3();
}
else if(ep.eat("a2.")) {
ginf[gArbitrary].g = giEuclid2;
ginf[gArbitrary].sides = 7;
set_flag(ginf[gArbitrary].flags, qBOUNDED, false);
set_flag(ginf[gArbitrary].flags, qCLOSED, false);
set_flag(ginf[gArbitrary].flags, qAFFINE, true);
affine_limit = 200;
geom3::apply_always3();
@ -681,14 +681,14 @@ EX void load(const string& fname, bool load_as_slided IS(false), bool keep_slide
else if(ep.eat("h2.")) {
ginf[gArbitrary].g = giHyperb2;
ginf[gArbitrary].sides = 7;
set_flag(ginf[gArbitrary].flags, qBOUNDED, false);
set_flag(ginf[gArbitrary].flags, qCLOSED, false);
set_flag(ginf[gArbitrary].flags, qAFFINE, false);
geom3::apply_always3();
}
else if(ep.eat("s2.")) {
ginf[gArbitrary].g = giSphere2;
ginf[gArbitrary].sides = 5;
set_flag(ginf[gArbitrary].flags, qBOUNDED, true);
set_flag(ginf[gArbitrary].flags, qCLOSED, true);
set_flag(ginf[gArbitrary].flags, qAFFINE, false);
geom3::apply_always3();
}
@ -1504,7 +1504,7 @@ EX void convert() {
ac.shapes.resize(N);
ginf[gArbitrary].g = cginf.g;
ginf[gArbitrary].flags = cgflags & qBOUNDED;
ginf[gArbitrary].flags = cgflags & qCLOSED;
for(int i=0; i<N; i++) {
auto id = identification[old_shvids[i]];

View File

@ -419,7 +419,7 @@ geometryinfo1& archimedean_tiling::get_geometry(ld mul) {
void archimedean_tiling::compute_geometry() {
ginf[gArchimedean].g = get_geometry();
set_flag(ginf[gArchimedean].flags, qBOUNDED, get_class() == gcSphere);
set_flag(ginf[gArchimedean].flags, qCLOSED, get_class() == gcSphere);
DEBB(DF_GEOM, (format("euclidean_angle_sum = %f\n", float(euclidean_angle_sum))));

View File

@ -214,7 +214,7 @@ EX int period_xy_edit, period_z_edit;
EX void set_flags() {
auto& flag = ginf[gArnoldCat].flags;
set_flag(flag, qANYQ, period_xy || period_z);
set_flag(flag, qBOUNDED, period_xy && period_z);
set_flag(flag, qCLOSED, period_xy && period_z);
set_flag(flag, qSMALL, period_xy && period_z && (period_xy * period_xy * period_z <= 4096));
set_flag(flag, qHUGE_BOUNDED, period_xy * period_xy * period_z > 16384);
}

View File

@ -2008,7 +2008,7 @@ EX void moreBigStuff(cell *c) {
EX void generate_mines() {
vector<cell*> candidates;
if(bounded)
if(closed_or_bounded)
for(cell *c: currentmap->allcells())
setdist(c, 7, nullptr);

View File

@ -183,7 +183,8 @@ transmatrix hrmap::adj(heptagon *h, int i) { return relative_matrix(h->cmove(i),
vector<cell*>& hrmap::allcells() {
static vector<cell*> default_allcells;
if(bounded && !(cgflags & qHUGE_BOUNDED) && !(hybri && hybrid::csteps == 0)) {
if(disksize) return all_disk_cells;
if(closed_manifold && !(cgflags & qHUGE_BOUNDED) && !(hybri && hybrid::csteps == 0)) {
celllister cl(gamestart(), 1000000, 1000000, NULL);
default_allcells = cl.lst;
return default_allcells;
@ -330,6 +331,24 @@ EX void eumerge(cell* c1, int s1, cell *c2, int s2, bool mirror) {
EX hookset<hrmap*()> hooks_newmap;
EX int req_disksize, disksize;
EX vector<cell*> all_disk_cells;
EX void init_disk_cells() {
disksize = req_disksize;
all_disk_cells.clear();
if(!disksize) return;
celllister cl(currentmap->gamestart(), 1000000, disksize, NULL);
all_disk_cells = cl.lst;
sort(all_disk_cells.begin(), all_disk_cells.end());
}
EX bool is_in_disk(cell *c) {
auto it = lower_bound(all_disk_cells.begin(), all_disk_cells.end(), c);
if(it == all_disk_cells.end()) return false;
return *it == c;
}
/** create a map in the current geometry */
EX void initcells() {
DEBB(DF_INIT, ("initcells"));
@ -520,7 +539,7 @@ EX int celldist(cell *c) {
return hybrid::celldistance(c, currentmap->gamestart());
if(nil && !quotient) return DISTANCE_UNKNOWN;
if(euc::in()) return celldistance(currentmap->gamestart(), c);
if(sphere || bt::in() || WDIM == 3 || cryst || sn::in() || kite::in() || bounded) return celldistance(currentmap->gamestart(), c);
if(sphere || bt::in() || WDIM == 3 || cryst || sn::in() || kite::in() || closed_manifold) return celldistance(currentmap->gamestart(), c);
#if CAP_IRR
if(IRREGULAR) return irr::celldist(c, false);
#endif
@ -1204,7 +1223,7 @@ EX int celldistance(cell *c1, cell *c2) {
}
#endif
if(bounded) return bounded_celldistance(c1, c2);
if(closed_manifold) return bounded_celldistance(c1, c2);
#if CAP_CRYSTAL
if(cryst) return crystal::precise_distance(c1, c2);

View File

@ -785,7 +785,7 @@ struct geometryinfo {
eVariation default_variation;
};
static const flagtype qBOUNDED = 1;
static const flagtype qCLOSED = 1;
static const flagtype qANYQ = 2;
static const flagtype qNONORIENTABLE = 4;
static const flagtype qSMALL = 8;
@ -835,20 +835,20 @@ extern eVariation variation;
#endif
#if HDR
static const flagtype qsNONOR = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE;
static const flagtype qsNONOR = qANYQ | qSMALL | qCLOSED | qNONORIENTABLE;
static const flagtype qsNONORE = qsNONOR | qELLIPTIC;
static const flagtype qsBQ = qANYQ | qSMALL | qBOUNDED;
static const flagtype qsSMALL = qANYQ | qSMALL | qBOUNDED;
static const flagtype qsSMALLN = qANYQ | qSMALL | qBOUNDED | qNONORIENTABLE;
static const flagtype qsZEBRA = qANYQ | qSMALL | qBOUNDED | qZEBRA;
static const flagtype qsFIELD = qANYQ | qFIELD | qBOUNDED;
static const flagtype qsDOCKS = qANYQ | qSMALL | qBOUNDED | qDOCKS;
static const flagtype qsSMALLB = qSMALL | qBOUNDED;
static const flagtype qsBQ = qANYQ | qSMALL | qCLOSED;
static const flagtype qsSMALL = qANYQ | qSMALL | qCLOSED;
static const flagtype qsSMALLN = qANYQ | qSMALL | qCLOSED | qNONORIENTABLE;
static const flagtype qsZEBRA = qANYQ | qSMALL | qCLOSED | qZEBRA;
static const flagtype qsFIELD = qANYQ | qFIELD | qCLOSED;
static const flagtype qsDOCKS = qANYQ | qSMALL | qCLOSED | qDOCKS;
static const flagtype qsSMALLB = qSMALL | qCLOSED;
static const flagtype qsSMALLBF = qsSMALLB | qsFIELD | qANYQ;
static const flagtype qsSMALLBE = qsSMALLB | qELLIPTIC | qANYQ;
static const flagtype qsBP = qBINARY | qKITE;
static const flagtype qsSINGLE = qANYQ | qSMALL | qBOUNDED | qSINGLE;
static const flagtype qsSINGLE = qANYQ | qSMALL | qCLOSED | qSINGLE;
#endif
EX geometryinfo1 giEuclid2 = { gcEuclid, 2, 2, 3, {1,1, 0,0 } };

View File

@ -15,7 +15,7 @@ EX namespace whirlwind {
EX int fzebra3(cell *c) {
if(arcm::in()) return 0;
if(euclid) {
if(bounded) return 0;
if(closed_manifold) return 0;
auto co = euc2_coordinates(c);
int y = co.second;
return 1+((((signed short)(y)+int(50000))/3)%3);
@ -1011,7 +1011,7 @@ EX namespace clearing {
}
EX void imput(cell *c) {
if(bounded) return;
if(closed_manifold) return;
if(score.count(c)) return;
changes.map_value(score, c);
auto& is = score[c];
@ -1216,7 +1216,7 @@ EX namespace mirror {
#endif
bool noMirrorOn(cell *c) {
return c->monst || (!shmup::on && isPlayerOn(c)) || (!bounded && c->cpdist > gamerange());
return c->monst || (!shmup::on && isPlayerOn(c)) || (!closed_or_bounded && c->cpdist > gamerange());
}
bool cellMirrorable(cell *c) {
@ -3671,6 +3671,53 @@ EX namespace halloween {
EX cell *dragoncells[4];
vector<cell*> srch;
EX void generate() {
auto lst = currentmap->allcells();
for(cell *c: lst)
setdist(c, 7, nullptr);
halloween::dragoncells[0] = NULL;
if(sphere && geometry == gNormal) {
for(cell *c: lst) {
if(GOLDBERG) {
int fv = c->master->fiftyval;
if(fv == 1 || fv == 4 || fv == 10)
c->wall = waChasm;
if(c == c->master->c7 && fv == 3)
c->item = itTreat;
}
else if(!BITRUNCATED) {
int fv = c->master->fiftyval;
if(fv == 1 || fv == 4 || fv == 2)
c->wall = waChasm;
if(fv == 3) c->item = itTreat;
}
else {
if(c->type == 5) {
int fv = c->master->fiftyval;
if(fv == 3 || fv == 4 || fv == 2 || fv == 5)
c->wall = waChasm;
if(fv == 2) halloween::dragoncells[0] = c;
if(fv == 5) halloween::dragoncells[3] = c;
if(fv == 1) c->item = itTreat;
}
if(c->type == 6) {
int fvset = 0;
for(int i=0; i<6; i+=2) fvset |= 1 << createMov(c, i)->master->fiftyval;
if(fvset == 35 || fvset == 7) c->wall = waChasm;
if(fvset == 7) halloween::dragoncells[1] = c;
if(fvset == 35) halloween::dragoncells[2] = c;
}
}
}
}
else {
for(int i=1; i<isize(lst); i+=60) lst[i]->item = itTreat;
for(int i=2; i<isize(lst); i+=6) lst[i]->wall = waChasm;
}
}
cell *farempty(bool lastresort = false) {
int maxdist = 0;
vector<cell*> validcells;

View File

@ -531,7 +531,7 @@ EX void count_status() {
}
EX bool in_minesweeper() {
return bounded && specialland == laMinefield;
return closed_or_bounded && specialland == laMinefield;
}
EX bool uncoverMines(cell *c, int lev, int dist, bool just_checking) {
@ -620,7 +620,7 @@ EX bool safe() {
EX void uncover_full(cell *c2) {
int mineradius =
bounded ? 3 :
closed_or_bounded ? 3 :
(items[itBombEgg] < 1 && !tactic::on) ? 0 :
items[itBombEgg] < 20 ? 1 :
items[itBombEgg] < 30 ? 2 :

View File

@ -934,6 +934,11 @@ EX void initConfig() {
param_b(vid.smart_area_based, "smart-area-based", false);
param_i(vid.cells_drawn_limit, "limit on cells drawn", 10000);
param_i(vid.cells_generated_limit, "limit on cells generated", 250);
param_i(req_disksize, "disk_size")
->editable(10, 100000, 10, "disk size", "Play on a disk. Enables the special game rules for small bounded spaces (especially relevant for e.g. Minefield and Halloween). The number given is the number of tiles to use; it is not used exactly, actually the smallest disk above this size is used. Set to 0 to disable.", 'd')
->set_sets([] { dialog::bound_low(0); })
->set_reaction([] { if(game_active) { stop_game(); start_game(); } });
#if CAP_SOLV
addsaver(sn::solrange_xy, "solrange-xy");

View File

@ -1358,7 +1358,7 @@ EX void set_crystal_period_flags() {
for(auto& g: ginf)
if(g.flags & qCRYSTAL) {
set_flag(ginf[gNil].flags, qSMALL, crystal_period && crystal_period <= 8);
set_flag(ginf[gNil].flags, qBOUNDED, crystal_period);
set_flag(ginf[gNil].flags, qCLOSED, crystal_period);
}
}

View File

@ -149,7 +149,7 @@ EX namespace euc {
vector<cell*> toruscells;
vector<cell*>& allcells() override {
if(bounded) {
if(closed_manifold && !disksize) {
if(isize(toruscells) == 0) {
celllister cl(getOrigin()->c7, 1000, 1000000, NULL);
toruscells = cl.lst;
@ -634,7 +634,7 @@ EX namespace euc {
}
set_flag(ginf[g].flags, qANYQ, eu.infinite_dims < dim);
set_flag(ginf[g].flags, qBOUNDED, eu.infinite_dims == 0);
set_flag(ginf[g].flags, qCLOSED, eu.infinite_dims == 0);
set_flag(ginf[g].flags, qSMALL, eu.infinite_dims == 0 && eu.det <= 4096);
bool nonori = false;
if(eu.twisted&1) nonori = !nonori;

View File

@ -392,7 +392,7 @@ int type_in_quick(expansion_analyzer& ea, cell *c, const cellfunction& f) {
EX bool sizes_known() {
if(reg3::in_rule()) return true;
if(bounded) return false;
if(closed_manifold) return false;
// Castle Anthrax is infinite
if(bt::in()) return false;
// not implemented
@ -717,7 +717,7 @@ string produce_coef_formula(vector<int> coef) {
void expansion_analyzer::view_distances_dialog() {
static int lastticks;
if(scrolling_distances && !bounded) {
if(scrolling_distances && !closed_manifold) {
scrolltime += SDL_GetTicks() - lastticks;
first_distance += scrolltime / scrollspeed;
scrolltime %= scrollspeed;
@ -729,7 +729,7 @@ void expansion_analyzer::view_distances_dialog() {
dialog::init("");
cmode |= sm::DIALOG_STRICT_X | sm::EXPANSION;
int maxlen = bounded ? 128 : 16 + first_distance;
int maxlen = closed_manifold ? 128 : 16 + first_distance;
vector<bignum> qty(maxlen);
auto& expansion = get_expansion();
@ -748,12 +748,12 @@ void expansion_analyzer::view_distances_dialog() {
}
else {
if(distance_from == dfPlayer) {
celllister cl(cwt.at, bounded ? maxlen-1 : gamerange(), 100000, NULL);
celllister cl(cwt.at, closed_manifold ? maxlen-1 : gamerange(), 100000, NULL);
for(int d: cl.dists)
if(d >= 0 && d < maxlen) qty[d]++;
}
else {
celllister cl(cwt.at, bounded ? maxlen-1 : gamerange(), 100000, NULL);
celllister cl(cwt.at, closed_manifold ? maxlen-1 : gamerange(), 100000, NULL);
for(cell *c: cl.lst) if((not_only_descendants || is_descendant(c)) && curr_dist(c) < maxlen) qty[curr_dist(c)]++;
}
#if !CAP_GMP

View File

@ -1458,7 +1458,7 @@ EX void enableFieldChange() {
ginf[geometry].distlimit = ginf[gxcur.base].distlimit;
ginf[geometry].tiling_name = ginf[gxcur.base].tiling_name;
ginf[geometry].default_variation = ginf[gxcur.base].default_variation;
ginf[geometry].flags = qFIELD | qANYQ | qBOUNDED;
ginf[geometry].flags = qFIELD | qANYQ | qCLOSED;
fieldpattern::current_quotient_field.init(gxcur.primes[gxcur.current_prime_id].p);
}
@ -1473,7 +1473,7 @@ EX void field_from_current() {
gg.vertex = go.vertex;
gg.distlimit = go.distlimit;
gg.tiling_name = go.tiling_name;
gg.flags = go.flags | qANYQ | qFIELD | qBOUNDED;
gg.flags = go.flags | qANYQ | qFIELD | qCLOSED;
gg.g = go.g;
gg.default_variation = go.default_variation;
fieldpattern::quotient_field_changed = true;

View File

@ -760,7 +760,7 @@ EX geometry_data compute_geometry_data() {
if(euclid) gd.euler = 0;
else if(sphere && nonorientable) gd.euler = 1;
else if(sphere) gd.euler = 2;
else if(!bounded) gd.euler = -2;
else if(!closed_manifold) gd.euler = -2;
else if(WDIM == 3) gd.euler = 0;
else switch(geometry) {
case gFieldQuotient:
@ -810,7 +810,7 @@ EX geometry_data compute_geometry_data() {
gd.denom /= g;
}
if(euclid && bounded) {
if(euclid && closed_manifold) {
gd.worldsize = euc::eu.det;
if(BITRUNCATED) gd.worldsize *= (a4 ? 2 : 3);
if(GOLDBERG) gd.worldsize *= cgi.gpdata->area;
@ -821,7 +821,7 @@ EX geometry_data compute_geometry_data() {
else
gd.worldsize = gd.denom ? gd.nom / gd.denom : 0;
if(gd.euler < 0 && !bounded)
if(gd.euler < 0 && !closed_manifold)
gd.worldsize = -gd.worldsize;
string spf = its(ts);
@ -895,6 +895,7 @@ EX geometry_data compute_geometry_data() {
}
gd.size_str =
disksize ? its(isize(currentmap->allcells())) :
#if CAP_BT
bt::in() ? fts(8 * M_PI * sqrt(2) * log(2) / pow(vid.binary_width, WDIM-1), 4) + " exp(∞)" :
#endif
@ -905,10 +906,10 @@ EX geometry_data compute_geometry_data() {
#if CAP_CRYSTAL
cryst ? "∞^" + its(ts/2) :
#endif
WDIM == 3 && bounded ? its(isize(currentmap->allcells())) :
WDIM == 3 && closed_manifold ? its(isize(currentmap->allcells())) :
WDIM == 3 && euclid ? "" :
gd.worldsize < 0 ? (gd.nom%gd.denom ? its(gd.nom)+"/"+its(gd.denom) : its(-gd.worldsize)) + " exp(∞)":
(euclid && quotient && !bounded) ? "" :
(euclid && quotient && !closed_manifold) ? "" :
gd.worldsize == 0 ? "∞²" :
its(gd.worldsize);
@ -1057,8 +1058,9 @@ EX void showEuclideanMenu() {
dialog::addBreak(100);
menuitem_land_structure('l');
add_edit(req_disksize);
if(specialland == laMinefield && bounded) {
if(specialland == laMinefield && closed_or_bounded) {
dialog::addSelItem(XLAT("number of mines"), its(bounded_mine_quantity), 'm');
dialog::add_action([] {
dialog::editNumber(bounded_mine_quantity, 0, bounded_mine_max, 1, (bounded_mine_max+5)/10,
@ -1129,7 +1131,7 @@ EX void showEuclideanMenu() {
else if(viewdists) viewdists = false;
});
if(bounded) {
if(closed_manifold) {
dialog::addSelItem(XLAT("Euler characteristics"), its(gd.euler), 0);
if(WDIM == 3) ;
else if(nonorientable)

View File

@ -139,7 +139,7 @@ transmatrix hrmap_standard::relative_matrixh(heptagon *h2, heptagon *h1, const h
steps++; if(steps > 10000) {
println(hlog, "not found"); return Id;
}
if(bounded) {
if(closed_manifold) {
transmatrix T;
ld bestdist = 1e9;
for(int d=0; d<S7; d++) {
@ -817,7 +817,7 @@ EX bool exhaustive_distance_appropriate() {
if(asonov::in() && asonov::period_xy && asonov::period_xy <= 256) return true;
#endif
if(bounded) return true;
if(closed_manifold) return true;
return false;
}

View File

@ -895,7 +895,7 @@ EX namespace gp {
dialog::addBoolItem(XLAT("irregular"), IRREGULAR, 'i');
dialog::add_action(dialog::add_confirmation([=] () {
if(min_quality && !irr::bitruncations_requested) irr::bitruncations_requested++;
if(euclid && (!bounded || nonorientable)) {
if(euclid && (!closed_manifold || nonorientable)) {
println(hlog, XLAT("To create Euclidean irregular tesselations, first enable a torus"));
return;
}

View File

@ -152,11 +152,12 @@ void addMessage(string s, char spamtype = 0);
#define nonorientable (cgflags & qNONORIENTABLE)
#define elliptic (cgflags & qELLIPTIC)
#define quotient (cgflags & qANYQ)
#define smallbounded (cgflags & qSMALL)
#define bounded (cgflags & qBOUNDED)
#define smallbounded ((cgflags & qSMALL) || disksize)
#define closed_manifold (cgflags & qCLOSED)
#define closed_or_bounded (closed_manifold || disksize)
// Dry Forest burning, heat transfer, etc. are performed on the whole universe
#define doall (bounded)
#define doall (closed_or_bounded)
#define sphere_narcm (sphere && !arcm::in())

View File

@ -1045,7 +1045,7 @@ EX bool ctof(cell* c) {
}
EX bool supports(eGeometry g) {
if(g == gEuclid || g == gEuclidSquare) return ginf[g].flags & qBOUNDED;
if(g == gEuclid || g == gEuclidSquare) return ginf[g].flags & qCLOSED;
return among(g, gNormal, gKleinQuartic, gOctagon, gBolza2, gFieldQuotient, gSphere, gSmallSphere, gTinySphere);
}

View File

@ -79,7 +79,7 @@ EX void pickupMovedItems(cell *c, cell *from) {
}
EX bool in_lovasz() {
return specialland == laMotion && bounded && ls::single() && !daily::on;
return specialland == laMotion && closed_or_bounded && ls::single() && !daily::on;
}
EX int threshold_met(int i) {

View File

@ -184,7 +184,7 @@ EX int hrand_monster(int x) {
}
EX bool is_zebra_trapdoor(cell *c) {
if(euclid && bounded) return false;
if(euclid && closed_or_bounded) return false;
#if CAP_ARCM
else if(arcm::in() && arcm::current.have_line)
return arcm::linespattern(c);
@ -359,7 +359,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
}
}
}
else if(PIU(hyperbolic_not37 || (euclid&&bounded) || S7 < 5 || arcm::in() || WDIM == 3)) {
else if(PIU(hyperbolic_not37 || (euclid&&closed_or_bounded) || S7 < 5 || arcm::in() || WDIM == 3)) {
if(fargen) {
int i = hrand(100);
if(i < 10)
@ -579,7 +579,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
if(d==8) {
if(randomPatternsMode)
c->wall = RANDPAT3(0) ? waCavewall : waCavefloor;
else if(euclid && bounded) {
else if(euclid && closed_or_bounded) {
c->wall = waCavefloor;
}
else if(nil) {
@ -685,7 +685,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
#endif
else if(arb::in() && arb::current.have_line)
v = arb::linespattern(c) ? 24 : 16;
else if((euclid&&bounded) || hyperbolic_not37 || quotient || arcm::in()) {
else if((euclid&&closed_or_bounded) || hyperbolic_not37 || quotient || arcm::in()) {
v = hrand(100) < 25 ? 24 : 16;
}
else if(euclid) {
@ -760,7 +760,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
if(d==8) {
if(randomPatternsMode)
c->wall = RANDPAT ? waVinePlant : waNone;
else if(euclid && bounded) ;
else if(euclid && closed_or_bounded) ;
#if CAP_ARCM
else if(arcm::in() && arcm::current.have_line)
c->wall = arcm::linespattern(c) ? waVinePlant : waNone;
@ -1269,50 +1269,6 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
break;
case laHalloween:
if(fargen) {
if(GOLDBERG) {
int fv = c->master->fiftyval;
if(fv == 1 || fv == 4 || fv == 10)
c->wall = waChasm;
if(c == c->master->c7 && fv == 3)
c->item = itTreat;
}
else if(!BITRUNCATED && !euclid) {
int fv = c->master->fiftyval;
if(fv == 1 || fv == 4 || fv == 2)
c->wall = waChasm;
if(fv == 3) c->item = itTreat;
}
else {
if(c->type == 5) {
int fv = c->master->fiftyval;
if(fv == 3 || fv == 4 || fv == 2 || fv == 5)
c->wall = waChasm;
if(fv == 2) halloween::dragoncells[0] = c;
if(fv == 5) halloween::dragoncells[3] = c;
if(fv == 1) c->item = itTreat;
}
if(c->type == 6 && !euclid) {
int fvset = 0;
for(int i=0; i<6; i+=2) fvset |= 1 << createMov(c, i)->master->fiftyval;
if(fvset == 35 || fvset == 7) c->wall = waChasm;
if(fvset == 7) halloween::dragoncells[1] = c;
if(fvset == 35) halloween::dragoncells[2] = c;
}
}
if(quotient && zebra40(c) == 7) {
c->item = itTreat;
halloween::dragoncells[0] = NULL;
}
if(quotient && zebra40(c) == 5) {
c->wall = waChasm;
}
if(euclid && bounded) {
int i = hrand(100);
if(i == 0) c->item = itTreat;
else if(i < 5) c->wall = waChasm;
}
}
break;
case laWildWest:
@ -2158,7 +2114,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
break;
case laMinefield:
if(d == 7 && bounded) c->wall = waMineUnknown;
if(d == 7 && closed_or_bounded) c->wall = waMineUnknown;
else if(d == 7) {
c->wall = waMineUnknown;
// 250: rare mines
@ -2191,7 +2147,7 @@ EX void giantLandSwitch(cell *c, int d, cell *from) {
c->monst = moBomberbird;
else placeLocalSpecial(c, 500);
}
if(d == 3 && safety && (c->wall == waMineMine || c->wall == waMineUnknown) && !bounded)
if(d == 3 && safety && (c->wall == waMineMine || c->wall == waMineUnknown) && !closed_or_bounded)
c->wall = waMineOpen;
break;
@ -2879,7 +2835,7 @@ EX void set_land_for_geometry(cell *c) {
else if(euc::in(3)) euc::set_land(c);
#endif
else if(hybri) setLandHybrid(c);
else if(sphere || (euclid && bounded)) setLandSphere(c);
else if(sphere || (euclid && closed_or_bounded)) setLandSphere(c);
else if(euclid) setLandEuclid(c);
else if(quotient) { setland(c, specialland); setLandQuotient(c); }
else if(sol) setLandSol(c);
@ -3058,6 +3014,13 @@ EX void setdist(cell *c, int d, cell *from) {
}
}
if(disksize && !is_in_disk(c)) {
setland(c, laMemory);
if(!isMultitile(c)) c->monst = moNone;
c->item = itNone;
c->wall = waChasm;
}
ONEMPTY if(!c->item) {
if(isCrossroads(c->land))
placeCrossroadOrbs(c);

View File

@ -139,7 +139,7 @@ EX string land_structure_name(bool which) {
}
EX void fix_land_structure_choice() {
if(bounded) {
if(closed_or_bounded) {
if(land_structure != lsTotalChaos && land_structure != lsChaosRW)
land_structure = lsSingle;
}
@ -155,7 +155,7 @@ EX void fix_land_structure_choice() {
land_structure = lsSingle;
if(land_structure == lsPatchedChaos && !(stdeuc || nil || cryst || (euclid && WDIM == 3)))
land_structure = lsSingle;
if(bounded && !among(land_structure, lsChaosRW, lsTotalChaos, lsSingle))
if(closed_or_bounded && !among(land_structure, lsChaosRW, lsTotalChaos, lsSingle))
land_structure = lsSingle;
}
@ -777,12 +777,12 @@ EX land_validity_t& land_validity(eLand l) {
return disabled;
#endif
if(l == laMinefield && bounded)
if(l == laMinefield && closed_or_bounded)
return special_geo3;
if(l == laAsteroids) {
if(!shmup::on) return shmup_only;
if(!bounded) return bounded_only;
if(!closed_manifold) return bounded_only;
return specially_designed;
}
@ -901,7 +901,7 @@ EX land_validity_t& land_validity(eLand l) {
return not_implemented;
// Halloween needs bounded world (can be big bounded)
if(l == laHalloween && !bounded)
if(l == laHalloween && !closed_or_bounded)
return bounded_only;
// Crystal World is designed for nice_dual geometries
@ -960,7 +960,7 @@ EX land_validity_t& land_validity(eLand l) {
if(geometry == gBinary4)
return not_implemented;
// no equidistants supported in these geometries (big sphere is OK though)
if(bounded && !bigsphere)
if(closed_or_bounded && !bigsphere)
return unbounded_only_except_bigsphere;
// Yendorian only implemented in standard
if(l == laEndorian && geometry)
@ -1004,7 +1004,7 @@ EX land_validity_t& land_validity(eLand l) {
if(l == laClearing)
if(!(stdeucx || geometry == gBinaryTiling || a38 || (a45 && BITRUNCATED) || (a47 && BITRUNCATED)) || NONSTDVAR)
if(!bounded)
if(!closed_or_bounded)
return not_implemented;
// does not work in non-bitrunc a4
@ -1012,7 +1012,7 @@ EX land_validity_t& land_validity(eLand l) {
return some0;
// does not work in bounded either
if(l == laOvergrown && bounded)
if(l == laOvergrown && closed_or_bounded)
return some0;
// horocycle-based lands, not available in bounded geometries nor in Chaos mode
@ -1023,7 +1023,7 @@ EX land_validity_t& land_validity(eLand l) {
return not_in_chaos;
}
if(arcm::in() || kite::in()) return not_implemented;
if(bounded) return unbounded_only;
if(closed_or_bounded) return unbounded_only;
if(INVERSE) return not_implemented;
}
@ -1064,7 +1064,7 @@ EX land_validity_t& land_validity(eLand l) {
return technical;
// only in bounded geometry, and not in PTM
if(l == laCA && !bounded)
if(l == laCA && !closed_or_bounded)
return bounded_only;
if(l == laCA && tactic::on)
@ -1121,7 +1121,7 @@ EX land_validity_t& land_validity(eLand l) {
if(l == laStorms && hyperbolic_not37)
return pattern_not_implemented_random;
if(l == laTrollheim && !stdeucx && !bounded)
if(l == laTrollheim && !stdeucx && !closed_or_bounded)
return some1;
if(l == laReptile && sol) return ugly_version_nofull;
@ -1174,7 +1174,7 @@ EX land_validity_t& land_validity(eLand l) {
if(l == laPrairie) {
if(GOLDBERG) return not_implemented;
else if(stdeucx || (bigsphere && BITRUNCATED && !elliptic) || (geometry == gFieldQuotient)) ;
else if(!bounded) return not_implemented;
else if(!closed_or_bounded) return not_implemented;
else return unbounded_only;
}
@ -1191,10 +1191,10 @@ EX land_validity_t& land_validity(eLand l) {
if(sol && l == laCamelot)
return not_implemented;
if(euclid && quotient && !bounded && l == laCrossroads && euc::sdxy().second == -2 * euc::sdxy().first)
if(euclid && quotient && !closed_or_bounded && l == laCrossroads && euc::sdxy().second == -2 * euc::sdxy().first)
return full_game;
if(euclid && quotient && !bounded && l == laCrossroads4 && euc::sdxy().second == 0)
if(euclid && quotient && !closed_or_bounded && l == laCrossroads4 && euc::sdxy().second == 0)
return full_game;
// highlight Zebra-based lands on Zebra Quotient!
@ -1231,7 +1231,7 @@ EX land_validity_t& land_validity(eLand l) {
return pattern_not_implemented_exclude;
}
if(l == laStorms && euclid && bounded)
if(l == laStorms && euclid && closed_manifold)
return interesting;
if(l == laMagnetic)

View File

@ -684,7 +684,7 @@ EX namespace mapstream {
EX hookset<void(fhstream&, int)> hooks_loadmap;
EX cell *save_start() {
return (bounded || euclid || prod || arcm::in() || sol || INVERSE) ? currentmap->gamestart() : cwt.at->master->c7;
return (closed_manifold || euclid || prod || arcm::in() || sol || INVERSE) ? currentmap->gamestart() : cwt.at->master->c7;
}
#if CAP_EDIT

View File

@ -770,9 +770,9 @@ EX bool makeEmpty(cell *c) {
c->wall = waBoat; // , c->item = itOrbYendor;
else if(c->land == laMinefield)
c->wall = waMineOpen;
else if(c->wall == waFan && bounded)
else if(c->wall == waFan && closed_manifold)
;
else if(c->wall == waOpenPlate && bounded)
else if(c->wall == waOpenPlate && closed_manifold)
;
else if(c->wall == waTrunk || c->wall == waSolidBranch || c->wall == waWeakBranch)
;
@ -786,13 +786,13 @@ EX bool makeEmpty(cell *c) {
;
else if(c->land == laDocks)
c->wall = waBoat;
else if(c->wall == waFreshGrave && bounded)
else if(c->wall == waFreshGrave && closed_manifold)
;
else if(c->wall == waBarrier && sphere && WDIM == 3)
;
else if(isReptile(c->wall))
c->wparam = reptilemax();
else if(c->wall == waAncientGrave && bounded)
else if(c->wall == waAncientGrave && closed_manifold)
;
else if(c->wall != waRoundTable)
c->wall = waNone;

View File

@ -704,7 +704,7 @@ EX void mode_higlights() {
}
EX eLandStructure default_land_structure() {
if(bounded) return lsSingle;
if(closed_or_bounded) return lsSingle;
if(tactic::on || princess::challenge) return lsSingle;
if(yendor::on) return yendor::get_land_structure();
if(specialland == laCanvas) return lsSingle;
@ -1171,7 +1171,7 @@ EX named_functionality get_o_key() {
dialog::infix = "";
if((geometry != gNormal || NONSTDVAR) && !daily::on)
if((geometry != gNormal || NONSTDVAR || disksize) && !daily::on)
res.push_back(named_functionality(XLAT("experiment with geometry"), runGeometryExperiments));
if(res.empty()) return named_dialog(XLAT("world overview"), showOverview);

View File

@ -335,18 +335,20 @@ EX void wandering() {
if(cwt.at->land == laCA) ghostcount = 0;
bool genturn = hrand(100) < 30;
if(bounded && specialland == laClearing)
if(closed_or_bounded && specialland == laClearing)
clearing::new_root();
if(cwt.at->land == laZebra && cwt.at->wall == waNone && wchance(items[itZebra], 20))
wanderingZebra(cwt.at);
bool smallbounded_generation = smallbounded || (bounded && specialland == laClearing);
bool smallbounded_generation = smallbounded || (closed_manifold && specialland == laClearing);
auto valid = [] (cell *c) { if(disksize && !is_in_disk(c)) return false; if(inmirror(c)) return false; return true; };
if(smallbounded_generation) {
int maxdist = 0;
for(int i=0; i<isize(dcal); i++) if(dcal[i]->cpdist > maxdist) maxdist = dcal[i]->cpdist;
for(int i=0; i<isize(dcal); i++) if(dcal[i]->cpdist >= maxdist-1) { first7 = i; break; }
for(int i=0; i<isize(dcal); i++) if(valid(dcal[i])) if(dcal[i]->cpdist > maxdist) maxdist = dcal[i]->cpdist;
for(int i=0; i<isize(dcal); i++) if(valid(dcal[i])) if(dcal[i]->cpdist >= maxdist-1) { first7 = i; break; }
if(hrand(5) == 0) {
// spawn treasure
@ -362,10 +364,12 @@ EX void wandering() {
}
}
int iter = 0;
while(first7 < isize(dcal)) {
iter++; if(iter > 1000) break;
int i = first7 + hrand(isize(dcal) - first7);
cell *c = dcal[i];
if(inmirror(c)) continue;
if(!valid(c)) continue;
if(isPlayerOn(c)) break;
if(specialland == laStorms) {

View File

@ -1393,7 +1393,7 @@ EX void movehex_rest(bool mounted) {
EX void movemutant() {
manual_celllister mcells;
for(cell *c: currentmap->allcells()) mcells.add(c);
if(!bounded)
if(!closed_or_bounded)
for(int i=0; i<isize(mcells.lst); i++) {
cell *c = mcells.lst[i];
if(c->land == laClearing && c->monst != moMutant && !pseudohept(c))
@ -1427,7 +1427,7 @@ EX void movemutant() {
if(isPlayerOn(c2)) continue;
if((c2->land == laOvergrown || !pseudohept(c2)) && passable(c2, c, 0)) {
if(c2->land == laClearing && !bounded && c2->mpdist > 7) continue;
if(c2->land == laClearing && !closed_or_bounded && c2->mpdist > 7) continue;
c2->monst = moMutant;
c2->mondir = c->c.spin(j);
c2->stuntime = mutantphase;
@ -2096,7 +2096,7 @@ EX void movemonsters() {
DEBB(DF_TURN, ("leader"));
if(havewhat & HF_LEADER) groupmove(moPirate, 0);
DEBB(DF_TURN, ("mutant"));
if((havewhat & HF_MUTANT) || (bounded && among(specialland, laOvergrown, laClearing))) movemutant();
if((havewhat & HF_MUTANT) || (closed_or_bounded && among(specialland, laOvergrown, laClearing))) movemutant();
DEBB(DF_TURN, ("bugs"));
if(havewhat & HF_BUG) hive::movebugs();
DEBB(DF_TURN, ("whirlpool"));

View File

@ -962,7 +962,7 @@ EX namespace nilv {
int coords = 0;
for(int a=0; a<3; a++) if(nilperiod[a]) coords++;
set_flag(ginf[gNil].flags, qANYQ, coords);
set_flag(ginf[gNil].flags, qBOUNDED, coords == 3);
set_flag(ginf[gNil].flags, qCLOSED, coords == 3);
set_flag(ginf[gNil].flags, qSMALL, coords == 3 && nilperiod[0] * nilperiod[1] * nilperiod[2] <= 4096);
}
@ -1229,7 +1229,7 @@ EX namespace hybrid {
EX void fix_bounded_cycles() {
if(!rotspace) return;
if(!bounded) return;
if(!closed_manifold) return;
in_underlying([&] {
cellwalker final(currentmap->gamestart(), 0);
auto& ac = currentmap->allcells();
@ -1505,7 +1505,7 @@ EX namespace hybrid {
dialog::extra_options = [=] () {
if(rotspace) {
int e_steps = cgi.psl_steps / gcd(cgi.single_step, cgi.psl_steps);
bool ubounded = PIU(bounded);
bool ubounded = PIU(closed_manifold);
dialog::addSelItem( sphere ? XLAT("elliptic") : XLAT("PSL(2,R)"), its(e_steps), 'P');
dialog::add_action(set_s(e_steps, true));
dialog::addSelItem( sphere ? XLAT("sphere") : XLAT("SL(2,R)"), its(2*e_steps), 'P');

View File

@ -441,12 +441,12 @@ EX int fieldval_uniq(cell *c) {
}
else if(euc::in(2)) {
auto p = euc2_coordinates(c);
if(bounded) return p.first + p.second * (1 << 16);
if(closed_manifold) return p.first + p.second * (1 << 16);
return gmod(p.first - 22 * p.second, 3*127);
}
else if(euc::in(3)) {
auto co = euc::get_ispacemap()[c->master];
if(bounded) return co[0] + (co[1] << 10) + (co[2] << 20);
if(closed_manifold) return co[0] + (co[1] << 10) + (co[2] << 20);
return gmod(co[0] + 3 * co[1] + 9 * co[2], 3*127);
}
else if(bt::in() || arcm::in() || nil || S3 >= OINF || (cgflags & qIDEAL)) return 0;
@ -1604,7 +1604,7 @@ EX namespace patterns {
color_t nearer_map(cell *c) {
if(computed_nearer_map.count(c)) return computed_nearer_map[c];
if(!bounded) return 0;
if(!closed_manifold) return 0;
cell *sc = currentmap->gamestart();
auto ac = currentmap->allcells();
@ -1645,7 +1645,7 @@ EX namespace patterns {
color_t furthest_map(cell *c, int reduce) {
auto& cfm = computed_furthest_map;
if(cfm.count(c)) return cfm[c];
if(!bounded) return 0;
if(!closed_manifold) return 0;
cell *sc = currentmap->gamestart();
auto ac = currentmap->allcells();
@ -2031,7 +2031,7 @@ EX namespace patterns {
dialog::addSelItem(XLAT("Penrose staircase"), "Nil", '/');
}
if(bounded) {
if(closed_manifold) {
dialog::addSelItem(XLAT("nearer end"), "bounded", 'Z');
dialog::addSelItem(XLAT("furthest from start"), "bounded", 'Y');
}

View File

@ -371,7 +371,7 @@ EX void showMission() {
}
dialog::addInfo(XLAT("Dropped floors: %1/%2", its(score), its(all)));
if(score == all) dialog::addInfo(XLAT("CONGRATULATIONS!"), iinf[itOrbYendor].color);
if(score == all && geometry == gKleinQuartic && variation == eVariation::untruncated && gp::param == gp::loc(1,1))
if(score == all && geometry == gKleinQuartic && variation == eVariation::untruncated && gp::param == gp::loc(1,1) && !disksize)
achievement_gain_once("LOVASZ", rg::special_geometry);
}
else {

View File

@ -475,7 +475,7 @@ EX void generate_track() {
}
try {
if(bounded && !prod && !(cgflags & qHUGE_BOUNDED)) {
if(closed_or_bounded && !prod && !(cgflags & qHUGE_BOUNDED)) {
bounded_track = true;
make_bounded_track(s);
}
@ -754,7 +754,7 @@ bool inrec = false;
EX ld race_angle = 90;
EX bool force_standard_centering() {
return nonisotropic || hybri || quotient || bounded;
return nonisotropic || hybri || quotient || closed_or_bounded;
}
EX bool use_standard_centering() {

View File

@ -490,7 +490,7 @@ void explore() {
ginf[gArbitrary].g = giEuclid2;
ginf[gArbitrary].sides = 7;
set_flag(ginf[gArbitrary].flags, qBOUNDED, true);
set_flag(ginf[gArbitrary].flags, qCLOSED, true);
set_flag(ginf[gArbitrary].flags, qAFFINE, false);
geom3::apply_always3();

View File

@ -503,8 +503,8 @@ bool drawVertex(const shiftmatrix &V, cell *c, shmup::monster *m) {
}
void init() {
if(!bounded) {
addMessage("Flocking simulation needs a bounded space.");
if(!closed_manifold) {
addMessage("Flocking simulation needs a closed manifold.");
return;
}
stop_game();

View File

@ -126,7 +126,7 @@ void create_janko() {
gJanko1 = eGeometry(isize(ginf) - 1);
// variation = eVariation::pure;
auto& gi = ginf.back();
gi.flags = qANYQ | qBOUNDED | qEXPERIMENTAL;
gi.flags = qANYQ | qCLOSED | qEXPERIMENTAL;
gi.quotient_name = "Janko";
gi.shortname = "Janko";
gi.menu_displayed_name = "Janko group J1";

View File

@ -1148,7 +1148,7 @@ void create_notknot() {
}
else ginf[gNotKnot] = ginf[base];
auto& gi = ginf.back();
gi.flags |= qANYQ | qBOUNDED | qEXPERIMENTAL | qPORTALSPACE;
gi.flags |= qANYQ | qCLOSED | qEXPERIMENTAL | qPORTALSPACE;
gi.quotient_name = "notknot";
gi.shortname = "notknot";
gi.menu_displayed_name = "notknot";

View File

@ -602,7 +602,7 @@ bool drawVertex(const shiftmatrix &V, cell *c, shmup::monster *m) {
bool multidraw = quotient;
bool use_brm = bounded && isize(currentmap->allcells()) <= brm_limit;
bool use_brm = closed_or_bounded && isize(currentmap->allcells()) <= brm_limit;
if(!lshiftclick) for(int j=0; j<isize(vd.edges); j++) {
edgeinfo *ei = vd.edges[j].second;

View File

@ -63,7 +63,7 @@ namespace sag {
int snakedist(int i, int j) {
if(i < insnaketab && j < insnaketab) return sdist[i][j];
if(bounded) return celldistance(snakecells[i], snakecells[j]);
if(closed_manifold) return celldistance(snakecells[i], snakecells[j]);
int i0 = i, i1 = i, j0 = j, j1 = j;
int cost = 0;
// intersect
@ -77,7 +77,7 @@ namespace sag {
}
void initSnake(int n) {
if(bounded) n = isize(currentmap->allcells());
if(closed_or_bounded) n = isize(currentmap->allcells());
numsnake = n;
snakecells.resize(numsnake);
snakefirst.resize(numsnake);
@ -85,7 +85,7 @@ namespace sag {
snakenode.resize(numsnake);
lpbak.resize(numsnake);
wpbak.resize(numsnake);
if(bounded) {
if(closed_or_bounded) {
for(int i=0; i<n; i++) {
cellwalker cw(currentmap->allcells()[i], 0);
setsnake(cw, i);

View File

@ -183,7 +183,7 @@ EX rugpoint *addRugpoint(shiftpoint h, double dist) {
m->y1 = (1 - onscreen[1] * pconf.scale) / 2;
m->valid = false;
if(euclid && quotient && !bounded) {
if(euclid && quotient && !closed_manifold) {
hyperpoint h1 = iso_inverse(models::euclidean_spin) * eumove(euc::eu.user_axes[1]) * C0;
h1 /= sqhypot_d(2, h1);
if(nonorientable) h1 /= 2;
@ -557,7 +557,7 @@ EX void buildRug() {
need_mouseh = true;
good_shape = false;
#if MAXMDIM >= 4
if(euclid && bounded) {
if(euclid && closed_manifold) {
good_shape = true;
buildTorusRug();
return;
@ -785,7 +785,7 @@ EX int precision_increases;
bool stop = false;
EX bool subdivide_further() {
if(euclid && bounded) return false;
if(euclid && closed_manifold) return false;
if(GDIM == 3) return false;
return isize(points) * 4 < vertex_limit;
}
@ -794,7 +794,7 @@ EX void subdivide() {
int N = isize(points);
// if(euclid && gwhere == gEuclid) return;
if(!subdivide_further()) {
if(euclid && !bounded && gwhere == gEuclid) {
if(euclid && !closed_manifold && gwhere == gEuclid) {
println(hlog, "Euclidean -- full precision");
stop = true;
}

View File

@ -346,11 +346,14 @@ EX void initgame() {
makeEmpty(cwt.at);
}
if(specialland == laMinefield && bounded) {
if(specialland == laMinefield && closed_or_bounded) {
bfs();
generate_mines();
}
if(specialland == laHalloween)
halloween::generate();
if(in_lovasz()) {
cwt.at->item = itOrbInvis;
}
@ -1455,7 +1458,7 @@ EX void switch_game_mode(char switchWhat) {
if(tactic::on) firstland = laIce;
yendor::on = tactic::on = princess::challenge = false;
land_structure = ls::any_chaos() ? lsNiceWalls : lsChaos;
if(bounded) set_geometry(gNormal);
if(closed_or_bounded) set_geometry(gNormal);
racing::on = false;
break;
@ -1570,6 +1573,7 @@ EX void start_game() {
#endif
initcells();
get_expansion().reset();
init_disk_cells();
if(randomPatternsMode) {
for(int i=0; i<landtypes; i++) {

View File

@ -1234,7 +1234,7 @@ EX namespace peace {
reset_modes();
if(peace::on) stop_game_and_switch_mode(rg::peace);
specialland = firstland = laMinefield;
if(!bounded) {
if(!closed_or_bounded) {
geometry = gBring;
variation = eVariation::goldberg;
gp::param = gp::loc(2, 1);