diff options
| author | Ben Harris <bjh21@bjh21.me.uk> | 2023-02-10 18:28:36 +0000 |
|---|---|---|
| committer | Ben Harris <bjh21@bjh21.me.uk> | 2023-02-10 18:32:00 +0000 |
| commit | ad2fb760fc881d1ceb1ac1151bf60b85deb16c71 (patch) | |
| tree | 4e13a17cda234eb61aa1e398965af2f656a86bec | |
| parent | bf9abb2a127a4a81babe50ecb419527f8aeffe28 (diff) | |
| download | puzzles-ad2fb760fc881d1ceb1ac1151bf60b85deb16c71.zip puzzles-ad2fb760fc881d1ceb1ac1151bf60b85deb16c71.tar.gz puzzles-ad2fb760fc881d1ceb1ac1151bf60b85deb16c71.tar.bz2 puzzles-ad2fb760fc881d1ceb1ac1151bf60b85deb16c71.tar.xz | |
Forbid game descriptions with joined islands in Bridges
A game description with islands in adjacent grid squares, like
"3x3:11g", shouldn't be allowed. If it is, then bridges between the
islands are invisible and clicking one of them causes an assertion
failure: "Assertion `is_loop->adj.points[j].off > 1' failed."
The code to check this is really rather complex, but I think the
complexity is mostly necessary.
| -rw-r--r-- | bridges.c | 27 |
1 files changed, 20 insertions, 7 deletions
@@ -2007,21 +2007,34 @@ generated: static const char *validate_desc(const game_params *params, const char *desc) { - int i, wh = params->w * params->h, nislands = 0; + int i, j, wh = params->w * params->h, nislands = 0; + bool *last_row = snewn(params->w, bool); + memset(last_row, 0, params->w * sizeof(bool)); for (i = 0; i < wh; i++) { - if (*desc >= '1' && *desc <= '9') + if ((*desc >= '1' && *desc <= '9') || (*desc >= 'A' && *desc <= 'G')) { nislands++; - else if (*desc >= 'a' && *desc <= 'z') + /* Look for other islands to the left and above. */ + if ((i % params->w > 0 && last_row[i % params->w - 1]) || + last_row[i % params->w]) { + sfree(last_row); + return "Game description contains joined islands"; + } + last_row[i % params->w] = true; + } else if (*desc >= 'a' && *desc <= 'z') { + for (j = 0; j < *desc - 'a' + 1; j++) + last_row[(i + j) % params->w] = false; i += *desc - 'a'; /* plus the i++ */ - else if (*desc >= 'A' && *desc <= 'G') - nislands++; - else if (!*desc) + } else if (!*desc) { + sfree(last_row); return "Game description shorter than expected"; - else + } else { + sfree(last_row); return "Game description contains unexpected character"; + } desc++; } + sfree(last_row); if (*desc || i > wh) return "Game description longer than expected"; if (nislands < 2) |