redo
This commit is contained in:
@@ -10,20 +10,12 @@ import puzzle.Riddle.ClueSign;
|
|||||||
import puzzle.Riddle.ExportedPuzzle;
|
import puzzle.Riddle.ExportedPuzzle;
|
||||||
import puzzle.Riddle.Placed;
|
import puzzle.Riddle.Placed;
|
||||||
import puzzle.Riddle.Rewards;
|
import puzzle.Riddle.Rewards;
|
||||||
import puzzle.Riddle.Vestigium;
|
import puzzle.Riddle.Signa;
|
||||||
import puzzle.Riddle.WordOut;
|
import puzzle.Riddle.WordOut;
|
||||||
import puzzle.SwedishGenerator.FillResult;
|
import puzzle.SwedishGenerator.FillResult;
|
||||||
import puzzle.SwedishGenerator.Grid;
|
import puzzle.SwedishGenerator.Grid;
|
||||||
import puzzle.SwedishGenerator.Slotinfo;
|
import puzzle.SwedishGenerator.Slotinfo;
|
||||||
import static precomp.Const9x8.CLUE_DOWN0;
|
|
||||||
import static precomp.Const9x8.CLUE_LEFT3;
|
|
||||||
import static precomp.Const9x8.CLUE_LEFT_TOP4;
|
|
||||||
import static precomp.Const9x8.CLUE_RIGHT1;
|
|
||||||
import static precomp.Const9x8.CLUE_RIGHT_TOP5;
|
|
||||||
import static precomp.Const9x8.CLUE_UP2;
|
|
||||||
import static puzzle.Clues.createEmpty;
|
|
||||||
import static puzzle.Masker.Slot;
|
import static puzzle.Masker.Slot;
|
||||||
import static puzzle.Masker.isLo;
|
|
||||||
import static puzzle.SwedishGenerator.X;
|
import static puzzle.SwedishGenerator.X;
|
||||||
|
|
||||||
@GenerateShapedCopies(
|
@GenerateShapedCopies(
|
||||||
@@ -33,22 +25,22 @@ import static puzzle.SwedishGenerator.X;
|
|||||||
)
|
)
|
||||||
public record Export() {
|
public record Export() {
|
||||||
|
|
||||||
public static final ThreadLocal<byte[]> BYTES = ThreadLocal.withInitial(() -> new byte[8]);
|
public record ExportTemplates(byte[] table, byte[] dashTable, byte[] wordBytes) { }
|
||||||
@Shaped static final String INIT_GRID_OUTPUT = Const9x8.INIT_GRID_OUTPUT;
|
|
||||||
@Shaped static final int R = Const9x8.R;
|
|
||||||
@Shaped static final int C = Const9x8.C;
|
|
||||||
@Shaped static final byte[] INIT_GRID_OUTPUT_ARR = Const9x8.INIT_GRID_OUTPUT_ARR;
|
|
||||||
@Shaped static final byte[] INIT_GRID_OUTPUT_DASH_ARR = Const9x8.INIT_GRID_OUTPUT_DASH_ARR;
|
|
||||||
@Shaped static final long MASK_HI = Const9x8.MASK_HI;
|
|
||||||
@Shaped static final long MASK_LO = Const9x8.MASK_LO;
|
|
||||||
|
|
||||||
static int HI(int in) { return in | 64; }
|
@Shaped static final int R = Const9x8.R;
|
||||||
static byte LETTER(int in) { return (byte) (in | 64); }
|
@Shaped static final int C = Const9x8.C;
|
||||||
static byte CLUE_CHAR(int s) { return (byte) (s | 48); }
|
@Shaped static final byte[] INIT_GRID_OUTPUT_ARR = Const9x8.INIT_GRID_OUTPUT_ARR;
|
||||||
static int INDEX_ROW(int idx) { return idx % R; }
|
@Shaped static final byte[] INIT_GRID_OUTPUT_DASH_ARR = Const9x8.INIT_GRID_OUTPUT_DASH_ARR;
|
||||||
static int INDEX_COL(int idx) { return idx / R; }
|
@Shaped static final long MASK_HI = Const9x8.MASK_HI;
|
||||||
static int INDEX(int r, int cols, int c) { return r * cols + c; }
|
@Shaped static final long MASK_LO = Const9x8.MASK_LO;
|
||||||
static int INDEX(int idx, int cols) { return INDEX_ROW(idx) * cols + INDEX_COL(idx); }
|
public static final ThreadLocal<ExportTemplates> BYTES = ThreadLocal.withInitial(
|
||||||
|
() -> new ExportTemplates(INIT_GRID_OUTPUT_ARR, INIT_GRID_OUTPUT_DASH_ARR, new byte[8]));
|
||||||
|
static int HI(int in) { return in | 64; }
|
||||||
|
static byte LETTER(int in) { return (byte) (in | 64); }
|
||||||
|
static byte CLUE_CHAR(int s) { return (byte) (s | 48); }
|
||||||
|
static int INDEX_ROW(int idx) { return idx % R; }
|
||||||
|
static int INDEX_COL(int idx) { return idx / R; }
|
||||||
|
static int INDEX(int idx, int cols) { return INDEX_ROW(idx) * cols + INDEX_COL(idx); }
|
||||||
|
|
||||||
record Lettrix(int index, byte letter) {
|
record Lettrix(int index, byte letter) {
|
||||||
|
|
||||||
@@ -59,47 +51,18 @@ public record Export() {
|
|||||||
public int index(int cols) { return (row() * cols) + col(); }
|
public int index(int cols) { return (row() * cols) + col(); }
|
||||||
}
|
}
|
||||||
public static String gridToString(Clues clues) {
|
public static String gridToString(Clues clues) {
|
||||||
val chars = INIT_GRID_OUTPUT_ARR.clone();
|
val chars = BYTES.get().table();
|
||||||
new Signa(clues).forEach(v -> chars[INDEX(v.index(), C + 1)] = CLUE_CHAR(v.clue()));
|
new Signa(clues).forEach(v -> chars[INDEX(v.index(), C + 1)] = CLUE_CHAR(v.clue()));
|
||||||
return new String(chars);
|
val result = new String(chars);
|
||||||
}
|
new Signa(clues).forEach(v -> chars[INDEX(v.index(), C + 1)] = ' ');
|
||||||
public record Signa(@Delegate Clues c) {
|
return result;
|
||||||
|
|
||||||
public static Signa of(Mask... cells) { return new Signa(createEmpty()).setClue(cells); }
|
|
||||||
public Signa setClue(Mask... cells) {
|
|
||||||
for (var cell : cells) {
|
|
||||||
if (isLo((cell.index()))) setClueLo(cell.lo(), cell.d());
|
|
||||||
else setClueHi(cell.hi(), cell.d());
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Signa deepCopyGrid() { return new Signa(new Clues(c.lo, c.hi, c.vlo, c.vhi, c.rlo, c.rhi, c.xlo, c.xhi)); }
|
|
||||||
@Delegate public Stream<Vestigium> stream() {
|
|
||||||
val stream = Stream.<Vestigium>builder();
|
|
||||||
for (var l = c.lo & ~c.xlo & ~c.rlo & c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_RIGHT1));
|
|
||||||
for (var l = c.lo & ~c.xlo & ~c.rlo & ~c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_DOWN0));
|
|
||||||
for (var l = c.lo & ~c.xlo & c.rlo & ~c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_UP2));
|
|
||||||
for (var l = c.lo & ~c.xlo & c.rlo & c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_LEFT3));
|
|
||||||
for (var l = c.lo & c.xlo & ~c.rlo & ~c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_LEFT_TOP4));
|
|
||||||
for (var l = c.lo & c.xlo & ~c.rlo & c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_RIGHT_TOP5));
|
|
||||||
|
|
||||||
for (var h = c.hi & ~c.xhi & ~c.rhi & c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(HI(Long.numberOfTrailingZeros(h)), CLUE_RIGHT1));
|
|
||||||
for (var h = c.hi & ~c.xhi & ~c.rhi & ~c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(HI(Long.numberOfTrailingZeros(h)), CLUE_DOWN0));
|
|
||||||
for (var h = c.hi & ~c.xhi & c.rhi & ~c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(HI(Long.numberOfTrailingZeros(h)), CLUE_UP2));
|
|
||||||
for (var h = c.hi & ~c.xhi & c.rhi & c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(HI(Long.numberOfTrailingZeros(h)), CLUE_LEFT3));
|
|
||||||
for (var h = c.hi & c.xhi & ~c.rhi & ~c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(HI(Long.numberOfTrailingZeros(h)), CLUE_LEFT_TOP4));
|
|
||||||
for (var h = c.hi & c.xhi & ~c.rhi & c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(HI(Long.numberOfTrailingZeros(h)), CLUE_RIGHT_TOP5));
|
|
||||||
|
|
||||||
return stream.build();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
record Puzzle(@Delegate Grid grid, Clues cl)
|
record Puzzle(@Delegate Grid grid, Clues cl)
|
||||||
implements Stream<Lettrix> {
|
implements Stream<Lettrix> {
|
||||||
|
|
||||||
public Puzzle(Clues clues) { this(Masker.toGrid(clues), clues); }
|
public Puzzle(Clues clues) { this(Masker.toGrid(clues), clues); }
|
||||||
public Puzzle(Signa clues) { this(clues.c); }
|
public Puzzle(Signa clues) { this(clues.c()); }
|
||||||
public @Delegate Stream<Lettrix> stream() {
|
public @Delegate Stream<Lettrix> stream() {
|
||||||
val stream = Stream.<Lettrix>builder();
|
val stream = Stream.<Lettrix>builder();
|
||||||
for (var l = grid.lo & MASK_LO & ~cl.lo; l != X; l &= l - 1) stream.accept(Lettrix.from(Long.numberOfTrailingZeros(l), grid.g));
|
for (var l = grid.lo & MASK_LO & ~cl.lo; l != X; l &= l - 1) stream.accept(Lettrix.from(Long.numberOfTrailingZeros(l), grid.g));
|
||||||
@@ -116,7 +79,7 @@ public record Export() {
|
|||||||
puzzle.stream().forEach((l) -> sb[l.index(C + 1)] = l.human());
|
puzzle.stream().forEach((l) -> sb[l.index(C + 1)] = l.human());
|
||||||
return new String(sb);
|
return new String(sb);
|
||||||
}
|
}
|
||||||
public String cluesGridToString() { return gridToString(clues.c); }
|
public String cluesGridToString() { return gridToString(clues.c()); }
|
||||||
public String gridRenderHuman() { return String.join("\n", exportGrid(_ -> (byte) ' ', INIT_GRID_OUTPUT_DASH_ARR).split("\n")); }
|
public String gridRenderHuman() { return String.join("\n", exportGrid(_ -> (byte) ' ', INIT_GRID_OUTPUT_DASH_ARR).split("\n")); }
|
||||||
public String gridGridToString() { return exportGrid(d1 -> d1, INIT_GRID_OUTPUT_ARR); }
|
public String gridGridToString() { return exportGrid(d1 -> d1, INIT_GRID_OUTPUT_ARR); }
|
||||||
public ExportedPuzzle exportFormatFromFilled(Rewards rewards, rci[] rcis) {
|
public ExportedPuzzle exportFormatFromFilled(Rewards rewards, rci[] rcis) {
|
||||||
@@ -159,7 +122,7 @@ public record Export() {
|
|||||||
var grid = new String(template).split("\n");
|
var grid = new String(template).split("\n");
|
||||||
// 5) words output with cropped coordinates
|
// 5) words output with cropped coordinates
|
||||||
|
|
||||||
val bytes = BYTES.get();
|
val bytes = BYTES.get().wordBytes();
|
||||||
var wordsOut = Arrays.stream(placed).map(p -> new WordOut(
|
var wordsOut = Arrays.stream(placed).map(p -> new WordOut(
|
||||||
p.lemma(),
|
p.lemma(),
|
||||||
p.startRow() - MINR,
|
p.startRow() - MINR,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import puzzle.Riddle.WordOut;
|
|||||||
import puzzle.SwedishGenerator.Rng;
|
import puzzle.SwedishGenerator.Rng;
|
||||||
import static puzzle.Export.Puzzle;
|
import static puzzle.Export.Puzzle;
|
||||||
import static puzzle.Export.PuzzleResult;
|
import static puzzle.Export.PuzzleResult;
|
||||||
import static puzzle.Export.Signa;
|
import static puzzle.Riddle.Signa;
|
||||||
import static puzzle.SwedishGenerator.Dict;
|
import static puzzle.SwedishGenerator.Dict;
|
||||||
import static puzzle.SwedishGenerator.Slotinfo;
|
import static puzzle.SwedishGenerator.Slotinfo;
|
||||||
import static puzzle.SwedishGenerator.fillMask;
|
import static puzzle.SwedishGenerator.fillMask;
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import puzzle.SwedishGenerator.Slotinfo;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.function.IntSupplier;
|
import java.util.function.IntSupplier;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
import java.util.stream.Stream;
|
||||||
import static precomp.Const9x8.CLUE_DOWN0;
|
import static precomp.Const9x8.CLUE_DOWN0;
|
||||||
import static precomp.Const9x8.CLUE_LEFT3;
|
import static precomp.Const9x8.CLUE_LEFT3;
|
||||||
import static precomp.Const9x8.CLUE_LEFT_TOP4;
|
import static precomp.Const9x8.CLUE_LEFT_TOP4;
|
||||||
@@ -17,6 +18,9 @@ import static precomp.Const9x8.CLUE_NONE;
|
|||||||
import static precomp.Const9x8.CLUE_RIGHT1;
|
import static precomp.Const9x8.CLUE_RIGHT1;
|
||||||
import static precomp.Const9x8.CLUE_RIGHT_TOP5;
|
import static precomp.Const9x8.CLUE_RIGHT_TOP5;
|
||||||
import static precomp.Const9x8.CLUE_UP2;
|
import static precomp.Const9x8.CLUE_UP2;
|
||||||
|
import static puzzle.Clues.createEmpty;
|
||||||
|
import static puzzle.Masker.isLo;
|
||||||
|
import static puzzle.SwedishGenerator.X;
|
||||||
public class Riddle {
|
public class Riddle {
|
||||||
|
|
||||||
public static IntStream cellWalk(int base, long lo, long hi) {
|
public static IntStream cellWalk(int base, long lo, long hi) {
|
||||||
@@ -138,4 +142,36 @@ public class Riddle {
|
|||||||
|
|
||||||
byte replace(byte data);
|
byte replace(byte data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record Signa(@Delegate Clues c) {
|
||||||
|
|
||||||
|
public static Signa of(Mask... cells) { return new Signa(createEmpty()).setClue(cells); }
|
||||||
|
public Signa setClue(Mask... cells) {
|
||||||
|
for (var cell : cells) {
|
||||||
|
if (isLo((cell.index()))) setClueLo(cell.lo(), cell.d());
|
||||||
|
else setClueHi(cell.hi(), cell.d());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Signa deepCopyGrid() { return new Signa(new Clues(c.lo, c.hi, c.vlo, c.vhi, c.rlo, c.rhi, c.xlo, c.xhi)); }
|
||||||
|
@Delegate public Stream<Vestigium> stream() {
|
||||||
|
val stream = Stream.<Vestigium>builder();
|
||||||
|
for (var l = c.lo & ~c.xlo & ~c.rlo & c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_RIGHT1));
|
||||||
|
for (var l = c.lo & ~c.xlo & ~c.rlo & ~c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_DOWN0));
|
||||||
|
for (var l = c.lo & ~c.xlo & c.rlo & ~c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_UP2));
|
||||||
|
for (var l = c.lo & ~c.xlo & c.rlo & c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_LEFT3));
|
||||||
|
for (var l = c.lo & c.xlo & ~c.rlo & ~c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_LEFT_TOP4));
|
||||||
|
for (var l = c.lo & c.xlo & ~c.rlo & c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), CLUE_RIGHT_TOP5));
|
||||||
|
|
||||||
|
for (var h = c.hi & ~c.xhi & ~c.rhi & c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(Export.HI(Long.numberOfTrailingZeros(h)), CLUE_RIGHT1));
|
||||||
|
for (var h = c.hi & ~c.xhi & ~c.rhi & ~c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(Export.HI(Long.numberOfTrailingZeros(h)), CLUE_DOWN0));
|
||||||
|
for (var h = c.hi & ~c.xhi & c.rhi & ~c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(Export.HI(Long.numberOfTrailingZeros(h)), CLUE_UP2));
|
||||||
|
for (var h = c.hi & ~c.xhi & c.rhi & c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(Export.HI(Long.numberOfTrailingZeros(h)), CLUE_LEFT3));
|
||||||
|
for (var h = c.hi & c.xhi & ~c.rhi & ~c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(Export.HI(Long.numberOfTrailingZeros(h)), CLUE_LEFT_TOP4));
|
||||||
|
for (var h = c.hi & c.xhi & ~c.rhi & c.vhi; h != X; h &= h - 1) stream.accept(new Vestigium(Export.HI(Long.numberOfTrailingZeros(h)), CLUE_RIGHT_TOP5));
|
||||||
|
|
||||||
|
return stream.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import org.junit.jupiter.api.Test;
|
|||||||
import puzzle.Export.Lettrix;
|
import puzzle.Export.Lettrix;
|
||||||
import puzzle.Export.Puzzle;
|
import puzzle.Export.Puzzle;
|
||||||
import puzzle.Export.PuzzleResult;
|
import puzzle.Export.PuzzleResult;
|
||||||
import puzzle.Export.Signa;
|
|
||||||
import puzzle.Main.Opts;
|
import puzzle.Main.Opts;
|
||||||
import puzzle.Riddle.Rewards;
|
import puzzle.Riddle.Rewards;
|
||||||
import puzzle.SwedishGenerator.Rng;
|
import puzzle.SwedishGenerator.Rng;
|
||||||
@@ -97,7 +96,7 @@ public class MainTest {
|
|||||||
}};
|
}};
|
||||||
@Test
|
@Test
|
||||||
void testExtractSlots() {
|
void testExtractSlots() {
|
||||||
var clues = Signa.of(r0c0d1);
|
var clues = Riddle.Signa.of(r0c0d1);
|
||||||
var grid = new Puzzle(clues);
|
var grid = new Puzzle(clues);
|
||||||
val g = grid.grid().g;
|
val g = grid.grid().g;
|
||||||
GridBuilder.placeWord(grid.grid(), g, r0c0d1.slotKey, (1L << OFF_0_1) | (1L << OFF_0_2), 0, AB);
|
GridBuilder.placeWord(grid.grid(), g, r0c0d1.slotKey, (1L << OFF_0_1) | (1L << OFF_0_2), 0, AB);
|
||||||
@@ -125,7 +124,7 @@ public class MainTest {
|
|||||||
@Test
|
@Test
|
||||||
void testForEachSlot() {
|
void testForEachSlot() {
|
||||||
var count = new AtomicInteger(0);
|
var count = new AtomicInteger(0);
|
||||||
Masker.forEachSlot(Signa.of(r0c0d1).c(), (key, lo, hi) -> {
|
Masker.forEachSlot(Riddle.Signa.of(r0c0d1).c(), (key, lo, hi) -> {
|
||||||
count.incrementAndGet();
|
count.incrementAndGet();
|
||||||
assertEquals(8, Long.bitCount(lo) + Long.bitCount(hi));
|
assertEquals(8, Long.bitCount(lo) + Long.bitCount(hi));
|
||||||
assertEquals(0, Masker.IT[Long.numberOfTrailingZeros(lo)].r());
|
assertEquals(0, Masker.IT[Long.numberOfTrailingZeros(lo)].r());
|
||||||
@@ -144,7 +143,7 @@ public class MainTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
public void testGridBasics() {
|
public void testGridBasics() {
|
||||||
var clues = Signa.of(r2c1d2);
|
var clues = Riddle.Signa.of(r2c1d2);
|
||||||
var grid = new Puzzle(clues);
|
var grid = new Puzzle(clues);
|
||||||
r1c1.or(r0c1).lo();
|
r1c1.or(r0c1).lo();
|
||||||
// Test set/get
|
// Test set/get
|
||||||
@@ -177,7 +176,7 @@ public class MainTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
public void testCluesDeepCopy() {
|
public void testCluesDeepCopy() {
|
||||||
var clues = Signa.of(r0c0d1, r0c1d2, r1c0d3, r1c1d0);
|
var clues = Riddle.Signa.of(r0c0d1, r0c1d2, r1c0d3, r1c1d0);
|
||||||
|
|
||||||
var copy = clues.deepCopyGrid();
|
var copy = clues.deepCopyGrid();
|
||||||
var clueMap = clues.stream().collect(Collectors.toMap(Riddle.Vestigium::index, Riddle.Vestigium::clue));
|
var clueMap = clues.stream().collect(Collectors.toMap(Riddle.Vestigium::index, Riddle.Vestigium::clue));
|
||||||
@@ -190,11 +189,11 @@ public class MainTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
public void testMini() {
|
public void testMini() {
|
||||||
Assertions.assertTrue(Signa.of(r1c1d3).isClueLo(OFF_1_1));
|
Assertions.assertTrue(Riddle.Signa.of(r1c1d3).isClueLo(OFF_1_1));
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testFiller2() {
|
void testFiller2() {
|
||||||
var mask = Signa.of(
|
var mask = Riddle.Signa.of(
|
||||||
r0c0d1,
|
r0c0d1,
|
||||||
r0c3d0, r0c4d0, r0c5d0, r0c6d0, r0c7d0, r0c8d0,
|
r0c3d0, r0c4d0, r0c5d0, r0c6d0, r0c7d0, r0c8d0,
|
||||||
r1c0d1,
|
r1c0d1,
|
||||||
@@ -204,7 +203,7 @@ public class MainTest {
|
|||||||
r5c0d3,
|
r5c0d3,
|
||||||
r6c0d3,
|
r6c0d3,
|
||||||
r7c0d2, r7c1d2, r7c2d2, r7c8d3
|
r7c0d2, r7c1d2, r7c2d2, r7c8d3
|
||||||
);
|
);
|
||||||
Assertions.assertEquals(20, mask.clueCount());
|
Assertions.assertEquals(20, mask.clueCount());
|
||||||
val map = mask.stream().collect(Collectors.toMap(Riddle.Vestigium::index, Riddle.Vestigium::clue));
|
val map = mask.stream().collect(Collectors.toMap(Riddle.Vestigium::index, Riddle.Vestigium::clue));
|
||||||
Assertions.assertEquals(20, map.size());
|
Assertions.assertEquals(20, map.size());
|
||||||
@@ -216,7 +215,7 @@ public class MainTest {
|
|||||||
void testFiller() {
|
void testFiller() {
|
||||||
System.out.println(DictData950.DICT950.index().length);
|
System.out.println(DictData950.DICT950.index().length);
|
||||||
val rng = new Rng(-343913721);
|
val rng = new Rng(-343913721);
|
||||||
var mask = Signa.of(
|
var mask = Riddle.Signa.of(
|
||||||
r0c3d3, r0c6d3, r0c7d0, r0c8d0,
|
r0c3d3, r0c6d3, r0c7d0, r0c8d0,
|
||||||
r1c1d1,
|
r1c1d1,
|
||||||
r2c1d1,
|
r2c1d1,
|
||||||
@@ -225,13 +224,13 @@ public class MainTest {
|
|||||||
r5c1d1,
|
r5c1d1,
|
||||||
r6c1d1, r6c8d2,
|
r6c1d1, r6c8d2,
|
||||||
r7c0d2, r7c1d1, r7c4d2, r7c5d2, r7c8d3
|
r7c0d2, r7c1d1, r7c4d2, r7c5d2, r7c8d3
|
||||||
);
|
);
|
||||||
var slotInfo = Masker.slots(mask.c(), DictData950.DICT950.index(), DictData950.DICT950.reversed());
|
var slotInfo = Masker.slots(mask.c(), DictData950.DICT950.index(), DictData950.DICT950.reversed());
|
||||||
var grid = Masker.grid(slotInfo);
|
var grid = Masker.grid(slotInfo);
|
||||||
var filled = fillMask(rng, slotInfo, grid.lo, grid.hi, grid.g);
|
var filled = fillMask(rng, slotInfo, grid.lo, grid.hi, grid.g);
|
||||||
Assertions.assertTrue(filled.ok(), "Puzzle generation failed (not ok)");
|
Assertions.assertTrue(filled.ok(), "Puzzle generation failed (not ok)");
|
||||||
Assertions.assertEquals(17, Slotinfo.wordCount(0, slotInfo), "Number of assigned words changed");
|
Assertions.assertEquals(17, Slotinfo.wordCount(0, slotInfo), "Number of assigned words changed");
|
||||||
Assertions.assertEquals("BEADEMT", Lemma.asWord(slotInfo[0].assign().w, Export.BYTES.get()));
|
Assertions.assertEquals("BEADEMT", Lemma.asWord(slotInfo[0].assign().w, Export.BYTES.get().wordBytes()));
|
||||||
Assertions.assertEquals(74732156493031040L, grid.lo);
|
Assertions.assertEquals(74732156493031040L, grid.lo);
|
||||||
Assertions.assertEquals(193L, grid.hi);
|
Assertions.assertEquals(193L, grid.hi);
|
||||||
var g = new Puzzle(grid, mask.c());
|
var g = new Puzzle(grid, mask.c());
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import lombok.val;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import puzzle.Export.Puzzle;
|
import puzzle.Export.Puzzle;
|
||||||
import puzzle.Export.PuzzleResult;
|
import puzzle.Export.PuzzleResult;
|
||||||
import puzzle.Export.Signa;
|
import puzzle.Riddle.Signa;
|
||||||
import puzzle.Riddle.Rewards;
|
import puzzle.Riddle.Rewards;
|
||||||
import puzzle.SwedishGenerator.Assign;
|
import puzzle.SwedishGenerator.Assign;
|
||||||
import puzzle.SwedishGenerator.FillResult;
|
import puzzle.SwedishGenerator.FillResult;
|
||||||
@@ -99,14 +99,14 @@ public class MarkerTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testSimilarity() {
|
void testSimilarity() {
|
||||||
var a = Signa.of(r0c0d1, r2c1d0).c();
|
var a = Riddle.Signa.of(r0c0d1, r2c1d0).c();
|
||||||
var b = Signa.of(r0c0d1, r2c1d0).c();
|
var b = Riddle.Signa.of(r0c0d1, r2c1d0).c();
|
||||||
|
|
||||||
// Identity
|
// Identity
|
||||||
assertEquals(1.0, Masker.similarity(a, b), 0.001);
|
assertEquals(1.0, Masker.similarity(a, b), 0.001);
|
||||||
|
|
||||||
// Different direction
|
// Different direction
|
||||||
var c = Signa.of(r0c0d0, r2c1d0);
|
var c = Riddle.Signa.of(r0c0d0, r2c1d0);
|
||||||
assertTrue(Masker.similarity(a, c.c()) < 1.0);
|
assertTrue(Masker.similarity(a, c.c()) < 1.0);
|
||||||
|
|
||||||
// Completely different
|
// Completely different
|
||||||
@@ -122,10 +122,10 @@ public class MarkerTest {
|
|||||||
assertTrue(masker.isValid(Clues.createEmpty()));
|
assertTrue(masker.isValid(Clues.createEmpty()));
|
||||||
|
|
||||||
// Valid clue: Right from (0,0) in 9x8 grid. Length is 8.
|
// Valid clue: Right from (0,0) in 9x8 grid. Length is 8.
|
||||||
assertTrue(masker.isValid(Signa.of(r0c0d1).c()));
|
assertTrue(masker.isValid(Riddle.Signa.of(r0c0d1).c()));
|
||||||
|
|
||||||
// Invalid clue: Right from (0,7) in 9x8 grid. Length is 1 (too short if MIN_LEN >= 2).
|
// Invalid clue: Right from (0,7) in 9x8 grid. Length is 1 (too short if MIN_LEN >= 2).
|
||||||
assertFalse(masker.isValid(Signa.of(r0c7d1).c()));
|
assertFalse(masker.isValid(Riddle.Signa.of(r0c7d1).c()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -157,18 +157,18 @@ public class MarkerTest {
|
|||||||
// Clue 1: (0,0) Right. Slot cells: (0,1), (0,2), (0,3), (0,4), (0,5), (0,6), (0,7), (0,8)
|
// Clue 1: (0,0) Right. Slot cells: (0,1), (0,2), (0,3), (0,4), (0,5), (0,6), (0,7), (0,8)
|
||||||
// Clue 2: (1,2) Up. Slot cells: (0,2)
|
// Clue 2: (1,2) Up. Slot cells: (0,2)
|
||||||
// Intersection is exactly 1 cell (0,2). Valid.
|
// Intersection is exactly 1 cell (0,2). Valid.
|
||||||
assertTrue(masker.isValid(Signa.of(r0c0d1, r2c2d2).c()));
|
assertTrue(masker.isValid(Riddle.Signa.of(r0c0d1, r2c2d2).c()));
|
||||||
|
|
||||||
// Clue 3: (1,1) Right. Slot cells: (1,2), (1,3), ...
|
// Clue 3: (1,1) Right. Slot cells: (1,2), (1,3), ...
|
||||||
// No intersection with Clue 1 or 2. Valid.
|
// No intersection with Clue 1 or 2. Valid.
|
||||||
assertTrue(masker.isValid(Signa.of(r0c0d1, r2c2d2, r1c1d1).c()));
|
assertTrue(masker.isValid(Riddle.Signa.of(r0c0d1, r2c2d2, r1c1d1).c()));
|
||||||
|
|
||||||
// Now create a violation: two slots sharing 2 cells.
|
// Now create a violation: two slots sharing 2 cells.
|
||||||
// We can do this with Corner Down and another clue.
|
// We can do this with Corner Down and another clue.
|
||||||
// Clue A: (0,0) Corner Down. Starts at (0,1) goes down: (0,1), (1,1), (2,1), (3,1), ...
|
// Clue A: (0,0) Corner Down. Starts at (0,1) goes down: (0,1), (1,1), (2,1), (3,1), ...
|
||||||
// Clue B: (0,2) Corner Down Left. Starts at (0,1) goes down: (0,1), (1,1), (2,1), ...
|
// Clue B: (0,2) Corner Down Left. Starts at (0,1) goes down: (0,1), (1,1), (2,1), ...
|
||||||
// They share MANY cells starting from (0,1).
|
// They share MANY cells starting from (0,1).
|
||||||
assertFalse(masker.isValid(Signa.of(r0c0d4, r0c2d5).c()));
|
assertFalse(masker.isValid(Riddle.Signa.of(r0c0d4, r0c2d5).c()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -250,7 +250,7 @@ public class MarkerTest {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testCornerDownSlot() {
|
void testCornerDownSlot() {
|
||||||
var clues = Signa.of(r0c0d4);
|
var clues = Riddle.Signa.of(r0c0d4);
|
||||||
// Clue op (0,0), type 4 (Corner Down)
|
// Clue op (0,0), type 4 (Corner Down)
|
||||||
|
|
||||||
assertEquals(r0c0d4.d, clues.getDir(r0c0d4.index));
|
assertEquals(r0c0d4.d, clues.getDir(r0c0d4.index));
|
||||||
@@ -274,14 +274,14 @@ public class MarkerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCornerDownExtraction() {
|
void testCornerDownExtraction() {
|
||||||
var slots = Masker.slots(Signa.of(r0c0d4).c(), DictData950.DICT950);
|
var slots = Masker.slots(Riddle.Signa.of(r0c0d4).c(), DictData950.DICT950);
|
||||||
assertEquals(1, slots.length);
|
assertEquals(1, slots.length);
|
||||||
assertEquals(r0c0d4.d, Masker.Slot.dir(slots[0].key()));
|
assertEquals(r0c0d4.d, Masker.Slot.dir(slots[0].key()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCornerDownLeftSlot() {
|
void testCornerDownLeftSlot() {
|
||||||
var clues = Signa.of(r0c1d5);
|
var clues = Riddle.Signa.of(r0c1d5);
|
||||||
|
|
||||||
assertEquals(r0c1d5.d, clues.getDir(r0c1d5.index));
|
assertEquals(r0c1d5.d, clues.getDir(r0c1d5.index));
|
||||||
|
|
||||||
@@ -304,13 +304,13 @@ public class MarkerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCornerDownLeftExtraction() {
|
void testCornerDownLeftExtraction() {
|
||||||
var slots = Masker.slots(Signa.of(r0c1d5).c(), DictData950.DICT950.index(), DictData950.DICT950.reversed());
|
var slots = Masker.slots(Riddle.Signa.of(r0c1d5).c(), DictData950.DICT950.index(), DictData950.DICT950.reversed());
|
||||||
assertEquals(1, slots.length);
|
assertEquals(1, slots.length);
|
||||||
assertEquals(r0c1d5.d, Masker.Slot.dir(slots[0].key()));
|
assertEquals(r0c1d5.d, Masker.Slot.dir(slots[0].key()));
|
||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testExportFormatFromFilled() {
|
void testExportFormatFromFilled() {
|
||||||
val clues = Signa.of(r0c0d1, r0c5d3);
|
val clues = Riddle.Signa.of(r0c0d1, r0c5d3);
|
||||||
var grid = new Puzzle(clues);
|
var grid = new Puzzle(clues);
|
||||||
|
|
||||||
// key = (cellIndex << 2) | (direction)
|
// key = (cellIndex << 2) | (direction)
|
||||||
@@ -378,7 +378,7 @@ public class MarkerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testShardToClue() {
|
void testShardToClue() {
|
||||||
var bytes = Export.BYTES.get();
|
var bytes = Export.BYTES.get().wordBytes();
|
||||||
for (var length = 2; length <= 8; length++) {
|
for (var length = 2; length <= 8; length++) {
|
||||||
val entry = DictData950.DICT950.index()[length];
|
val entry = DictData950.DICT950.index()[length];
|
||||||
if (entry == null) continue;
|
if (entry == null) continue;
|
||||||
@@ -399,7 +399,7 @@ public class MarkerTest {
|
|||||||
@Test
|
@Test
|
||||||
void testSpecificWords() {
|
void testSpecificWords() {
|
||||||
// These words are known to be in the CSV and likely in the dictionary
|
// These words are known to be in the CSV and likely in the dictionary
|
||||||
var bytes = Export.BYTES.get();
|
var bytes = Export.BYTES.get().wordBytes();
|
||||||
var testWords = new String[]{ "EEN", "NAAR", "IEDEREEN" };
|
var testWords = new String[]{ "EEN", "NAAR", "IEDEREEN" };
|
||||||
for (var wStr : testWords) {
|
for (var wStr : testWords) {
|
||||||
var w = Lemma.from(wStr);
|
var w = Lemma.from(wStr);
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import anno.DictGen;
|
|||||||
import anno.Dictionaries;
|
import anno.Dictionaries;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import puzzle.Export.Signa;
|
|
||||||
import puzzle.SwedishGenerator.Rng;
|
import puzzle.SwedishGenerator.Rng;
|
||||||
import puzzle.SwedishGenerator.Slotinfo;
|
import puzzle.SwedishGenerator.Slotinfo;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
@@ -113,7 +112,7 @@ public class PerformanceTest {
|
|||||||
void testIncrementalComplexity() {
|
void testIncrementalComplexity() {
|
||||||
|
|
||||||
// Use the complex mask from Main.java
|
// Use the complex mask from Main.java
|
||||||
var mask = Signa.of(
|
var mask = Riddle.Signa.of(
|
||||||
r0c0d1, r0c5d0, r0c6d0, r0c7d0, r0c8d0,
|
r0c0d1, r0c5d0, r0c6d0, r0c7d0, r0c8d0,
|
||||||
r1c0d1,
|
r1c0d1,
|
||||||
r2c0d0, r2c1d0, r2c3d0, r2c4d1,
|
r2c0d0, r2c1d0, r2c3d0, r2c4d1,
|
||||||
@@ -122,7 +121,7 @@ public class PerformanceTest {
|
|||||||
r5c2d2, r5c4d1,
|
r5c2d2, r5c4d1,
|
||||||
r6c2d1,
|
r6c2d1,
|
||||||
r7c0d2, r7c1d2, r7c2d1, r7c7d2, r7c8d2
|
r7c0d2, r7c1d2, r7c2d1, r7c7d2, r7c8d2
|
||||||
);
|
);
|
||||||
val allSlots = Masker.slots(mask.c(), DICT900);
|
val allSlots = Masker.slots(mask.c(), DICT900);
|
||||||
//mask.toGrid()
|
//mask.toGrid()
|
||||||
System.out.println("[DEBUG_LOG] \n--- Incremental Complexity Test ---");
|
System.out.println("[DEBUG_LOG] \n--- Incremental Complexity Test ---");
|
||||||
@@ -143,7 +142,7 @@ public class PerformanceTest {
|
|||||||
val rng = new Rng(42);
|
val rng = new Rng(42);
|
||||||
|
|
||||||
// A single horizontal slot at (0,0)
|
// A single horizontal slot at (0,0)
|
||||||
val mask = Signa.of(r0c0d1);
|
val mask = Riddle.Signa.of(r0c0d1);
|
||||||
val slots = Masker.slots(mask.c(), DICT800);
|
val slots = Masker.slots(mask.c(), DICT800);
|
||||||
|
|
||||||
System.out.println("[DEBUG_LOG] \n--- Single Slot Resolution ---");
|
System.out.println("[DEBUG_LOG] \n--- Single Slot Resolution ---");
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import precomp.Neighbors9x8;
|
|||||||
import puzzle.DictJavaGeneratorMulti.DictEntryDTO.IntListDTO;
|
import puzzle.DictJavaGeneratorMulti.DictEntryDTO.IntListDTO;
|
||||||
import puzzle.Export.Lettrix;
|
import puzzle.Export.Lettrix;
|
||||||
import puzzle.Export.Puzzle;
|
import puzzle.Export.Puzzle;
|
||||||
import puzzle.Export.Signa;
|
import puzzle.Riddle.Signa;
|
||||||
import puzzle.Masker.Slot;
|
import puzzle.Masker.Slot;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
@@ -126,7 +126,7 @@ public class SwedishGeneratorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPatternForSlotAllLetters() {
|
void testPatternForSlotAllLetters() {
|
||||||
var grid = new Puzzle(Signa.of(r0c0d1));
|
var grid = new Puzzle(Riddle.Signa.of(r0c0d1));
|
||||||
GridBuilder.placeWord(grid.grid(), grid.grid().g, r0c0d1.slotKey, r0c1.or(r0c2).or(r0c3).lo(), X, ABC);
|
GridBuilder.placeWord(grid.grid(), grid.grid().g, r0c0d1.slotKey, r0c1.or(r0c2).or(r0c3).lo(), X, ABC);
|
||||||
val map = grid.collect(Collectors.toMap(Lettrix::index, Lettrix::letter));
|
val map = grid.collect(Collectors.toMap(Lettrix::index, Lettrix::letter));
|
||||||
assertEquals(LETTER_A, map.get(OFF_0_1));
|
assertEquals(LETTER_A, map.get(OFF_0_1));
|
||||||
@@ -246,7 +246,7 @@ public class SwedishGeneratorTest {
|
|||||||
void testForEachSlotAndExtractSlots() {
|
void testForEachSlotAndExtractSlots() {
|
||||||
// This should detect a slot starting at 0,1 with length 2 (0,1 and 0,2)
|
// This should detect a slot starting at 0,1 with length 2 (0,1 and 0,2)
|
||||||
var dict = DictJavaGeneratorMulti.Dicts.makeDict(WORDS2);
|
var dict = DictJavaGeneratorMulti.Dicts.makeDict(WORDS2);
|
||||||
var slots = Masker.extractSlots(Signa.of(r0c0d1).c(), dict.index(), dict.reversed());
|
var slots = Masker.extractSlots(Riddle.Signa.of(r0c0d1).c(), dict.index(), dict.reversed());
|
||||||
assertEquals(1, slots.length);
|
assertEquals(1, slots.length);
|
||||||
var s = slots[0];
|
var s = slots[0];
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ import gen.Test123X_Neighbors9x8;
|
|||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import puzzle.Export.Signa;
|
|
||||||
import puzzle.Riddle.Rewards;
|
import puzzle.Riddle.Rewards;
|
||||||
|
import puzzle.Riddle.Signa;
|
||||||
import puzzle.SwedishGenerator.Rng;
|
import puzzle.SwedishGenerator.Rng;
|
||||||
import puzzle.dict800_4.DictData800_4;
|
import puzzle.dict800_4.DictData800_4;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
@@ -31,7 +31,7 @@ public class TestDuplication {
|
|||||||
}
|
}
|
||||||
@Test
|
@Test
|
||||||
void testFiller2() {
|
void testFiller2() {
|
||||||
var mask = Signa.of(
|
var mask = Riddle.Signa.of(
|
||||||
r0c0d4, r0c2d0,
|
r0c0d4, r0c2d0,
|
||||||
r1c0d1,
|
r1c0d1,
|
||||||
r2c0d1,
|
r2c0d1,
|
||||||
@@ -45,7 +45,7 @@ public class TestDuplication {
|
|||||||
grid.lo = Masker_Neighbors3x4.MASK_LO & ~mask.c().lo;
|
grid.lo = Masker_Neighbors3x4.MASK_LO & ~mask.c().lo;
|
||||||
grid.hi = Masker_Neighbors3x4.MASK_HI & ~mask.c().hi;
|
grid.hi = Masker_Neighbors3x4.MASK_HI & ~mask.c().hi;
|
||||||
var grid1 = new ExportX_Const3x4.Puzzle(grid, mask.c());
|
var grid1 = new ExportX_Const3x4.Puzzle(grid, mask.c());
|
||||||
var result = new ExportX_Const3x4.PuzzleResult(new ExportX_Const3x4.Signa(mask.c()), grid1, slots, filled);
|
var result = new ExportX_Const3x4.PuzzleResult(new Signa(mask.c()), grid1, slots, filled);
|
||||||
if (filled.ok()) {
|
if (filled.ok()) {
|
||||||
System.out.println(filled);
|
System.out.println(filled);
|
||||||
val res = result.exportFormatFromFilled(new Rewards(0, 0, 0), Masker_Neighbors3x4.IT);
|
val res = result.exportFormatFromFilled(new Rewards(0, 0, 0), Masker_Neighbors3x4.IT);
|
||||||
|
|||||||
Reference in New Issue
Block a user