redo
This commit is contained in:
14
pom.xml
14
pom.xml
@@ -69,6 +69,12 @@
|
||||
<version>1.7-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>mike.plugin</groupId>
|
||||
<artifactId>plugin</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>-->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
@@ -94,6 +100,13 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<configuration>
|
||||
<!-- <compilerArgs>
|
||||
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED</arg>
|
||||
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED</arg>
|
||||
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED</arg>
|
||||
<arg>--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED</arg>
|
||||
<arg>-Xplugin:autogetter</arg>
|
||||
</compilerArgs>-->
|
||||
<annotationProcessorPaths>
|
||||
<!-- Lombok processor -->
|
||||
<path>
|
||||
@@ -111,6 +124,7 @@
|
||||
</annotationProcessorPaths>
|
||||
<source>25</source>
|
||||
<target>25</target>
|
||||
<release>25</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
||||
@@ -386,6 +386,10 @@ public class Main {
|
||||
var grid = Masker_Neighbors9x8.grid(slotInfo);// mask.toGrid();
|
||||
var filled = fillMask(rng, slotInfo, grid.lo, grid.hi, grid.g);
|
||||
|
||||
if (Thread.currentThread().isInterrupted() && !filled.ok()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!multiThreaded) {
|
||||
System.out.print("\r" + " ".repeat(120 - "".length()) + "\r");
|
||||
System.out.flush();
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package puzzle;
|
||||
|
||||
import anno.GenAccessors;
|
||||
|
||||
@GenAccessors
|
||||
public class Person {
|
||||
@GenAccessors.Getter final String name;
|
||||
@GenAccessors.Getter final int age;
|
||||
|
||||
public Person(String name, int age) { this.name = name; this.age = age; }
|
||||
|
||||
public static void main(String[] args) {
|
||||
var p = new Person("Mike", 42);
|
||||
|
||||
System.out.println(Person__Accessors.getName(p));
|
||||
System.out.println(Person__Accessors.getAge(p));
|
||||
}
|
||||
}
|
||||
@@ -159,9 +159,9 @@ public class MarkerTest {
|
||||
// Intersection is exactly 1 cell (0,2). Valid.
|
||||
assertTrue(masker.isValid(Riddle.Signa.of(r0c0d1, r2c2d2).c()));
|
||||
|
||||
// Clue 3: (1,1) Right. Slot cells: (1,2), (1,3), ...
|
||||
// Clue 3: (1,3) Right. Slot cells: (1,4), (1,5), ...
|
||||
// No intersection with Clue 1 or 2. Valid.
|
||||
assertTrue(masker.isValid(Riddle.Signa.of(r0c0d1, r2c2d2, r1c1d1).c()));
|
||||
assertTrue(masker.isValid(Riddle.Signa.of(r0c0d1, r2c2d2, precomp.Const9x8.Cell.r1c3d1).c()));
|
||||
|
||||
// Now create a violation: two slots sharing 2 cells.
|
||||
// We can do this with Corner Down and another clue.
|
||||
@@ -205,26 +205,76 @@ public class MarkerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPhysicalAdjacency() {
|
||||
var rng = new Rng(42);
|
||||
var masker = new Masker(rng, new int[STACK_SIZE], Clues.createEmpty());
|
||||
void testDeadCellPenalty() {
|
||||
var masker = emptyMasker();
|
||||
|
||||
// Twee clues naast elkaar, maar slots kruisen niet.
|
||||
// Clue 1: (1,1) Right. Slot (1,2), (1,3), (1,4)
|
||||
// Clue 2: (2,1) Right. Slot (2,2), (2,3), (2,4)
|
||||
var clues = Clues.createEmpty().setClue(r1c1d1).setClue(r2c1d1);
|
||||
// A cell surrounded by 4 clues is a "dead cell"
|
||||
// Let's take cell (4,4)
|
||||
// Clues at (4,3), (4,5), (3,4), (5,4)
|
||||
var deadClues = Clues.createEmpty();
|
||||
deadClues.setClue(precomp.Const9x8.CELLS[precomp.Const9x8.OFF_4_3 * 33 + 1]); // (4,3) Down
|
||||
deadClues.setClue(precomp.Const9x8.CELLS[precomp.Const9x8.OFF_4_5 * 33 + 1]); // (4,5) Down
|
||||
deadClues.setClue(precomp.Const9x8.CELLS[precomp.Const9x8.OFF_3_4 * 33]); // (3,4) Right
|
||||
deadClues.setClue(precomp.Const9x8.CELLS[precomp.Const9x8.OFF_5_4 * 33]); // (5,4) Right
|
||||
|
||||
var fitness = masker.maskFitness(clues, 2);
|
||||
// Als 8-naburigheid NIET MEER meetelt, moet de penalty hoog zijn.
|
||||
System.out.println("[DEBUG_LOG] Fitness physically adjacent: " + fitness);
|
||||
assertTrue(fitness > 20000, "Should have island penalty even if physically adjacent");
|
||||
var fitness = masker.maskFitness(deadClues, 4);
|
||||
System.out.println("[DEBUG_LOG] Fitness dead cell: " + fitness);
|
||||
|
||||
// Twee clues naast elkaar, maar slots kruisen niet.
|
||||
var clues2 = Clues.createEmpty().setClue(r1c1d1).setClue(r3c1d1);
|
||||
var fitness2 = new Masker(rng, new int[STACK_SIZE], Clues.createEmpty()).maskFitness(clues2, 2);
|
||||
// Als 8-naburigheid NIET MEER meetelt, moet de penalty hoog zijn.
|
||||
System.out.println("[DEBUG_LOG] Fitness physically adjacent: " + fitness2);
|
||||
assertTrue(fitness2 > 20000, "Should have island penalty even if physically adjacent");
|
||||
// The cell (4,4) should have 4 clue neighbors -> penalty 2000.
|
||||
// It is also not covered by any word -> penalty 4000.
|
||||
// Total penalty should be high.
|
||||
assertTrue(fitness > 5000, "Dead cell should have high penalty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDeadCellIsValid() {
|
||||
var masker = emptyMasker();
|
||||
var deadClues = Clues.createEmpty();
|
||||
deadClues.setClue(precomp.Const9x8.Cell.r0c1d1);
|
||||
deadClues.setClue(precomp.Const9x8.Cell.r2c1d1);
|
||||
deadClues.setClue(precomp.Const9x8.Cell.r1c0d0);
|
||||
deadClues.setClue(precomp.Const9x8.Cell.r1c2d0);
|
||||
|
||||
int offending = masker.findOffendingClue(deadClues);
|
||||
if (offending != -1) {
|
||||
System.out.println("[DEBUG_LOG] Offending clue index: " + offending);
|
||||
}
|
||||
|
||||
assertFalse(masker.isValid(deadClues), "Mask with dead cell should be invalid");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCleanupDeadCell() {
|
||||
var masker = emptyMasker();
|
||||
var deadClues = Clues.createEmpty();
|
||||
deadClues.setClue(precomp.Const9x8.Cell.r0c1d1);
|
||||
deadClues.setClue(precomp.Const9x8.Cell.r2c1d1);
|
||||
deadClues.setClue(precomp.Const9x8.Cell.r1c0d0);
|
||||
deadClues.setClue(precomp.Const9x8.Cell.r1c2d0);
|
||||
|
||||
assertFalse(masker.isValid(deadClues));
|
||||
|
||||
masker.cleanup(deadClues);
|
||||
|
||||
assertTrue(masker.isValid(deadClues), "After cleanup, mask should be valid");
|
||||
assertTrue(deadClues.clueCount() < 4, "Cleanup should have removed at least one clue");
|
||||
}
|
||||
|
||||
@Test
|
||||
void testOnlyOneWordCoveragePenalty() {
|
||||
var masker = emptyMasker();
|
||||
|
||||
// A white cell covered by only one word.
|
||||
// Clue (4,0) Right. Cell (4,1) is covered only by this horizontal word.
|
||||
var oneWord = Clues.createEmpty().setClue(precomp.Const9x8.CELLS[precomp.Const9x8.OFF_4_0 * 33]);
|
||||
|
||||
var fitness = masker.maskFitness(oneWord, 1);
|
||||
System.out.println("[DEBUG_LOG] Fitness only one word: " + fitness);
|
||||
|
||||
// Each white cell of (4,0) Right (length 8) will have 1 word coverage.
|
||||
// Penalty per cell is 1500. 8 cells * 1500 = 12000.
|
||||
// Plus some 1-clue-per-row/col penalties etc.
|
||||
assertTrue(fitness > 11000, "Should have penalty for single word coverage");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -57,7 +57,7 @@ import static puzzle.dict900.DictData900.DICT900;
|
||||
public class PerformanceTest {
|
||||
|
||||
void main() {
|
||||
testIncrementalComplexity();
|
||||
testPerformance();
|
||||
}
|
||||
@Test
|
||||
void testPerformance() {
|
||||
@@ -65,14 +65,15 @@ public class PerformanceTest {
|
||||
|
||||
// 1. Stress test Clue Generation (Mask Generation)
|
||||
System.out.println("[DEBUG_LOG] --- Mask Generation Performance ---");
|
||||
var clueSizes = new int[]{ 20, 25, 30 };
|
||||
var arr = new Clues[3];
|
||||
var clueSizes = new int[]{ 20,22,24, 25, 30 };
|
||||
var arr = new Clues[clueSizes.length];
|
||||
var c = 0;
|
||||
val masker = new Masker(rng, new int[Masker.STACK_SIZE], Clues.createEmpty());
|
||||
for (var size : clueSizes) {
|
||||
var t0 = System.currentTimeMillis();
|
||||
val masker = new Masker(rng, new int[Masker.STACK_SIZE], Clues.createEmpty());
|
||||
var t0 = System.currentTimeMillis();
|
||||
|
||||
// Increased population and generations for stress
|
||||
arr[c++] = masker.generateMask(size, 200, 100, 50);
|
||||
arr[c++] = masker.generateMask(size, 200, 700, 50);
|
||||
var t1 = System.currentTimeMillis();
|
||||
var duration = (t1 - t0) / 1000.0;
|
||||
System.out.printf(Locale.ROOT, "[DEBUG_LOG] Size %d (pop=200, gen=100): %.3fs%n", size, duration);
|
||||
|
||||
Reference in New Issue
Block a user