This commit is contained in:
mike
2026-01-23 20:33:36 +01:00
parent fa3e8ef1ed
commit 73192f5905
8 changed files with 132 additions and 116 deletions

View File

@@ -3,27 +3,28 @@ package puzzle;
import module java.base;
import anno.GenerateShapedCopies;
import anno.Shaped;
import lombok.AllArgsConstructor;
import lombok.experimental.Delegate;
import lombok.val;
import precomp.Const9x8;
import puzzle.Meta.ShardLem;
import puzzle.Replacar.Rell;
import puzzle.Riddle.ExportedPuzzle;
import puzzle.Riddle.Placed;
import puzzle.Riddle.Rewards;
import puzzle.Riddle.Vestigium;
import puzzle.Riddle.WordOut;
import puzzle.SwedishGenerator.FillResult;
import puzzle.SwedishGenerator.Grid;
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_NONE;
import static precomp.Const9x8.CLUE_RIGHT1;
import static precomp.Const9x8.CLUE_RIGHT_TOP5;
import static precomp.Const9x8.CLUE_UP2;
import static puzzle.Export.Clue.DOWN0;
import static puzzle.Export.Clue.RIGHT1;
import static puzzle.Riddle.Clue.DOWN0;
import static puzzle.Riddle.Clue.RIGHT1;
import static puzzle.Clues.createEmpty;
import static puzzle.Masker.Slot;
import static puzzle.SwedishGenerator.Lemma;
import static puzzle.SwedishGenerator.X;
@GenerateShapedCopies(
@@ -47,22 +48,6 @@ public record Export() {
static int INDEX_ROW(int idx) { return idx % R; }
static int INDEX_COL(int idx) { return idx / R; }
static int INDEX(int r, int cols, int c) { return r * cols + c; }
@AllArgsConstructor
enum Clue {
DOWN0(CLUE_DOWN0, 'B', 'b'),
RIGHT1(CLUE_RIGHT1, 'A', 'a'),
UP2(CLUE_UP2, 'C', 'c'),
LEFT3(CLUE_LEFT3, 'D', 'd'),
LEFT_TOP4(CLUE_LEFT_TOP4, 'E', 'e'),
RIGHT_TOP5(CLUE_RIGHT_TOP5, 'F', 'f'),
NONE(CLUE_NONE, '?', '?');
final byte dir;
final char slotChar, clueChar;
private static final Clue[] CLUES = new Clue[]{ DOWN0, RIGHT1, UP2, LEFT3, LEFT_TOP4, RIGHT_TOP5, NONE, NONE, NONE };
public static Clue from(int dir) { return CLUES[dir]; }
}
public record Vestigium(int index, int clue) { }
public record Signa(@Delegate Clues c) {
@@ -83,13 +68,13 @@ public record Export() {
public Signa deepCopyGrid() { return new Signa(new Clues(c.lo, c.hi, c.vlo, c.vhi, c.rlo, c.rhi, c.xlo, c.xhi)); }
String gridToString() {
var sb = new StringBuilder(INIT_GRID_OUTPUT);
stream().forEach(v -> sb.setCharAt(INDEX(INDEX_ROW(v.index), C + 1, INDEX_COL(v.index)), CLUE_CHAR(v.clue)));
stream().forEach(v -> sb.setCharAt(INDEX(INDEX_ROW(v.index()), C + 1, INDEX_COL(v.index())), CLUE_CHAR(v.clue())));
return sb.toString();
}
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), RIGHT1.dir));
for (var l = c.lo & ~c.xlo & ~c.rlo & ~c.vlo; l != X; l &= l - 1) stream.accept(new Vestigium(Long.numberOfTrailingZeros(l), DOWN0.dir));
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));
@@ -114,7 +99,7 @@ public record Export() {
public @Delegate Stream<Lettrix> stream() {
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 h = grid.hi & MASK_HI & ~cl.hi; h != X; h &= h - 1) stream.accept(Lettrix.from(64 | Long.numberOfTrailingZeros(h), grid.g));
for (var h = grid.hi & MASK_HI & ~cl.hi; h != X; h &= h - 1) stream.accept(Lettrix.from(HI(Long.numberOfTrailingZeros(h)), grid.g));
return stream.build();
}
public String[] exportGrid(Slotinfo[] slots, Replacar clueChar, char emptyFallback) {
@@ -179,56 +164,6 @@ public record Export() {
}
record Placed(long lemma, int slotKey, rci[] cells) {
public static final char HORIZONTAL = 'h';
static final char VERTICAL = 'v';
static final char[] DIRECTION = { Placed.VERTICAL, Placed.HORIZONTAL, Placed.VERTICAL, Placed.HORIZONTAL, Placed.VERTICAL, Placed.VERTICAL };
public int arrowCol() { return cells[0].c(); }
public int arrowRow() { return cells[0].r(); }
public int startRow() { return cells[1].r(); }
public int startCol() { return cells[1].c(); }
public boolean isReversed() { return !Slotinfo.increasing(slotKey); }
public char direction() { return DIRECTION[Slot.dir(slotKey)]; }
}
public record Rewards(int coins, int stars, int hints) { }
public record WordOut(String word, int[] cell, int startRow, int startCol, char direction, int arrowRow, int arrowCol, boolean isReversed, int complex, String[] clue) {
record ShaLemma(String word, @Delegate ShardLem rec) { }
private static ShaLemma lookup(long w, byte[] bytes) {
try {
val rec = Meta.lookupSilent(w);
System.out.println("\nQuery: w=" + w + " -> i=" + rec.mmap());
var word1 = Lemma.asWord(w, bytes);
System.out.println(" word=" + word1 + "\n" + " simpel=" + rec.simpel() + "\n" + " clues=" + Arrays.toString(rec.clues()));
return new ShaLemma(word1, rec);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static long reverse(long w) {
int L = Lemma.unpackSize(w) + 1;
long letters = w & Lemma.LETTER_MASK;
long rev = 0;
for (int i = 0; i < L; i++) {
long letter = (letters >>> (5 * i)) & 31;
rev |= (letter << (5 * (L - 1 - i)));
}
return (w & ~Lemma.LETTER_MASK) | rev;
}
public WordOut(long l, int startRow, int startCol, char d, int arrowRow, int arrowCol, boolean isReversed, byte[] bytes) {
val meta = lookup(isReversed ? reverse(l) : l, bytes);
this(meta.word, new int[]{ arrowRow, arrowCol, startRow, startCol }, startRow, startCol, d, arrowRow, arrowCol, isReversed,
meta.simpel(), meta.clues());
}
}
public record ExportedPuzzle(String[] grid, WordOut[] words, int difficulty, Rewards rewards) { }
public record PuzzleResult(Signa clues, Puzzle grid, Slotinfo[] slots, FillResult filled) {
public String cluesGridToString() {
@@ -264,7 +199,7 @@ public record Export() {
int maxR = Integer.MIN_VALUE, maxC = Integer.MIN_VALUE;
for (var rc : placed) {
for (var it : rc.cells) {
for (var it : rc.cells()) {
minR = Math.min(minR, it.r());
minC = Math.min(minC, it.c());
maxR = Math.max(maxR, it.r());
@@ -292,7 +227,7 @@ public record Export() {
val bytes = BYTES.get();
var wordsOut = Arrays.stream(placed).map(p -> new WordOut(
p.lemma,
p.lemma(),
p.startRow() - MINR,
p.startCol() - MINC,
p.direction(),
@@ -300,7 +235,7 @@ public record Export() {
p.arrowCol() - MINC,
p.isReversed(), bytes
)).toArray(WordOut[]::new);
var total = 0.0001d + Arrays.stream(wordsOut).mapToDouble(WordOut::complex).sum();
var total = 0.0001d + Arrays.stream(wordsOut).mapToDouble(Riddle.WordOut::complex).sum();
return new ExportedPuzzle(grid, wordsOut, (int) (total / wordsOut.length), rewards);
}