diff --git a/src/main/java/puzzle/SwedishGenerator.java b/src/main/java/puzzle/SwedishGenerator.java index bfa5356..0ac976f 100644 --- a/src/main/java/puzzle/SwedishGenerator.java +++ b/src/main/java/puzzle/SwedishGenerator.java @@ -27,8 +27,6 @@ import static java.nio.charset.StandardCharsets.*; * A) generate randoms for and idx and direction (clue together) * B) convert IDX_PATH_0_BASE into bit-pattern (i think) Length should not be checked, just left empty if not good. * C) store more information in the byte[] even consider the long[] or try sqeeze the 288 options (clue) in a byte. - * D) separate clue into three long pairs of hi and lo, (v,h,r) so we do not store the clue anymore in the grid array at all - * E) store letter-set also in a long pair so we can use it in path determinations * F) pre-determine random clue arrangements, so they do not involve impossible clue's such as bottom at last or the line before that and such to all sides * G) Check 3wall, the current implementation may be faster, but the accuracy is lower, degrade performance on the filler */ @@ -391,11 +389,8 @@ public record SwedishGenerator(Rng rng, int[] stack, Clues cache) { static Slot from(int key, long lo, long hi) { return new Slot(key, lo, hi); } public int length() { return Long.bitCount(lo) + Long.bitCount(hi); } - public int clueIndex() { return clueIndex(key); } public static int clueIndex(int key) { return key >>> BIT_FOR_DIR; } public static int dir(int key) { return key & 3; } - public boolean horiz() { return horiz(key); } - public boolean increasing() { return (key & 2) == 0; } public static boolean increasing(int dir) { return (dir & 2) == 0; } public IntStream walk() { return Gridded.walk((byte) key, lo, hi); } public static boolean horiz(int d) { return (d & 1) != 0; } diff --git a/src/test/java/puzzle/MainTest.java b/src/test/java/puzzle/MainTest.java index 1710a3a..fb5d428 100644 --- a/src/test/java/puzzle/MainTest.java +++ b/src/test/java/puzzle/MainTest.java @@ -90,10 +90,10 @@ public class MainTest { } @Test public void testHoriz() { - assertTrue(Slot.from(1, 0L, 0L).horiz()); // Right - assertTrue(Slot.from(3, 0L, 0L).horiz()); // Left - assertFalse(Slot.from(0, 0L, 0L).horiz()); // Down - assertFalse(Slot.from(2, 0L, 0L).horiz()); // Up + assertTrue(Slot.horiz(1)); // Right + assertTrue(Slot.horiz(3)); // Left + assertFalse(Slot.horiz(0)); // Down + assertFalse(Slot.horiz(2)); // Up } @Test public void testGridBasics() { diff --git a/src/test/java/puzzle/SwedishGeneratorTest.java b/src/test/java/puzzle/SwedishGeneratorTest.java index a0436f4..ff63cfd 100644 --- a/src/test/java/puzzle/SwedishGeneratorTest.java +++ b/src/test/java/puzzle/SwedishGeneratorTest.java @@ -3,6 +3,7 @@ package puzzle; import lombok.val; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import puzzle.Export.Gridded; import puzzle.Export.IntListDTO; import java.nio.charset.StandardCharsets; import java.util.Arrays; @@ -81,9 +82,8 @@ public class SwedishGeneratorTest { grid.setLetterLo(0, LETTER_A); grid.setLetterLo(1, LETTER_B); grid.setLetterLo(2, LETTER_C); - var slot = Slot.from(18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L); - var pattern = patternForSlot(grid, slot.key(), slot.lo(), slot.hi()); - + var key = 18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT); + var pattern = patternForSlot(grid, key, 7L, 0L); assertEquals(1L | (28L << 8) | (55L << 16), pattern); } @@ -92,18 +92,16 @@ public class SwedishGeneratorTest { var grid = createEmpty(); grid.setLetterLo(OFF_0_0, LETTER_A); grid.setLetterLo(2, LETTER_C); - var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L); - var pattern = patternForSlot(grid, slot.key(), slot.lo(), slot.hi()); - - assertEquals(1L | (0L << 8) | (55L << 16), pattern); + var key = 1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT); + var pattern = patternForSlot(grid, key, 7L, 0L); + assertEquals(1L | (0L) | (55L << 16), pattern); } @Test void testPatternForSlotAllDashes() { var grid = createEmpty(); - var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L); - var pattern = patternForSlot(grid, slot.key(), slot.lo(), slot.hi()); - + var key = 1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT); + var pattern = patternForSlot(grid, key, 7L, 0L); assertEquals(0L, pattern); } @@ -111,9 +109,8 @@ public class SwedishGeneratorTest { void testPatternForSlotSingleLetter() { var grid = createEmpty(); grid.setLetterLo(OFF_0_0, LETTER_A); - var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT), 7L, 0L); - var pattern = patternForSlot(grid, slot.key(), slot.lo(), slot.hi()); - + var key = 1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT); + var pattern = patternForSlot(grid, key, 7L, 0L); assertEquals(1L, pattern); } @Test @@ -191,12 +188,11 @@ public class SwedishGeneratorTest { // pos 2: (4, 5) lo |= 1L << OFF_4_5; - var s = Slot.from(key, lo, 0L); - System.out.println("[DEBUG_LOG] s.dir() = " + Slot.dir(s.key())); - assertEquals(OFF_2_3, s.clueIndex()); - assertEquals(CLUE_DOWN, Slot.dir(s.key())); - assertFalse(s.horiz()); - var cells = s.walk().toArray(); + System.out.println("[DEBUG_LOG] s.dir() = " + Slot.dir(key)); + assertEquals(OFF_2_3, Slot.clueIndex(key)); + assertEquals(CLUE_DOWN, Slot.dir(key)); + assertFalse(Slot.horiz(key)); + var cells = Gridded.walk((byte) key, lo, 0L).toArray(); assertEquals(2, SwedishGenerator.IT[cells[0]].r()); assertEquals(3, SwedishGenerator.IT[cells[1]].r()); assertEquals(4, SwedishGenerator.IT[cells[2]].r()); @@ -290,7 +286,7 @@ public class SwedishGeneratorTest { var s = slots[0]; assertTrue(s.length() >= 2); - assertEquals(OFF_0_0, s.clueIndex()); + assertEquals(OFF_0_0, Slot.clueIndex(s.key())); assertEquals(CLUE_RIGHT, Slot.dir(s.key())); } @@ -332,21 +328,21 @@ public class SwedishGeneratorTest { // Slot at OFF_0_0 length 3, horizontal (right) var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT); var lo = (1L << OFF_0_0) | (1L << OFF_0_1) | (1L << OFF_0_2); - var s = Slot.from(key, lo, 0L); + val hi = 0L; var w1 = ABC; // 1. Successful placement in empty grid - assertTrue(placeWord(grid, s.key(), s.lo(), s.hi(), w1)); + assertTrue(placeWord(grid, key, lo, hi, w1)); assertEquals(LETTER_A, grid.letter32At(OFF_0_0)); assertEquals(LETTER_B, grid.letter32At(OFF_0_1)); assertEquals(LETTER_C, grid.letter32At(OFF_0_2)); // 2. Successful placement with partial overlap (same characters) - assertTrue(placeWord(grid, s.key(), s.lo(), s.hi(), w1)); + assertTrue(placeWord(grid, key, lo, hi, w1)); // 3. Conflict: place "ABD" where "ABC" is var w2 = ABD; - assertFalse(placeWord(grid, s.key(), s.lo(), s.hi(), w2)); + assertFalse(placeWord(grid, key, lo, hi, w2)); // Verify grid is unchanged (still "ABC") assertEquals(LETTER_A, grid.letter32At(OFF_0_0)); assertEquals(LETTER_B, grid.letter32At(OFF_0_1)); @@ -355,7 +351,7 @@ public class SwedishGeneratorTest { // 4. Partial placement then conflict (rollback) grid = createEmpty(); grid.setLetterLo(OFF_0_2, LETTER_X); // Conflict at the end - assertFalse(placeWord(grid, s.key(), s.lo(), s.hi(), w1)); + assertFalse(placeWord(grid, key, lo, hi, w1)); // Verify grid is still empty (except for 'X') assertFalse(grid.lisLetterAtLo(OFF_0_0)); assertFalse(grid.lisLetterAtLo(OFF_0_1)); @@ -368,11 +364,10 @@ public class SwedishGeneratorTest { // Slot at 0,1 length 2 var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT); var lo = (1L << OFF_0_1) | (1L << OFF_0_2); - var s = Slot.from(key, lo, 0L); var w = AZ; val low = grid.lo; val top = grid.hi; - var placed = placeWord(grid, s.key(), s.lo(), s.hi(), w); + var placed = placeWord(grid, key, lo, 0L, w); assertTrue(placed); assertEquals(LETTER_A, grid.letter32At(OFF_0_1)); assertEquals(LETTER_Z, grid.letter32At(OFF_0_2)); @@ -392,25 +387,21 @@ public class SwedishGeneratorTest { assertTrue(Slot.increasing(CLUE_DOWN)); // Down assertFalse(Slot.increasing(CLUE_UP)); // Up - var sInc = Slot.from((0) | CLUE_RIGHT, 1L, 0L); - assertTrue(Slot.increasing(sInc.key())); - var sDec = Slot.from((0) | CLUE_LEFT, 1L, 0L); - assertFalse(Slot.increasing(sDec.key())); + assertTrue(Slot.increasing((0) | CLUE_RIGHT)); + assertFalse(Slot.increasing((0) | CLUE_LEFT)); // 2. Test slotScore val counts = new byte[SIZE]; counts[1] = 2; counts[2] = 3; + var dict = new Dict(WORDS); + var entry5 = dict.index()[5]; var sScore = Slot.from(0, (1L << 1) | (1L << 2), 0L); // cross = (counts[1]-1) + (counts[2]-1) = 1 + 2 = 3 // score = 3 * 10 + len(2) = 32 assertEquals(32, slotScore(counts, sScore)); - // 3. Test candidateCountForPattern - var dict = new Dict(WORDS); - var entry5 = dict.index()[5]; - var ctx = Context.get(); var pattern = packPattern("APP"); assertEquals(2, candidateCountForPattern(ctx.bitset(), pattern, entry5.posBitsets(), entry5.numlong()));