From 45a9ae4f206eeff7b4972d4544f649fc2ac06c07 Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Mon, 7 Oct 2024 16:58:08 +0200 Subject: [PATCH] Update generator to favor collisions --- .../java/eu/m724/crossword/Generator.java | 63 +++++++++++++++++-- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/src/main/java/eu/m724/crossword/Generator.java b/src/main/java/eu/m724/crossword/Generator.java index 119c2de..ccd73d4 100644 --- a/src/main/java/eu/m724/crossword/Generator.java +++ b/src/main/java/eu/m724/crossword/Generator.java @@ -137,26 +137,79 @@ public class Generator { } private Set follow(Grid grid, Set placedChain, int wordIndex) { - //System.out.println("Depth " + wordIndex); + System.out.println("Depth " + wordIndex); if (wordIndex > peakDepth) peakDepth = wordIndex; if (wordIndex == words.length) { - //System.out.println(" Completed"); + System.out.println(" Completed"); return placedChain; } List currentPossiblePlacements = new ArrayList<>(possiblePlacements); shuffle(currentPossiblePlacements); - //Collections.shuffle(currentPossiblePlacements); boolean vertical = random.nextBoolean(); Word word = words[wordIndex]; + // TODO optimize. maybe make this a list. and consider if this is really necessary. + Map> rankedPlacements = new LinkedHashMap<>(); + int hi = -1; + for (int i=0; i<2; i++) { // repeating twice to pass horizontal and vertical vertical = !vertical; + for (Vec placement : currentPossiblePlacements) { + if (vertical) { + int y = placement.y(); + if (y == 0 || y + word.length() >= height) continue; + } else { + int x = placement.x(); + if (x == 0 || x + word.length() >= width) continue; + } + + PlacedWord candidate = new PlacedWord(placement, vertical, word); + int placementResult = grid.canPlace(candidate); + + if (placementResult != -1) { + //System.out.println(" Found candidate"); + rankedPlacements.computeIfAbsent(placementResult, k -> new ArrayList<>()).add(candidate); + if (placementResult > hi) hi = placementResult; + } + } + } + + System.out.println("hi " + hi); + + for (int i=hi; i>=0; i--) { + //List candidates = rankedPlacements.getOrDefault(i, new ArrayList<>()); + //System.out.println(" Candidates: " + candidates.size()); + for (PlacedWord candidate : rankedPlacements.getOrDefault(i, new ArrayList<>())) { + Set potentialChain = new HashSet<>(placedChain); + + potentialChain.add(candidate); + + Grid newGrid = grid.clone(); + newGrid.placeWord(candidate); + + Set newChain = follow(newGrid, potentialChain, wordIndex + 1); + System.out.println("Back to depth " + wordIndex); + + // if it's null it means there's no good placement, and we should continue searching at this depth + if (newChain != null) { + System.out.println(" Done here"); + return newChain; + } else { + System.out.println(" Looking further"); + } + } + } + + + /*for (int i=0; i<2; i++) { // repeating twice to pass horizontal and vertical + vertical = !vertical; + for (Vec placement : currentPossiblePlacements) { if (vertical) { int y = placement.y(); @@ -188,9 +241,9 @@ public class Generator { } } } - } + }*/ - //System.out.println(" No solution"); + System.out.println(" No solution"); // no placement at this depth return null; }