redo
This commit is contained in:
@@ -1,11 +1,15 @@
|
||||
package puzzle;
|
||||
|
||||
import module java.base;
|
||||
import anno.ConstGen;
|
||||
import anno.DictGen;
|
||||
import anno.GenerateNeighbor;
|
||||
import anno.GenerateNeighbors;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.val;
|
||||
import precomp.Neighbors9x8;
|
||||
import puzzle.SwedishGenerator.Rng;
|
||||
|
||||
import static puzzle.Export.*;
|
||||
@@ -18,8 +22,14 @@ import static puzzle.SwedishGenerator.*;
|
||||
minLen = 2,
|
||||
maxLen = 8
|
||||
)
|
||||
@ConstGen(C = 9, R = 8, packageName = "precomp", className = "Const9x8")
|
||||
@GenerateNeighbors({
|
||||
@GenerateNeighbor(C = 9, R = 8, packageName = "precomp", className = "Neighbors9x8", MIN_LEN = 2),
|
||||
@GenerateNeighbor(C = 4, R = 3, packageName = "precomp", className = "Neighbors4x3", MIN_LEN = 2)
|
||||
})
|
||||
public class Main {
|
||||
|
||||
final static rci RCI = Masker.IT[0];
|
||||
final static String OUT_DIR = envOrDefault("OUT_DIR", "/data/puzzle");
|
||||
final static Path PUZZLE_DIR = Paths.get(OUT_DIR, "puzzles");
|
||||
static final Path INDEX_FILE = PUZZLE_DIR.resolve("index.json");
|
||||
@@ -83,13 +93,13 @@ public class Main {
|
||||
}
|
||||
|
||||
section("Mask");
|
||||
System.out.print(indentLines(res.clues().gridToString(), " "));
|
||||
System.out.print(indentLines(res.clues().gridToString()));
|
||||
|
||||
section("Grid (raw)");
|
||||
System.out.print(indentLines(res.grid().gridToString(), " "));
|
||||
System.out.print(indentLines(res.grid().gridToString()));
|
||||
|
||||
section("Grid (human)");
|
||||
System.out.print(indentLines(res.grid().renderHuman(), " "));
|
||||
System.out.print(indentLines(res.grid().renderHuman()));
|
||||
|
||||
var exported = res.exportFormatFromFilled(new Rewards(50, 2, 1));
|
||||
|
||||
@@ -178,11 +188,11 @@ public class Main {
|
||||
return s.substring(0, Math.max(0, max - 1)) + "…";
|
||||
}
|
||||
|
||||
static String indentLines(String s, String indent) {
|
||||
static String indentLines(String s) {
|
||||
if (s == null || s.isEmpty()) return "";
|
||||
var lines = s.split("\\R", -1);
|
||||
var sb = new StringBuilder();
|
||||
for (var line : lines) sb.append(indent).append(line).append('\n');
|
||||
for (var line : lines) sb.append(" ").append(line).append('\n');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -356,7 +366,7 @@ public class Main {
|
||||
}
|
||||
}
|
||||
static Clues generateNewClues(Rng rng, Opts opts) {
|
||||
var masker = new Masker(rng, new int[Masker.STACK_SIZE], Clues.createEmpty());
|
||||
var masker = new Masker_Neighbors9x8(rng, new int[Masker_Neighbors9x8.STACK_SIZE], Clues.createEmpty());
|
||||
return masker.generateMask(opts.clueSize, opts.pop, opts.gens, opts.offspring);
|
||||
}
|
||||
static PuzzleResult _attempt(Rng rng, Dict dict, Opts opts) {
|
||||
@@ -367,8 +377,8 @@ public class Main {
|
||||
//val mask = generateClues();
|
||||
if (mask == null) return null;
|
||||
|
||||
val slotInfo = Masker.slots(mask, dict.index(), dict.reversed());
|
||||
var grid = Slotinfo.grid(slotInfo);// mask.toGrid();
|
||||
val slotInfo = Masker_Neighbors9x8.slots(mask, dict.index(), dict.reversed());
|
||||
var grid = Masker_Neighbors9x8.grid(slotInfo, Neighbors9x8.SIZE);// mask.toGrid();
|
||||
var filled = fillMask(rng, slotInfo, grid.lo, grid.hi, grid.g);
|
||||
|
||||
if (!multiThreaded) {
|
||||
|
||||
@@ -5,7 +5,6 @@ import anno.GenerateShapedCopies;
|
||||
import anno.Shaped;
|
||||
import lombok.val;
|
||||
import precomp.Neighbors9x8;
|
||||
import gen.rci;
|
||||
|
||||
import static java.lang.Long.*;
|
||||
import static puzzle.SwedishGenerator.*;
|
||||
@@ -53,6 +52,14 @@ public final class Masker {
|
||||
|
||||
return (bitCount(matchLo & MASK_LO) + bitCount(matchHi & MASK_HI)) / SIZED;
|
||||
}
|
||||
public static Grid grid(Slotinfo[] slots, int size) {
|
||||
long lo = X, hi = X;
|
||||
for (var slot : slots) {
|
||||
lo |= slot.lo();
|
||||
hi |= slot.hi();
|
||||
}
|
||||
return new Grid(new byte[size], ~lo & MASK_LO, ~hi & MASK_HI);
|
||||
}
|
||||
|
||||
public boolean isValid(Clues c) {
|
||||
return findOffendingClue(c) == -1;
|
||||
@@ -180,7 +187,7 @@ public final class Masker {
|
||||
if (Long.bitCount(rayLo) + Long.bitCount(rayHi) >= MIN_LEN)
|
||||
visitor.visit(key, rayLo, rayHi);
|
||||
}
|
||||
public static void forEachSlot(Clues c,SlotVisitor visitor) {
|
||||
public static void forEachSlot(Clues c, SlotVisitor visitor) {
|
||||
final long lo = c.lo, hi = c.hi, xlo = c.xlo, xhi = c.xhi, rlo = c.rlo, rhi = c.rhi, vlo = c.vlo, vhi = c.vhi;
|
||||
for (var l = lo & ~xlo & ~rlo & vlo; l != X; l &= l - 1) processSlot(c, visitor, Slot.packSlotKey(numberOfTrailingZeros(l), 1));
|
||||
for (var l = lo & ~xlo & ~rlo & ~vlo; l != X; l &= l - 1) processSlot(c, visitor, Slot.packSlotKey(numberOfTrailingZeros(l), 0));
|
||||
@@ -198,7 +205,7 @@ public final class Masker {
|
||||
}
|
||||
public static Slot[] extractSlots(Clues c, DictEntry[] index, DictEntry[] rev) {
|
||||
var slots = new ArrayList<Slot>(c.clueCount());
|
||||
forEachSlot(c,(key, lo, hi) -> slots.add(Slot.from(key, lo, hi, Slotinfo.increasing(key) ? index[Slot.length(lo, hi)] : rev[Slot.length(lo, hi)])));
|
||||
forEachSlot(c, (key, lo, hi) -> slots.add(Slot.from(key, lo, hi, Slotinfo.increasing(key) ? index[Slot.length(lo, hi)] : rev[Slot.length(lo, hi)])));
|
||||
return slots.toArray(Slot[]::new);
|
||||
}
|
||||
public static Slotinfo[] slots(Clues mask, Dict d) { return slots(mask, d.index(), d.reversed()); }
|
||||
@@ -455,7 +462,7 @@ public final class Masker {
|
||||
|
||||
return penalty;
|
||||
}
|
||||
public static boolean hasRoomForClue(Clues c,int key) {
|
||||
public static boolean hasRoomForClue(Clues c, int key) {
|
||||
if (Slotinfo.increasing(key)) if (!validSlot(c.lo, c.hi, key)) return false;
|
||||
return validSlotRev(c.lo, c.hi, key);
|
||||
}
|
||||
@@ -468,7 +475,7 @@ public final class Masker {
|
||||
if (g.isClueLo(ri)) continue;
|
||||
var d_idx = rng.randomClueDir();
|
||||
var key = Slot.packSlotKey(ri, d_idx);
|
||||
if (hasRoomForClue(g,key)) {
|
||||
if (hasRoomForClue(g, key)) {
|
||||
g.setClueLo(1L << ri, d_idx);
|
||||
if (isValid(g)) placed++;
|
||||
else g.clearClueLo(~(1L << ri));
|
||||
@@ -477,7 +484,7 @@ public final class Masker {
|
||||
if (g.isClueHi(ri)) continue;
|
||||
var d_idx = rng.randomClueDir();
|
||||
var key = Slot.packSlotKey(ri, d_idx);
|
||||
if (hasRoomForClue(g,key)) {
|
||||
if (hasRoomForClue(g, key)) {
|
||||
g.setClueHi(1L << (ri & 63), d_idx);
|
||||
if (isValid(g)) placed++;
|
||||
else g.clearClueHi(~(1L << (ri & 63)));
|
||||
@@ -495,7 +502,7 @@ public final class Masker {
|
||||
if (c.notClue(ri)) { // ADD
|
||||
var d = rng.randomClueDir();
|
||||
var key = Slot.packSlotKey(ri, d);
|
||||
if (hasRoomForClue(c,key)) {
|
||||
if (hasRoomForClue(c, key)) {
|
||||
if (isLo(ri)) {
|
||||
c.setClueLo(1L << ri, d);
|
||||
if (!isValid(c)) c.clearClueLo(~(1L << ri));
|
||||
@@ -523,7 +530,7 @@ public final class Masker {
|
||||
if (op < 4) { // CHANGE DIRECTION
|
||||
var d = rng.randomClueDir();
|
||||
var key = Slot.packSlotKey(ri, d);
|
||||
if (hasRoomForClue(c,key)) {
|
||||
if (hasRoomForClue(c, key)) {
|
||||
var oldD = c.getDir(ri);
|
||||
if (isLo(ri)) {
|
||||
c.setClueLo(1L << ri, d);
|
||||
@@ -540,7 +547,7 @@ public final class Masker {
|
||||
if (c.notClue(nri)) {
|
||||
var d = c.getDir(ri);
|
||||
var nkey = Slot.packSlotKey(nri, d);
|
||||
if (hasRoomForClue(c,nkey)) {
|
||||
if (hasRoomForClue(c, nkey)) {
|
||||
if (isLo(ri)) c.clearClueLo(~(1L << ri));
|
||||
else c.clearClueHi(~(1L << (ri & 63)));
|
||||
if (isLo(nri)) c.setClueLo(1L << nri, d);
|
||||
|
||||
@@ -38,9 +38,9 @@ import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
public record SwedishGenerator() {
|
||||
|
||||
public static final int MAX_TRIES_PER_SLOT = 500;// MAX_TRIES_PER_SLOT;
|
||||
public static final long X = 0L;
|
||||
@Shaped private static final int SIZE = Neighbors9x8.SIZE;
|
||||
@Shaped private static final long RANGE_0_SIZE = Neighbors9x8.RANGE_0_SIZE;
|
||||
public static final long X = 0L;
|
||||
@Shaped static final int SIZE = Neighbors9x8.SIZE;
|
||||
@Shaped private static final long RANGE_0_SIZE = Neighbors9x8.RANGE_0_SIZE;
|
||||
@Shaped private static final long RANGE_0_624 = Neighbors9x8.RANGE_0_624;
|
||||
|
||||
interface Bit1029 {
|
||||
@@ -118,14 +118,6 @@ public record SwedishGenerator() {
|
||||
return k;
|
||||
}
|
||||
public static boolean increasing(int dir) { return (dir & 2) == 0; }
|
||||
public static Grid grid(Slotinfo[] slots) {
|
||||
long lo = X, hi = X;
|
||||
for (var slot : slots) {
|
||||
lo |= slot.lo;
|
||||
hi |= slot.hi;
|
||||
}
|
||||
return new Grid(new byte[SIZE], ~lo, ~hi);
|
||||
}
|
||||
}
|
||||
|
||||
public static long patternForSlot(final long glo, final long ghi, final byte[] g, final long lo, final long hi) {
|
||||
|
||||
3
src/main/java/puzzle/rci.java
Normal file
3
src/main/java/puzzle/rci.java
Normal file
@@ -0,0 +1,3 @@
|
||||
package puzzle;
|
||||
|
||||
public record rci(int r, int c, int i, long n1, long n2, int nbrCount, long n8_1, long n8_2, double cross_r, double cross_c) {}
|
||||
Reference in New Issue
Block a user