diff --git a/src/main/java/puzzle/SwedishGenerator.java b/src/main/java/puzzle/SwedishGenerator.java index 5bcb72d..efa0c27 100644 --- a/src/main/java/puzzle/SwedishGenerator.java +++ b/src/main/java/puzzle/SwedishGenerator.java @@ -166,7 +166,7 @@ public record SwedishGenerator(Rng rng) { this.hi = hi; } static Grid createEmpty() { return new Grid(new byte[SIZE], X, X); } - int digitAt(int index) { return g[index] & 7; } + int digitAt(int index) { return g[index]; } 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); } @@ -326,9 +326,8 @@ public record SwedishGenerator(Rng rng) { } private static void processSlot(Grid grid, SlotVisitor visitor, int idx) { - int d = grid.digitAt(idx); // 1..4 - int di = d - 1; // 0..3 - int key = (idx << 2) | di; + int d = grid.digitAt(idx); // 0..3 + int key = (idx << 2) | d; long rayLo = PATH_LO[key]; long rayHi = PATH_HI[key]; @@ -339,7 +338,7 @@ public record SwedishGenerator(Rng rng) { // slice ray to stop before first clue, depending on direction monotonicity // right/down => increasing indices; up/left => decreasing indices - boolean increasing = Slot.increasing(d); + boolean increasing = Slot.increasing(d + 1); if (increasing) { // first clue is lowest index among hits (lo first, then hi) @@ -367,7 +366,7 @@ public record SwedishGenerator(Rng rng) { } if ((rayLo | rayHi) != 0) { - visitor.visit(Slot.packSlotDir(idx, d), rayLo, rayHi); + visitor.visit(Slot.packSlotDir(idx, d + 1), rayLo, rayHi); } } @@ -391,11 +390,10 @@ public record SwedishGenerator(Rng rng) { for (long bits = (i == 0 ? lo_cl : hi_cl); bits != X; bits &= bits - 1) { int clueIdx = i | Long.numberOfTrailingZeros(bits); int d = grid.digitAt(clueIdx); - int di = d - 1; - int key = (clueIdx << 2) | di; + int key = (clueIdx << 2) | d; long rLo = PATH_LO[key], rHi = PATH_HI[key]; long hLo = rLo & lo_cl, hHi = rHi & hi_cl; - if (Slot.increasing(d)) { + if (Slot.increasing(d + 1)) { if (hLo != 0) { rLo &= ((1L << Long.numberOfTrailingZeros(hLo)) - 1); rHi = 0; @@ -412,7 +410,7 @@ public record SwedishGenerator(Rng rng) { } if ((rLo | rHi) != 0) { hasSlots = true; - if (Slot.horiz(d)) covH.or(rLo, rHi); + if (Slot.horiz(d + 1)) covH.or(rLo, rHi); else covV.or(rLo, rHi); if ((Long.bitCount(rLo) + Long.bitCount(rHi)) < MIN_LEN) penalty += 8000; } else { @@ -508,7 +506,7 @@ public record SwedishGenerator(Rng rng) { if (g.isClue(idx)) continue; int d_idx = rng.randint2bit(); if (g.hasRoomForClue(OFFSETS_D_IDX[d_idx | idx << 2])) { - g.setClue(idx, (byte) (1 + (d_idx | 48))); + g.setClue(idx, (byte) d_idx); placed++; } } @@ -523,7 +521,7 @@ public record SwedishGenerator(Rng rng) { if (!g.clueless(ri)) { int d_idx = rng.randint2bit(); val packed = OFFSETS_D_IDX[d_idx | ri << 2]; - if (g.hasRoomForClue(packed)) g.setClue(ri, (byte) (1 + (d_idx | 48))); + if (g.hasRoomForClue(packed)) g.setClue(ri, (byte) d_idx); } } return g; @@ -557,7 +555,7 @@ public record SwedishGenerator(Rng rng) { for (var hi = out.hi; hi != X; hi &= hi - 1L) clearClues(out, 64 + Long.numberOfTrailingZeros(hi)); return out; } - public static void clearClues(Grid out, int idx) { if (!out.hasRoomForClue(OFFSETS_D_IDX[(out.digitAt(idx) - 1) | (idx << 2)])) out.clearClue(idx); } + public static void clearClues(Grid out, int idx) { if (!out.hasRoomForClue(OFFSETS_D_IDX[(out.digitAt(idx) ) | (idx << 2)])) out.clearClue(idx); } Grid hillclimb(Grid start, int limit) { var best = start; diff --git a/src/test/java/puzzle/ExportFormatTest.java b/src/test/java/puzzle/ExportFormatTest.java index a11797c..59a20cb 100644 --- a/src/test/java/puzzle/ExportFormatTest.java +++ b/src/test/java/puzzle/ExportFormatTest.java @@ -19,18 +19,23 @@ import static puzzle.SwedishGenerator.*; public class ExportFormatTest { + static final byte CLUE_UP = 0; + static final byte CLUE_RIGHT = 1; + static final byte CLUE_DOWN = 2; + static final byte CLUE_LEFT = 3; + @Test void testExportFormatFromFilled() { var swe = new SwedishGenerator(new Rng(0)); var grid = Grid.createEmpty(); - // Place a '2' (right) at (0,0) - grid.setClue(0, (byte) '2'); + // Place a RIGHT clue at (0,0) + grid.setClue(0, CLUE_RIGHT); // This creates a slot starting at (0,1) var clueMap = new HashMap(); - // key = (cellIndex << 4) | direction - var key = 2; + // key = (cellIndex << 3) | (direction + 1) + var key = (0 << 3) | (CLUE_RIGHT + 1); clueMap.put(key, Lemma.from("TEST")); // Manually fill the grid letters for "TEST" at (0,1), (0,2), (0,3), (0,4) @@ -38,8 +43,8 @@ public class ExportFormatTest { grid.setLetter(Grid.offset(0, 2), (byte) 'E'); grid.setLetter(Grid.offset(0, 3), (byte) 'S'); grid.setLetter(Grid.offset(0, 4), (byte) 'T'); - // Terminate thGrid.offset(e slot at) (0,5) with another digit to avoid it extending to MAX_WORD_LENGTH - grid.setClue(Grid.offset(0, 5), (byte) '1'); + // Terminate the slot at (0,5) with another digit to avoid it extending to MAX_WORD_LENGTH + grid.setClue(Grid.offset(0, 5), CLUE_UP); var fillResult = new FillResult(true, new Gridded(grid), clueMap, new FillStats()); var puzzleResult = new PuzzleResult(swe, null, null, fillResult); diff --git a/src/test/java/puzzle/MainTest.java b/src/test/java/puzzle/MainTest.java index 938193f..8a3cfc5 100644 --- a/src/test/java/puzzle/MainTest.java +++ b/src/test/java/puzzle/MainTest.java @@ -16,15 +16,30 @@ import static puzzle.SwedishGenerator.DASH; public class MainTest { + static final byte LETTER_A = (byte) 'A'; + static final byte LETTER_B = (byte) 'B'; + static final byte LETTER_Z = (byte) 'Z'; + static final byte CLUE_UP = 0; + static final byte CLUE_RIGHT = 1; + static final byte CLUE_DOWN = 2; + static final byte CLUE_LEFT = 3; + + static final int OFF_0_0 = Grid.offset(0, 0); + static final int OFF_0_1 = Grid.offset(0, 1); + static final int OFF_0_2 = Grid.offset(0, 2); + static final int OFF_1_1 = Grid.offset(1, 1); + static final int OFF_1_2 = Grid.offset(1, 2); + static final int OFF_2_3 = Grid.offset(2, 3); + @Test void testExtractSlots() { var grid = Grid.createEmpty(); // Set up digits on the grid to create slots. - // '2' (right) at (0,0) -> slot at (0,1), (0,2) - grid.setClue(0, (byte) '2'); - grid.setLetter(Grid.offset(0, 1), (byte) 'A'); - grid.setLetter(Grid.offset(0, 2), (byte) 'B'); + // CLUE_RIGHT at OFF_0_0 -> slot at (0,1), (0,2) + grid.setClue(OFF_0_0, CLUE_RIGHT); + grid.setLetter(OFF_0_1, LETTER_A); + grid.setLetter(OFF_0_2, LETTER_B); var slots = extractSlots(grid); assertEquals(1, slots.size()); @@ -49,7 +64,7 @@ public class MainTest { @Test void testForEachSlot() { var grid = Grid.createEmpty(); - grid.setClue(0, (byte) '2'); // right + grid.setClue(OFF_0_0, CLUE_RIGHT); // right var count = new AtomicInteger(0); grid.forEachSlot((key, lo, hi) -> { @@ -72,32 +87,32 @@ public class MainTest { var grid = Grid.createEmpty(); // Test set/get - grid.setLetter(Grid.offset(0, 0), (byte) 'A'); - grid.setClue(Grid.offset(1, 2), (byte) '3'); - grid.setLetter(Grid.offset(2, 3), (byte) 'Z'); + grid.setLetter(OFF_0_0, LETTER_A); + grid.setClue(OFF_1_2, CLUE_UP); + grid.setLetter(OFF_2_3, LETTER_Z); - Assertions.assertEquals((byte) 'A', grid.byteAt(Grid.offset(0, 0))); - Assertions.assertEquals((byte) '3', grid.byteAt(Grid.offset(1, 2))); - Assertions.assertEquals((byte) 'Z', grid.byteAt(Grid.offset(2, 3))); - Assertions.assertEquals(DASH, grid.byteAt(Grid.offset(1, 1))); + Assertions.assertEquals(LETTER_A, grid.byteAt(OFF_0_0)); + Assertions.assertEquals(CLUE_UP, grid.byteAt(OFF_1_2)); + Assertions.assertEquals(LETTER_Z, grid.byteAt(OFF_2_3)); + Assertions.assertEquals(DASH, grid.byteAt(OFF_1_1)); // Test isLetterAt - Assertions.assertTrue(grid.notClue(Grid.offset(0, 0))); - Assertions.assertFalse(grid.notClue(Grid.offset(1, 2))); - Assertions.assertTrue(grid.notClue(Grid.offset(2, 3))); - Assertions.assertFalse(grid.isClue(Grid.offset(1, 1))); + Assertions.assertTrue(grid.notClue(OFF_0_0)); + Assertions.assertFalse(grid.notClue(OFF_1_2)); + Assertions.assertTrue(grid.notClue(OFF_2_3)); + Assertions.assertFalse(grid.isClue(OFF_1_1)); // Test isDigitAt Assertions.assertFalse(grid.isClue(0)); - Assertions.assertTrue(grid.isClue(Grid.offset(1, 2))); - Assertions.assertEquals(3, grid.digitAt(Grid.offset(1, 2))); - Assertions.assertFalse(grid.isClue(Grid.offset(2, 3))); - Assertions.assertFalse(grid.isClue(Grid.offset(1, 1))); + Assertions.assertTrue(grid.isClue(OFF_1_2)); + Assertions.assertEquals(CLUE_UP, grid.digitAt(OFF_1_2)); + Assertions.assertFalse(grid.isClue(OFF_2_3)); + Assertions.assertFalse(grid.isClue(OFF_1_1)); // Test isLettercell - Assertions.assertTrue(grid.notClue(Grid.offset(0, 0))); // 'A' is letter - Assertions.assertTrue(grid.isClue(Grid.offset(1, 2))); // '5' is digit - Assertions.assertTrue(grid.notClue(Grid.offset(1, 1))); // '#' is lettercell + Assertions.assertTrue(grid.notClue(OFF_0_0)); // 'A' is letter + Assertions.assertTrue(grid.isClue(OFF_1_2)); // digit + Assertions.assertTrue(grid.notClue(OFF_1_1)); // '#' is lettercell } @Test @@ -119,8 +134,8 @@ public class MainTest { @Test public void testMini() { var grid = Grid.createEmpty(); - val idx = Grid.offset(1, 1); - grid.setClue(idx, (byte) '1'); + val idx = OFF_1_1; + grid.setClue(idx, CLUE_LEFT); Assertions.assertTrue(grid.isClue(idx)); } @Test @@ -163,9 +178,9 @@ public class MainTest { // Regression baseline for seed search starting at 12347, pop 4, gens 20 Assertions.assertEquals(12348, foundSeed, "Found seed changed"); Assertions.assertEquals(18, res.filled().clueMap().size(), "Number of assigned words changed"); - Assertions.assertEquals("TEN", Lemma.asWord(res.filled().clueMap().get(2))); - Assertions.assertEquals(301794542151533187L, res.filled().grid().grid().lo); - Assertions.assertEquals(193L, res.filled().grid().grid().hi); + Assertions.assertEquals("DISCO", Lemma.asWord(res.filled().clueMap().get(476))); + Assertions.assertEquals(3332734179516361088L, res.filled().grid().grid().lo); + Assertions.assertEquals(128L, res.filled().grid().grid().hi); } boolean isLetter(byte b) { return (b & 64) != 0; } @Test diff --git a/src/test/java/puzzle/SwedishGeneratorTest.java b/src/test/java/puzzle/SwedishGeneratorTest.java index 2e9c313..b084f17 100644 --- a/src/test/java/puzzle/SwedishGeneratorTest.java +++ b/src/test/java/puzzle/SwedishGeneratorTest.java @@ -11,11 +11,32 @@ import static puzzle.SwedishGenerator.*; public class SwedishGeneratorTest { - static final byte D_BYTE_2 = 50; + static final byte LETTER_A = (byte) 'A'; + static final byte LETTER_B = (byte) 'B'; + static final byte LETTER_C = (byte) 'C'; + static final byte LETTER_X = (byte) 'X'; + static final byte LETTER_Z = (byte) 'Z'; + static final byte CLUE_UP = 0; + static final byte CLUE_RIGHT = 1; + static final byte CLUE_DOWN = 2; + static final byte CLUE_LEFT = 3; + + static final int OFF_0_0 = Grid.offset(0, 0); + static final int OFF_0_1 = Grid.offset(0, 1); + static final int OFF_0_2 = Grid.offset(0, 2); + static final int OFF_1_1 = Grid.offset(1, 1); + static final int OFF_1_2 = Grid.offset(1, 2); + static final int OFF_2_0 = Grid.offset(2, 0); + static final int OFF_2_3 = Grid.offset(2, 3); + static final int OFF_2_5 = Grid.offset(2, 5); + static final int OFF_3_5 = Grid.offset(3, 5); + static final int OFF_4_5 = Grid.offset(4, 5); + + static final byte D_BYTE_2 = CLUE_RIGHT; @Test void testPatternForSlotAllLetters() { - var grid = new Grid(new byte[]{ 65, 66, 67 }); // A B C - var slot = Slot.from(18, 7L, 0L); + var grid = new Grid(new byte[]{ LETTER_A, LETTER_B, LETTER_C }); + var slot = Slot.from(18 << Slot.BIT_FOR_DIR | (CLUE_RIGHT + 1), 7L, 0L); long pattern = patternForSlot(grid, slot); assertEquals(1 | (2 << 5) | (3 << 10), pattern); @@ -23,8 +44,8 @@ public class SwedishGeneratorTest { @Test void testPatternForSlotMixed() { - var grid = new Grid(new byte[]{ 65, DASH, 67 }); // A - C - var slot = Slot.from(1 << 3 | 2, 7L, 0L); + var grid = new Grid(new byte[]{ LETTER_A, DASH, LETTER_C }); + var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT + 1), 7L, 0L); long pattern = patternForSlot(grid, slot); assertEquals(1 | (0 << 5) | (3 << 10), pattern); @@ -33,7 +54,7 @@ public class SwedishGeneratorTest { @Test void testPatternForSlotAllDashes() { var grid = new Grid(new byte[]{ DASH, DASH, DASH }); // - - - - var slot = Slot.from(1 << 3 | 2, 7L, 0L); + var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT + 1), 7L, 0L); long pattern = patternForSlot(grid, slot); assertEquals(0, pattern); @@ -41,8 +62,8 @@ public class SwedishGeneratorTest { @Test void testPatternForSlotSingleLetter() { - var grid = new Grid(new byte[]{ 65, DASH, DASH }); // A - - - var slot = Slot.from(1 << 3 | 2, 7L, 0L); + var grid = new Grid(new byte[]{ LETTER_A, DASH, DASH }); + var slot = Slot.from(1 << Slot.BIT_FOR_DIR | (CLUE_RIGHT + 1), 7L, 0L); long pattern = patternForSlot(grid, slot); assertEquals(1, pattern); @@ -68,23 +89,23 @@ public class SwedishGeneratorTest { @Test void testGrid() { var grid = Grid.createEmpty(); - grid.setLetter(0, (byte) 'A'); - grid.setClue(Grid.offset(0, 1), (byte) '1'); + grid.setLetter(OFF_0_0, LETTER_A); + grid.setClue(OFF_0_1, CLUE_LEFT); - assertEquals('A', grid.byteAt(0)); - assertEquals(1, grid.digitAt(Grid.offset(0, 1))); - assertTrue(grid.notClue(0)); - assertFalse(grid.isClue(0)); - assertTrue(grid.isClue(Grid.offset(0, 1))); - assertFalse(grid.notClue(Grid.offset(0, 1))); - assertTrue(grid.notClue(0)); - assertFalse(grid.notClue(Grid.offset(0, 1))); + assertEquals('A', grid.byteAt(OFF_0_0)); + assertEquals(CLUE_LEFT, grid.digitAt(OFF_0_1)); + assertTrue(grid.notClue(OFF_0_0)); + assertFalse(grid.isClue(OFF_0_0)); + assertTrue(grid.isClue(OFF_0_1)); + assertFalse(grid.notClue(OFF_0_1)); + assertTrue(grid.notClue(OFF_0_0)); + assertFalse(grid.notClue(OFF_0_1)); var copy = grid.deepCopyGrid(); - assertEquals('A', copy.byteAt(0)); - copy.setLetter(0, (byte) 'B'); - assertEquals('B', copy.byteAt(0)); - assertEquals('A', grid.byteAt(0)); + assertEquals('A', copy.byteAt(OFF_0_0)); + copy.setLetter(OFF_0_0, LETTER_B); + assertEquals('B', copy.byteAt(OFF_0_0)); + assertEquals('A', grid.byteAt(OFF_0_0)); } @Test @@ -134,22 +155,22 @@ public class SwedishGeneratorTest { void testSlot() { System.out.println("[DEBUG_LOG] Slot.BIT_FOR_DIR = " + Slot.BIT_FOR_DIR); // key = (r << 8) | (c << 4) | d - var offset = Grid.offset(2, 3); + var offset = OFF_2_3; System.out.println("[DEBUG_LOG] Grid.offset(2, 3) = " + offset); - var key = (offset << Slot.BIT_FOR_DIR) | 3; + var key = (offset << Slot.BIT_FOR_DIR) | (CLUE_DOWN + 1); System.out.println("[DEBUG_LOG] key = " + key); long lo = 0; // pos 0: (2, 5) - lo |= 1L << Grid.offset(2, 5); + lo |= 1L << OFF_2_5; // pos 1: (3, 5) - lo |= 1L << Grid.offset(3, 5); + lo |= 1L << OFF_3_5; // pos 2: (4, 5) - lo |= 1L << Grid.offset(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(Grid.offset(2,3), s.clueIndex()); - assertEquals(3, Slot.dir(s.key())); + assertEquals(OFF_2_3, s.clueIndex()); + assertEquals(CLUE_DOWN + 1, Slot.dir(s.key())); assertFalse(s.horiz()); var cells = s.walk().toArray(); assertEquals(2, Grid.r(cells[0])); @@ -159,8 +180,8 @@ public class SwedishGeneratorTest { assertEquals(5, Grid.c(cells[1])); assertEquals(5, Grid.c(cells[2])); - assertTrue(Slot.horiz(2)); // right - assertFalse(Slot.horiz(3)); // down + assertTrue(Slot.horiz(CLUE_RIGHT + 1)); // right + assertFalse(Slot.horiz(CLUE_DOWN + 1)); // down } static int intersectSorted(int[] a, int aLen, int[] b, int bLen, int[] out) { if (aLen == 0 || bLen == 0) return 0; @@ -238,26 +259,17 @@ public class SwedishGeneratorTest { var gen = new SwedishGenerator(new Rng(0)); var grid = Grid.createEmpty(); // 3x3 grid (Config.PUZZLE_ROWS/COLS are 3 in test env) - // Set '2' (right) at 0,0 - grid.setClue(0, (byte) '2'); + // Set CLUE_RIGHT at OFF_0_0 + grid.setClue(OFF_0_0, CLUE_RIGHT); // This should detect a slot starting at 0,1 with length 2 (0,1 and 0,2) var slots = extractSlots(grid); - // Depending on MAX_WORD_LENGTH and grid size. - // In 3x3, if we have '2' at 0,0, rr=0, cc=1. - // while loop: - // 1. rr=0, cc=1, n=0 -> packedRs |= 0, packedCs |= 1, n=1, rr=0, cc=2 - // 2. rr=0, cc=2, n=1 -> packedRs |= 0, packedCs |= 2<<4, n=2, rr=0, cc=3 (out) - // result: Slot with len 2. - assertEquals(1, slots.size()); var s = slots.getFirst(); - // MAX_WORD_LENGTH = Math.min(W, H). In tests with -DPUZZLE_ROWS=3 -DPUZZLE_COLS=3, it should be 3. - // However, the test run might be using default Config values if not properly overridden in the test environment. - // If Actual was 8, it means MAX_WORD_LENGTH was at least 8. + assertTrue(s.len() >= 2); - assertEquals(0, s.clueIndex()); - assertEquals(2, Slot.dir(s.key())); + assertEquals(OFF_0_0, s.clueIndex()); + assertEquals(CLUE_RIGHT + 1, Slot.dir(s.key())); } @Test @@ -273,8 +285,7 @@ public class SwedishGeneratorTest { assertTrue(f1 >= 1_000_000_000L); // Add a slot - //var dbyte = OFFSETS[2].dbyte(); - grid.setClue(0, D_BYTE_2); + grid.setClue(OFF_0_0, D_BYTE_2); var f2 = gen.maskFitness(grid); assertTrue(f2 < f1); } @@ -303,18 +314,18 @@ public class SwedishGeneratorTest { @Test void testPlaceWord() { var grid = Grid.createEmpty(); - // Slot at (0,0) length 3, horizontal (right) - var key = (Grid.offset(0,0) << Slot.BIT_FOR_DIR) | 2; - var lo = (1L << Grid.offset(0, 0)) | (1L << Grid.offset(0, 1)) | (1L << Grid.offset(0, 2)); + // Slot at OFF_0_0 length 3, horizontal (right) + var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT + 1); + var lo = (1L << OFF_0_0) | (1L << OFF_0_1) | (1L << OFF_0_2); var s = Slot.from(key, lo, 0L); var w1 = Lemma.from("ABC"); var undoBuffer = new long[10]; // 1. Successful placement in empty grid assertTrue(placeWord(grid, s, w1, undoBuffer, 0)); - assertEquals('A', grid.byteAt(0)); - assertEquals('B', grid.byteAt(Grid.offset(0, 1))); - assertEquals('C', grid.byteAt(Grid.offset(0, 2))); + assertEquals('A', grid.byteAt(OFF_0_0)); + assertEquals('B', grid.byteAt(OFF_0_1)); + assertEquals('C', grid.byteAt(OFF_0_2)); assertEquals(lo, undoBuffer[0]); // 2. Successful placement with partial overlap (same characters) @@ -325,52 +336,52 @@ public class SwedishGeneratorTest { var w2 = Lemma.from("ABD"); assertFalse(placeWord(grid, s, w2, undoBuffer, 2)); // Verify grid is unchanged (still "ABC") - assertEquals('A', grid.byteAt(Grid.offset(0, 0))); - assertEquals('B', grid.byteAt(Grid.offset(0, 1))); - assertEquals('C', grid.byteAt(Grid.offset(0, 2))); + assertEquals('A', grid.byteAt(OFF_0_0)); + assertEquals('B', grid.byteAt(OFF_0_1)); + assertEquals('C', grid.byteAt(OFF_0_2)); // 4. Partial placement then conflict (rollback) grid = Grid.createEmpty(); - grid.setLetter(Grid.offset(0, 2), (byte) 'X'); // Conflict at the end + grid.setLetter(OFF_0_2, LETTER_X); // Conflict at the end assertFalse(placeWord(grid, s, w1, undoBuffer, 3)); // Verify grid is still empty (except for 'X') - assertEquals(DASH, grid.byteAt(Grid.offset(0, 0))); - assertEquals(DASH, grid.byteAt(Grid.offset(0, 1))); - assertEquals('X', grid.byteAt(Grid.offset(0, 2))); + assertEquals(DASH, grid.byteAt(OFF_0_0)); + assertEquals(DASH, grid.byteAt(OFF_0_1)); + assertEquals('X', grid.byteAt(OFF_0_2)); } @Test void testBacktrackingHelpers() { var grid = Grid.createEmpty(); // Slot at 0,1 length 2 - var key = (Grid.offset(0,0) << Slot.BIT_FOR_DIR) | 2; - var lo = (1L << Grid.offset(0, 1)) | (1L << Grid.offset(0, 2)); + var key = (OFF_0_0 << Slot.BIT_FOR_DIR) | (CLUE_RIGHT + 1); + var lo = (1L << OFF_0_1) | (1L << OFF_0_2); var s = Slot.from(key, lo, 0L); var w = Lemma.from("AZ"); var undoBuffer = new long[10]; var placed = placeWord(grid, s, w, undoBuffer, 0); assertTrue(placed); - assertEquals('A', grid.byteAt(Grid.offset(0, 1))); - assertEquals('Z', grid.byteAt(Grid.offset(0, 2))); + assertEquals('A', grid.byteAt(OFF_0_1)); + assertEquals('Z', grid.byteAt(OFF_0_2)); assertEquals(lo, undoBuffer[0]); grid.undoPlace( undoBuffer[0], undoBuffer[1]); - assertEquals(DASH, grid.byteAt(Grid.offset(0, 1))); - assertEquals(DASH, grid.byteAt(Grid.offset(0, 2))); + assertEquals(DASH, grid.byteAt(OFF_0_1)); + assertEquals(DASH, grid.byteAt(OFF_0_2)); } @Test void testInnerWorkings() { // 1. Test Slot.increasing - assertFalse(Slot.increasing(1)); // Left - assertTrue(Slot.increasing(2)); // Right - assertTrue(Slot.increasing(3)); // Down - assertFalse(Slot.increasing(4)); // Up + assertFalse(Slot.increasing(CLUE_LEFT + 1)); // Left + assertTrue(Slot.increasing(CLUE_RIGHT + 1)); // Right + assertTrue(Slot.increasing(CLUE_DOWN + 1)); // Down + assertFalse(Slot.increasing(CLUE_UP + 1)); // Up - var sInc = Slot.from((0 << Slot.BIT_FOR_DIR) | 2, 1L, 0L); + var sInc = Slot.from((0 << Slot.BIT_FOR_DIR) | CLUE_RIGHT + 1, 1L, 0L); assertTrue(sInc.increasing()); - var sDec = Slot.from((0 << Slot.BIT_FOR_DIR) | 1, 1L, 0L); + var sDec = Slot.from((0 << Slot.BIT_FOR_DIR) | CLUE_LEFT + 1, 1L, 0L); assertFalse(sDec.increasing()); // 2. Test slotScore