diff --git a/src/main/java/puzzle/SwedishGenerator.java b/src/main/java/puzzle/SwedishGenerator.java index 70bbd82..4656067 100644 --- a/src/main/java/puzzle/SwedishGenerator.java +++ b/src/main/java/puzzle/SwedishGenerator.java @@ -17,15 +17,16 @@ import java.util.function.Predicate; @SuppressWarnings("ALL") public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN) { - public SwedishGenerator(int W,int H) { this(W, H, W * H, Math.min(W, H)); } - public SwedishGenerator() { this(9, 8); } + public SwedishGenerator(int W, int H) { this(W, H, W * H, Math.min(W, H)); } + public SwedishGenerator() { this(9, 8); } static final int CLUE_SIZE = 4, SIMPLICITY_DEFAULT_SCORE = 2; - static final int MIN_LEN = 2; + static final int MIN_LEN = 2; + static final int MAX_TRIES_PER_SLOT = 2000; // Directions for '1'..'6' - static final int[][] OFFSETS = new int[7][2]; - static final int[][] STEPS = new int[7][2]; + static final int[][] OFFSETS = new int[7][2]; + static final int[][] STEPS = new int[7][2]; static { // 1: up OFFSETS[1] = new int[]{ -1, 0 }; @@ -80,7 +81,17 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN) { } static int clamp(int x, int a, int b) { return Math.max(a, Math.min(b, x)); } - + record Grid(char[][] g,int H,int W) { + + public Grid(char[][] grid) { + this(grid, grid.length, grid[0].length); + } + Grid deepCopyGrid() { + var out = new char[H][W]; + for (var r = 0; r < H; r++) out[r] = Arrays.copyOf(g[r], W); + return new Grid(out); + } + } // ---------------- Grid helpers ---------------- char[][] makeEmptyGrid() { var g = new char[H][W]; @@ -89,9 +100,10 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN) { } char[][] deepCopyGrid(char[][] g) { - var out = new char[H][W]; + return new Grid(g).deepCopyGrid().g; + /*var out = new char[H][W]; for (var r = 0; r < H; r++) out[r] = Arrays.copyOf(g[r], W); - return out; + return out;*/ } String gridToString(char[][] g) { @@ -347,13 +359,20 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN) { return run >= MIN_LEN; } + record nbrs_8(int x, int y) { } + // ---------------- FAST mask fitness ---------------- - final static int[][] nbrs8 = new int[][]{ - { -1, -1 }, { -1, 0 }, { -1, 1 }, - { 0, -1 }, { 0, 1 }, - { 1, -1 }, { 1, 0 }, { 1, 1 } + final static nbrs_8[] nbrs8 = new nbrs_8[]{ + new nbrs_8(-1, -1), + new nbrs_8(-1, 0), + new nbrs_8(-1, 1), + new nbrs_8(0, -1), + new nbrs_8(0, 1), + new nbrs_8(1, -1), + new nbrs_8(1, 0), + new nbrs_8(1, 1) }; - static final int[][] nbrs4 = new int[][]{ { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; + static final int[][] nbrs4 = new int[][]{ { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; long maskFitness(char[][] grid, int[] lenCounts) { long penalty = 0; @@ -414,7 +433,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN) { size++; for (var d : nbrs8) { - int nx = x + d[0], ny = y + d[1]; + int nx = x + d.x, ny = y + d.y; if (nx < 0 || nx >= H || ny < 0 || ny >= W) continue; if (seen[nx][ny]) continue; if (!isDigit(grid[nx][ny])) continue; @@ -588,6 +607,7 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN) { } // ---------------- Fill (CSP) ---------------- + record Undo(int[] rs, int[] cs, char[] prev, int n) { } public static final class FillStats { @@ -597,6 +617,10 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN) { public int lastMRV; } + record Pick(Slot slot, + CandidateInfo info, + boolean done) { } + public static final record FillResult(boolean ok, char[][] grid, HashMap clueMap, @@ -613,8 +637,6 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN) { } } - record Undo(int[] rs, int[] cs, char[] prev, int n) { } - static char[] patternForSlot(char[][] grid, Slot s) { var pat = new char[s.len]; for (var i = 0; i < s.len; i++) { @@ -654,13 +676,11 @@ public record SwedishGenerator(int W, int H, int SIZE, int MAX_LEN) { } return new Undo(urs, ucs, up, n); } - static final int MAX_TRIES_PER_SLOT = 2000; + static void undoPlace(char[][] grid, Undo u) { for (var i = 0; i < u.n; i++) grid[u.rs[i]][u.cs[i]] = u.prev[i]; } - record Pick(Slot slot, - CandidateInfo info, - boolean done) { } + public FillResult fillMask(Rng rng, char[][] mask, DictEntry[] dictIndex, int logEveryMs, int timeLimitMs, boolean verbose) {