mine adjacency rule can be changed (in 2D for now)

This commit is contained in:
Zeno Rogue 2019-04-08 14:58:54 +02:00
parent 8a53258361
commit 9b7ad345a9
3 changed files with 46 additions and 10 deletions

View File

@ -7352,6 +7352,28 @@ void knightFlavorMessage(cell *c2) {
msgid++;
}
int mine_adjacency_rule = 0;
vector<cell*> adj_minefield_cells(cell *c) {
vector<cell*> res;
if(mine_adjacency_rule == 0 || (VALENCE == 3 && DIM == 2))
forCellCM(c2, c) res.push_back(c2);
else if(DIM == 2) {
cellwalker cw(c, 0);
cw += wstep;
cw++;
cellwalker cw1 = cw;
do {
res.push_back(cw.at);
cw += wstep;
cw++;
if(cw.cpeek() == c) cw++;
}
while(cw != cw1);
}
return res;
}
bool uncoverMines(cell *c, int lev, int dist, bool just_checking) {
bool b = false;
if(c->wall == waMineMine && just_checking) return true;
@ -7367,21 +7389,23 @@ bool uncoverMines(cell *c, int lev, int dist, bool just_checking) {
bool minesNearby = false;
bool nominesNearby = false;
bool mineopens = false;
auto adj = adj_minefield_cells(c);
forCellEx(c2, c) {
for(cell *c2: adj) {
if(c2->wall == waMineMine) minesNearby = true;
if(c2->wall == waMineOpen) mineopens = true;
if(c2->wall == waMineUnknown && !c2->item) nominesNearby = true;
}
if(lev && (nominesNearby || mineopens) && !minesNearby) for(int i=0; i<c->type; i++)
if(c->move(i) && (c->move(i)->wall == waMineUnknown || c->move(i)->wall == waMineOpen)) {
b |= uncoverMines(c->move(i), lev-1, dist+1, just_checking);
if(lev && (nominesNearby || mineopens) && !minesNearby) for(cell *c2: adj)
if(c2->wall == waMineUnknown || c2->wall == waMineOpen) {
b |= uncoverMines(c2, lev-1, dist+1, just_checking);
if(b && just_checking) return true;
}
if(minesNearby && !nominesNearby && dist == 0) {
forCellEx(c2, c)
for(cell *c2: adj)
if(c2->wall == waMineMine && c2->land == laMinefield)
c2->landparam |= 1;
}

View File

@ -695,6 +695,15 @@ void showEuclideanMenu() {
};
});
}
if(specialland == laMinefield && (DIM == 3 || VALENCE != 3)) {
dialog::addSelItem(XLAT("mine adjacency rule"), XLAT(mine_adjacency_rule ? "vertex" : DIM == 3 ? "face" : "edge"), 'M');
dialog::add_action([] {
stop_game();
mine_adjacency_rule = !mine_adjacency_rule;
start_game();
});
}
dialog::addBoolItem(XLAT("pattern"), specialland == laCanvas, 'p');
if(specialland == laCanvas) dialog::lastItem().value = patterns::whichCanvas;
@ -838,6 +847,9 @@ int read_geom_args() {
currfp.findsubpath();
}
#endif
else if(argis("-mineadj")) {
shift(); mine_adjacency_rule = argi();
}
else if(argis("-tpar")) {
torusconfig::torus_mode = torusconfig::tmSingle;
shift(); sscanf(argcs(), "%d,%d,%d",

View File

@ -2741,8 +2741,8 @@ const char* minetexts[8] = {
int countMinesAround(cell *c) {
int mines = 0;
for(int i=0; i<c->type; i++)
if(c->move(i) && c->move(i)->wall == waMineMine)
for(cell *c2: adj_minefield_cells(c))
if(c2->wall == waMineMine)
mines++;
return mines;
}
@ -6544,10 +6544,10 @@ void drawscreen() {
mines[p] = 0;
cell *c = playerpos(p);
if(!c) continue;
for(int i=0; i<c->type; i++) if(c->move(i)) {
if(c->move(i)->land == laMinefield)
for(cell *c2: adj_minefield_cells(c)) {
if(c2->land == laMinefield)
minefieldNearby = true;
if(c->move(i)->wall == waMineMine) {
if(c2->wall == waMineMine) {
bool ep = false;
if(!ep) mines[p]++, tmines++;
}