Gather data
This commit is contained in:
@@ -111,7 +111,7 @@ public final class ExportFormat {
|
||||
p.arrowRow - minR,
|
||||
p.arrowCol - minC,
|
||||
p.isReversed,
|
||||
puz.dict().words().get(p.word).cross()
|
||||
puz.dict().words().get(p.word).simpel()
|
||||
));
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@ public final class ExportFormat {
|
||||
|
||||
return new Placed(
|
||||
word,
|
||||
dict.words().get(word).clue(), // clue placeholder
|
||||
dict.words().get(word).clue().toArray( String[]::new), // clue placeholder
|
||||
startRow,
|
||||
startCol,
|
||||
direction,
|
||||
@@ -187,13 +187,13 @@ public final class ExportFormat {
|
||||
* @param direction "h" | "v"
|
||||
* @param cells word cells
|
||||
* @param arrow [arrowRow, arrowCol] */
|
||||
private record Placed(String word, String clue, int startRow, int startCol, String direction, String answer, int arrowRow, int arrowCol, List<int[]> cells, int[] arrow,
|
||||
private record Placed(String word, String[] clue, int startRow, int startCol, String direction, String answer, int arrowRow, int arrowCol, List<int[]> cells, int[] arrow,
|
||||
boolean isReversed) { }
|
||||
|
||||
public record Rewards(int coins, int stars, int hints) { }
|
||||
|
||||
/// @param direction "h" | "v"
|
||||
public record WordOut(String word, String clue, int startRow, int startCol, String direction, String answer, int arrowRow, int arrowCol, boolean isReversed, int complex) { }
|
||||
public record WordOut(String word, String[] clue, int startRow, int startCol, String direction, String answer, int arrowRow, int arrowCol, boolean isReversed, int complex) { }
|
||||
|
||||
public record ExportedPuzzle(List<String> gridv2, List<WordOut> words, int difficulty, Rewards rewards) { }
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import java.time.ZoneOffset;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static puzzle.SwedishGenerator.fillMask;
|
||||
import static puzzle.SwedishGenerator.generateMask;
|
||||
@@ -83,7 +84,6 @@ public class Main {
|
||||
section("Clues");
|
||||
info("status : generating...");
|
||||
info("generatedFor : " + exported.words().size());
|
||||
//exported = ClueGenerator.applyClues(exported);
|
||||
info("status : done");
|
||||
|
||||
section("Words");
|
||||
@@ -92,10 +92,7 @@ public class Main {
|
||||
section("Gridv2");
|
||||
for (var row : exported.gridv2()) System.out.println(" " + row);
|
||||
|
||||
// Export to JSON file
|
||||
|
||||
var theme = "algemeen";
|
||||
|
||||
section("Export");
|
||||
info("file : " + OUTPUT_PATH);
|
||||
|
||||
@@ -151,14 +148,14 @@ public class Main {
|
||||
for (var w : words) {
|
||||
System.out.printf(
|
||||
Locale.ROOT,
|
||||
" %-2d %-12s %-3s %-3s %-9s %-9s %s%n",
|
||||
" %-2d %-12s %-4s %-3s %-9s %-9s %s%n",
|
||||
i++,
|
||||
safe(w.word(), 12),
|
||||
safe("" + w.complex(), 3),
|
||||
safe("" + w.complex(), 4),
|
||||
safe(w.direction(), 3),
|
||||
fmtPoint(w.startRow(), w.startCol()),
|
||||
fmtPoint(w.arrowRow(), w.arrowCol()),
|
||||
w.clue() == null ? "" : w.clue()
|
||||
w.clue() == null ? "" : Arrays.toString(w.clue())
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -332,9 +329,10 @@ public class Main {
|
||||
sb.append(" \"words\": [\n");
|
||||
for (var i = 0; i < puzzle.words().size(); i++) {
|
||||
var w = puzzle.words().get(i);
|
||||
Arrays.sort(w.clue(), Comparator.comparingInt(String::length));
|
||||
sb.append(" {\n");
|
||||
sb.append(" \"word\": \"").append(escapeJson(w.word())).append("\",\n");
|
||||
sb.append(" \"clue\": \"").append(escapeJson(w.clue())).append("\",\n");
|
||||
sb.append(" \"clue\": [").append(Arrays.stream(w.clue()).map(ss -> "\"" + escapeJson(ss) + "\"").collect(Collectors.joining(","))).append("],\n");
|
||||
sb.append(" \"startRow\": ").append(w.startRow()).append(",\n");
|
||||
sb.append(" \"startCol\": ").append(w.startCol()).append(",\n");
|
||||
sb.append(" \"direction\": \"").append(escapeJson(w.direction())).append("\",\n");
|
||||
|
||||
@@ -142,12 +142,14 @@ public class SwedishGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
static record WordDifficulty(String word, int difficulty, int simpel, int score, int cross, String clue) {
|
||||
static record WordDifficulty(String word, int difficulty, int simpel, int score, int cross, ArrayList<String> clue) {
|
||||
|
||||
public WordDifficulty(String word, int simpel, int score, String clue) {
|
||||
var difficulty1 = 0 + ((8 - word.length()) * 30) + ((10 - score) * 15);
|
||||
var crossScore = ThemePoolBuilderLength.crossabilityScore(word);
|
||||
this(word, difficulty1, simpel, score, (crossScore * 7) + ((score) * 30) + ((word.length()) * 15), clue);
|
||||
var list = new ArrayList<String>(10);
|
||||
list.add(clue);
|
||||
this(word, difficulty1, simpel, score, (crossScore * 7) + ((score) * 30) + ((word.length()) * 15), list);
|
||||
|
||||
// Prioritize simple words (high lScore) and long words.
|
||||
// lScore (1-10) adds up to 1000 points (weight 100).
|
||||
@@ -194,10 +196,15 @@ public class SwedishGenerator {
|
||||
if (rawClue.startsWith("\"") && rawClue.endsWith("\"")) {
|
||||
rawClue = rawClue.substring(1, rawClue.length() - 1).replace("\"\"", "\"");
|
||||
}
|
||||
if (score >= 1)
|
||||
if (score >= 1) {
|
||||
if (map.containsKey(s)) {
|
||||
map.get(s).clue.add(rawClue);
|
||||
} else {
|
||||
map.put(s, new WordDifficulty(s, simpel, score, rawClue));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var words = map.values().stream().collect(Collectors.toCollection(ArrayList::new));
|
||||
// Sort words by difficulty in ascending order
|
||||
words.sort(Comparator.comparingInt(wd -> wd.simpel));
|
||||
@@ -853,65 +860,4 @@ public class SwedishGenerator {
|
||||
// ---------------- Top-level generatePuzzle ----------------
|
||||
public record PuzzleResult(Dict dict, char[][] mask, FillResult filled) { }
|
||||
|
||||
public static PuzzleResult generatePuzzle(Main.Opts opts) {
|
||||
var tLoad0 = System.nanoTime();
|
||||
var dict = loadWords(opts.wordsPath);
|
||||
var tLoad1 = System.nanoTime();
|
||||
System.out.printf(Locale.ROOT, "LOAD_WORDS: %.3fs%n %s words%n", (tLoad1 - tLoad0) / 1e9, dict.words.size());
|
||||
|
||||
if (opts.threads > 1) {
|
||||
System.out.println("Running in multi-threaded mode with " + opts.threads + " threads...");
|
||||
var executor = Executors.newFixedThreadPool(opts.threads);
|
||||
try {
|
||||
var tasks = new ArrayList<Callable<PuzzleResult>>();
|
||||
for (int i = 1; i <= opts.tries; i++) {
|
||||
final int attempt = i;
|
||||
tasks.add(() -> {
|
||||
var threadRng = new Rng(opts.seed + attempt);
|
||||
var mask = generateMask(threadRng, dict.lenCounts, opts.pop, opts.gens, false);
|
||||
var filled = fillMask(threadRng, mask, dict.index, dict.words, 200, 60000, false);
|
||||
|
||||
if (filled.ok && (opts.minSimplicity <= 0 || filled.simplicity >= opts.minSimplicity)) {
|
||||
System.out.println("\nSolution found on attempt " + attempt);
|
||||
return new PuzzleResult(dict, mask, filled);
|
||||
}
|
||||
throw new RuntimeException("No solution found in attempt " + attempt);
|
||||
});
|
||||
}
|
||||
return executor.invokeAny(tasks);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (ExecutionException e) {
|
||||
// all failed
|
||||
} finally {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
var rng = new Rng(opts.seed);
|
||||
for (var attempt = 1; attempt <= opts.tries; attempt++) {
|
||||
System.out.println("\nAttempt " + attempt + "/" + opts.tries);
|
||||
|
||||
var tMask0 = System.nanoTime();
|
||||
var mask = generateMask(rng, dict.lenCounts, opts.pop, opts.gens, true);
|
||||
var tMask1 = System.nanoTime();
|
||||
System.out.printf(Locale.ROOT, "MASK: %.3fs%n", (tMask1 - tMask0) / 1e9);
|
||||
|
||||
var tFill0 = System.nanoTime();
|
||||
var filled = fillMask(rng, mask, dict.index, dict.words, 200, 60000, true);
|
||||
var tFill1 = System.nanoTime();
|
||||
System.out.printf(Locale.ROOT, "FILL: %.3fms | Simplicity: %.2f%n", (tFill1 - tFill0) / 1e6, filled.simplicity);
|
||||
|
||||
if (filled.ok && (opts.minSimplicity <= 0 || filled.simplicity >= opts.minSimplicity)) {
|
||||
return new PuzzleResult(dict, mask, filled);
|
||||
}
|
||||
if (filled.ok) {
|
||||
System.out.printf(Locale.ROOT, "Puzzle simplicity %.2f is below min %.2f, retrying...%n",
|
||||
filled.simplicity, opts.minSimplicity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user