This commit is contained in:
mike
2026-01-23 22:17:13 +01:00
parent d9b565301f
commit 282ec56f19
8 changed files with 95 additions and 98 deletions

View File

@@ -10,20 +10,12 @@ import puzzle.Riddle.ClueSign;
import puzzle.Riddle.ExportedPuzzle;
import puzzle.Riddle.Placed;
import puzzle.Riddle.Rewards;
import puzzle.Riddle.Vestigium;
import puzzle.Riddle.Signa;
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_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.isLo;
import static puzzle.SwedishGenerator.X;
@GenerateShapedCopies(
@@ -33,22 +25,22 @@ import static puzzle.SwedishGenerator.X;
)
public record Export() {
public static final ThreadLocal<byte[]> BYTES = ThreadLocal.withInitial(() -> new byte[8]);
@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;
public record ExportTemplates(byte[] table, byte[] dashTable, byte[] wordBytes) { }
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 r, int cols, int c) { return r * cols + c; }
static int INDEX(int idx, int cols) { return INDEX_ROW(idx) * cols + INDEX_COL(idx); }
@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;
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) {
@@ -59,47 +51,18 @@ public record Export() {
public int index(int cols) { return (row() * cols) + col(); }
}
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()));
return new String(chars);
}
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(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();
}
val result = new String(chars);
new Signa(clues).forEach(v -> chars[INDEX(v.index(), C + 1)] = ' ');
return result;
}
record Puzzle(@Delegate Grid grid, Clues cl)
implements Stream<Lettrix> {
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() {
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));
@@ -116,7 +79,7 @@ public record Export() {
puzzle.stream().forEach((l) -> sb[l.index(C + 1)] = l.human());
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 gridGridToString() { return exportGrid(d1 -> d1, INIT_GRID_OUTPUT_ARR); }
public ExportedPuzzle exportFormatFromFilled(Rewards rewards, rci[] rcis) {
@@ -159,7 +122,7 @@ public record Export() {
var grid = new String(template).split("\n");
// 5) words output with cropped coordinates
val bytes = BYTES.get();
val bytes = BYTES.get().wordBytes();
var wordsOut = Arrays.stream(placed).map(p -> new WordOut(
p.lemma(),
p.startRow() - MINR,