Gather data
This commit is contained in:
@@ -30,7 +30,12 @@ public record SwedishGenerator(int[] buff) {
|
||||
|
||||
record nbrs_8(int r, int c) { }
|
||||
|
||||
record nbrs_16(int r, int c, int dr, int dc) { }
|
||||
record nbrs_16(int r, int c, int dr, int dc, int d, byte dbyte) {
|
||||
|
||||
public nbrs_16(int r, int c, int dr, int dc, int d) {
|
||||
this(r, c, dr, dc, d, (byte) (48 + d));
|
||||
}
|
||||
}
|
||||
|
||||
static final int C = Config.PUZZLE_COLS;
|
||||
static final double CROSS_Y = (C - 1) / 2.0;
|
||||
@@ -54,12 +59,12 @@ public record SwedishGenerator(int[] buff) {
|
||||
// Directions for '1'..'6'
|
||||
static final nbrs_16[] OFFSETS = new nbrs_16[]{
|
||||
null,
|
||||
new nbrs_16(-1, 0, -1, 0), // 1: up
|
||||
new nbrs_16(0, 1, 0, 1), // 2: right
|
||||
new nbrs_16(1, 0, 1, 0),// 3: down
|
||||
new nbrs_16(0, -1, 0, -1),// 4: left
|
||||
new nbrs_16(0, -1, 1, 0),// 5: vertical down, clue is on the right of the first letter
|
||||
new nbrs_16(0, 1, 1, 0)// 6: vertical down, clue is on the left of the first letter
|
||||
new nbrs_16(-1, 0, -1, 0, 1), // 1: up
|
||||
new nbrs_16(0, 1, 0, 1, 2), // 2: right
|
||||
new nbrs_16(1, 0, 1, 0, 3),// 3: down
|
||||
new nbrs_16(0, -1, 0, -1, 4),// 4: left
|
||||
new nbrs_16(0, -1, 1, 0, 5),// 5: vertical down, clue is on the right of the first letter
|
||||
new nbrs_16(0, 1, 1, 0, 6)// 6: vertical down, clue is on the left of the first letter
|
||||
};
|
||||
final static nbrs_8[] nbrs8 = new nbrs_8[]{
|
||||
new nbrs_8(-1, -1),
|
||||
@@ -110,6 +115,11 @@ public record SwedishGenerator(int[] buff) {
|
||||
x = y;
|
||||
return y;
|
||||
}
|
||||
byte randbyte(int min, int max) {
|
||||
var u = (nextU32() & 0xFFFFFFFFL);
|
||||
var range = (long) max - (long) min + 1L;
|
||||
return (byte) (min + (u % range));
|
||||
}
|
||||
int randint(int min, int max) {
|
||||
var u = (nextU32() & 0xFFFFFFFFL);
|
||||
var range = (long) max - (long) min + 1L;
|
||||
@@ -118,18 +128,22 @@ public record SwedishGenerator(int[] buff) {
|
||||
double nextFloat() { return (nextU32() & 0xFFFFFFFFL) / 4294967295.0; }
|
||||
}
|
||||
|
||||
static final byte _48 = 48;
|
||||
|
||||
record Grid(byte[] g) {
|
||||
|
||||
int digitAt(int r, int c) { return g[offset(r, c)] - 48; }
|
||||
public static int r(int offset) { return offset & 7; }
|
||||
public static int c(int offset) { return offset >>> 3; }
|
||||
static int offset(int r, int c) { return r | (c << 3); }
|
||||
Grid deepCopyGrid() { return new Grid(g.clone()); }
|
||||
char getCharAt(int r, int c) { return (char) (g[offset(r, c)]); }
|
||||
char getCharAt(int pos) { return (char) (g[pos]); }
|
||||
int digitAt(int r, int c) { return g[offset(r, c)] - 48; }
|
||||
byte byteAt(int r, int c) { return g[offset(r, c)]; }
|
||||
byte byteAt(int pos) { return g[pos]; }
|
||||
byte byteAtStatic(int r, int c) { return g[offset(r, c)]; }
|
||||
void setCharAt(int r, int c, char ch) { g[offset(r, c)] = (byte) ch; }
|
||||
void setByteAt(int r, int c, byte ch) { g[offset(r, c)] = ch; }
|
||||
void setDigitAt(int r, int c, int ch) { g[offset(r, c)] = (byte) (_48 + ch); }
|
||||
void setCharAt(int idx, char ch) { g[idx] = (byte) ch; }
|
||||
void setByteAt(int idx, byte ch) { g[idx] = ch; }
|
||||
void clear(int r, int c) { g[offset(r, c)] = 0; }
|
||||
@@ -391,7 +405,17 @@ public record SwedishGenerator(int[] buff) {
|
||||
forEachSlot(grid, (key, packedPos, len) -> slots.add(Slot.from(key, packedPos, len)));
|
||||
return slots;
|
||||
}
|
||||
|
||||
boolean hasRoomForClue(Grid grid, int idx, nbrs_16 nbrs16) {
|
||||
int rr = Grid.r(idx) + nbrs16.r, cc = Grid.c(idx) + nbrs16.c;
|
||||
var run = 0;
|
||||
while (rr >= 0 && rr < R && cc >= 0 && cc < C && (grid.isLettercell(rr, cc)) && run < MAX_WORD_LENGTH) {
|
||||
run++;
|
||||
rr += nbrs16.dr;
|
||||
cc += nbrs16.dc;
|
||||
if (run >= MIN_LEN) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
boolean hasRoomForClue(Grid grid, int r, int c, char d) {
|
||||
var nbrs16 = OFFSETS[d - '0'];
|
||||
int rr = r + nbrs16.r, cc = c + nbrs16.c;
|
||||
@@ -516,7 +540,25 @@ public record SwedishGenerator(int[] buff) {
|
||||
}
|
||||
|
||||
// ---------------- Mask generation ----------------
|
||||
|
||||
Grid randomMask2(Rng rng) {
|
||||
var g = makeEmptyGrid();
|
||||
|
||||
int placed = 0, guard = 0;
|
||||
|
||||
while (placed < TARGET_CLUES && guard++ < 4000) {
|
||||
var idx = rng.randint(0, SIZE - 1);
|
||||
if (g.isDigitAt(idx)) continue;
|
||||
|
||||
var d = OFFSETS[rng.randbyte(1, 4)];
|
||||
g.setByteAt(idx, d.dbyte);
|
||||
if (!hasRoomForClue(g, idx, d)) {
|
||||
g.clear(idx);
|
||||
continue;
|
||||
}
|
||||
placed++;
|
||||
}
|
||||
return g;
|
||||
}
|
||||
Grid randomMask(Rng rng) {
|
||||
var g = makeEmptyGrid();
|
||||
var targetClues = (int) Math.round(SIZE * 0.25);
|
||||
@@ -537,7 +579,26 @@ public record SwedishGenerator(int[] buff) {
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
Grid mutate2(Rng rng, Grid grid) {
|
||||
var g = grid.deepCopyGrid();
|
||||
var cx = rng.randint(0, R - 1);
|
||||
var cy = rng.randint(0, C - 1);
|
||||
|
||||
var steps = 4;
|
||||
for (var k = 0; k < steps; k++) {
|
||||
var rr = clamp(cx + (rng.randint(-2, 2) + rng.randint(-2, 2)), 0, R - 1);
|
||||
var cc = clamp(cy + (rng.randint(-2, 2) + rng.randint(-2, 2)), 0, C - 1);
|
||||
|
||||
if (g.isDigitAt(rr, cc)) {
|
||||
g.clear(rr, cc);
|
||||
} else {
|
||||
var d = OFFSETS[rng.randint(1, 4)];
|
||||
g.setByteAt(rr, cc, d.dbyte);
|
||||
if (!hasRoomForClue(g, Grid.offset(rr, cc), d)) g.clear(rr, cc);
|
||||
}
|
||||
}
|
||||
return g;
|
||||
}
|
||||
Grid mutate(Rng rng, Grid grid) {
|
||||
var g = grid.deepCopyGrid();
|
||||
var cx = rng.randint(0, R - 1);
|
||||
@@ -558,7 +619,6 @@ public record SwedishGenerator(int[] buff) {
|
||||
}
|
||||
return g;
|
||||
}
|
||||
|
||||
Grid crossover(Rng rng, Grid a, Grid b) {
|
||||
var out = makeEmptyGrid();
|
||||
var theta = rng.nextFloat() * Math.PI;
|
||||
|
||||
Reference in New Issue
Block a user