Compare commits

..

No commits in common. "500dcc1b9a38d31c3aad5d6086947e5a6149aca5" and "472106ba3af8b715b6009c7e32524c06b317d25f" have entirely different histories.

4 changed files with 13 additions and 87 deletions

View file

@ -1,10 +0,0 @@
# Crossword generator
### Usage
See `src/main/java/eu/m724/crossword/Main.java`
### Speed
Generally, slow. \
Compared to mining:
- difficulty: the "tighter", the slower. It has to fit the words on the surface somehow, it bruteforces a good placement, if it's more crowded it'll have to try harder
- luck

View file

@ -80,11 +80,6 @@ public class Generator {
}
System.out.println("Possible placements: " + possiblePlacements.size() + " * 2");
int totalCharacters = Arrays.stream(words).map(w -> w.length() + 1).reduce(0, Integer::sum);
if (totalCharacters > possiblePlacements.size()) {
System.out.printf("Warning: there might be no solution (%d > %d)", totalCharacters, possiblePlacements.size());
}
/*for (Word word : words) {
PlacedWord placedWord = null;
@ -149,14 +144,11 @@ public class Generator {
List<Vec> 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<Integer, List<PlacedWord>> rankedPlacements = new LinkedHashMap<>();
int hi = -1;
for (int i=0; i<2; i++) { // repeating twice to pass horizontal and vertical
vertical = !vertical;
@ -170,59 +162,9 @@ public class Generator {
}
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<PlacedWord> candidates = rankedPlacements.getOrDefault(i, new ArrayList<>());
//System.out.println(" Candidates: " + candidates.size());
for (PlacedWord candidate : rankedPlacements.getOrDefault(i, new ArrayList<>())) {
Set<PlacedWord> potentialChain = new HashSet<>(placedChain);
potentialChain.add(candidate);
Grid newGrid = grid.clone();
newGrid.placeWord(candidate);
Set<PlacedWord> 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();
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);
if (grid.canPlace(candidate) != -1) {
//System.out.println(" Found candidate");
if (grid.canPlace(candidate)) {
System.out.println(" Found candidate");
Set<PlacedWord> potentialChain = new HashSet<>(placedChain);
potentialChain.add(candidate);
@ -230,18 +172,18 @@ public class Generator {
newGrid.placeWord(candidate);
Set<PlacedWord> newChain = follow(newGrid, potentialChain, wordIndex + 1);
//System.out.println("Back to depth " + wordIndex);
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(" Unfolding"); // is that a correct word?
System.out.println(" Unfolding"); // is that a correct word?
return newChain;
} else {
//System.out.println(" Looking further");
System.out.println(" Looking further");
}
}
}
}*/
}
System.out.println(" No solution");
// no placement at this depth

View file

@ -46,11 +46,9 @@ public class Grid implements Cloneable {
* Can a word be placed, will it not collide
*
* @param word The word
* @return can it be placed. -1 = no, 0 = yes, >0 = yes and will be over n characters
* @return can it be placed
*/
public int canPlace(PlacedWord word) {
int cols = 0;
public boolean canPlace(PlacedWord word) {
int x = word.pos().x();
int y = word.pos().y();
@ -69,16 +67,12 @@ public class Grid implements Cloneable {
c = word.word().text().charAt(i);
}
if (charArray[_x][_y] != 0) {
if (charArray[_x][_y] != c) {
return -1;
} else {
cols++;
}
if (charArray[_x][_y] != 0 && charArray[_x][_y] != c) {
return false;
}
}
return cols;
return true;
}
@Override

View file

@ -2,7 +2,7 @@ package eu.m724.crossword;
public class Main {
public static void main(String[] args) {
CrosswordBuilder builder = new CrosswordBuilder(20, 20, "crossword")
CrosswordBuilder builder = new CrosswordBuilder(12, 12, "crossword")
.addWord("cat", "Furry feline pet")
.addWord("owl", "Nocturnal bird of prey")
.addWord("kite", "Flying toy on a string")