Hallo,
zur Überprüfung, ob eine Stradoku-Aufgabe nur eine Lösung hat, verwende ich folgende Methode:
Bei HinweisWarten handelt es sich um eine simple Dialogklasse mit eine progressiven Fortschrittsanzeige.
Die Klasse EindeutigkeitChecken prüft, ob eine Stradoku-Aufgabe eindeutig lösbar ist. Hier der Code dieser Klasse:
Zur Überprüfung, ob die Klasse auch korrekt arbeitet, habe ich eine Reihe von Ausgaben eingebaut. Für ein simples Beispiel sieht die erzeugte Testausgabe so aus:
Trotzdem gibt die Methode 'true' zurück. Was mache ich falsch, kann mir jemand bitte helfen?
zur Überprüfung, ob eine Stradoku-Aufgabe nur eine Lösung hat, verwende ich folgende Methode:
Java:
/**
* Überprüft nach der Neueingabe oder Bearbeitung eines Stradoku,
* ob und mit welchem Level die Aufgabe gelöst werden kann.
* @param tstEindeutigkeit Flag für Eindeutigkeitsprüfung
* @param check16 Flag für Prüfung auf Archivtauglichkeit
* @return eindeutig gelöst: Level (1-5),
* nicht eindeutig gelöst: 0
* nicht gelöst, also fehlerhaft: -1
* bei Prüfung auf Archivtauglichkeit: nicht tauglich Level > 9, tauglich 1 - 5
*/
public int loeseStradoku(boolean tstEindeutigkeit, boolean check16) {
level = -1;
filterKnd = 0;
if (getVorgabewerte() > 0 || getSperrzellen() > 0) {
System.arraycopy(aufgabe, 0, stradoku, 0, 81);
erstelleKndListe(stradoku);
for (int i = 0; i < 81; i++) {
loesung[i] = 0;
}
if (check16) {
ArchivLevel aLevel = new ArchivLevel();
level = aLevel.getArchivLevel(stradoku, loesung);
} else {
strLoeser = new LevelLoeser(this, stradoku, loesung, true);
level = strLoeser.loeseAufgabe();
}
// level 1 bis 4 per se eindeutig
if (level == 5 && tstEindeutigkeit) {
eindeutig = false;
HinweisWarten hnw = new HinweisWarten(strApp);
EindeutigkeitChecken echeck = new EindeutigkeitChecken(
strApp, hnw, stradoku, loesung);
echeck.execute();
eindeutig = echeck.is_eindeutig();
if (!eindeutig) {
level = 0;
}
}
}
return level;
}
Bei HinweisWarten handelt es sich um eine simple Dialogklasse mit eine progressiven Fortschrittsanzeige.
Die Klasse EindeutigkeitChecken prüft, ob eine Stradoku-Aufgabe eindeutig lösbar ist. Hier der Code dieser Klasse:
Java:
import javax.swing.SwingWorker;
import static stradoku.GlobaleObjekte.LWF;
import static stradoku.GlobaleObjekte.LWRT;
import static stradoku.GlobaleObjekte.kopieren;
/**
* Überprüft Stradoku auf Eindeutigkeit
* @author Konrad
*/
public class EindeutigkeitChecken extends SwingWorker<Boolean, Object>
implements GlobaleObjekte {
private LevelLoeser strLoeser;
private final int[] aufgabe;
private final int[] loesung;
private boolean eindeutig;
HinweisWarten hnwDialog;
/**
* Konstruktor
* @param mf Referenz auf Hauptklasse der Anwendung
* @param hnw Referenz auf Warten-Dialog
* @param af Bitcodierte Stradoku Aufgabe
* @param ls Bitcodierte Stradoku Lösung
*/
EindeutigkeitChecken(StradokuApp mf, HinweisWarten hnw, int[] af, int[] ls) {
aufgabe = new int[81];
kopieren(af, aufgabe, true);
loesung = new int[81];
kopieren(ls, loesung, false);
eindeutig = true;
if (hnw != null){
hnwDialog = hnw;
hnwDialog.zeigeHinweis("<html><center><b>Eindeutigkeit wird überprüft."
+ "<br><br>Bitte solange warten.</b></center></html>");
}
}
/**
* Überschreibt die entsprechende Methode der Superklasse SwingWorker
* und führt im Hintergrund die Eindeutigkeitsprüfung für ein Stradoku aus.
* Sie steuert außerdem ein Fortschrittsanzeige.
* @return true wenn eindeutig, sonst false
*/
@Override
public Boolean doInBackground() {
System.out.print("\nCheck wird durchgeführt.\n");
int afg[] = new int[81];
int lsg[] = new int[81];
kopieren(aufgabe, afg, false);
for (int i = 0; i < 81; i++) {
System.out.printf(" Zelle %d\n", i);
hnwDialog.setVortschritt((int)(i*1.25)+2);
int lw = loesung[i] & ~LWF;
if (loesung[i] <= LWRT && loesung[i] > 9) {
for (int k = 1; k <= 9; k++) {
if (lw != k) {
System.out.printf(" Kandidat %d Lösungswert %d\n", k, lw);
afg[i] = k;
strLoeser = new LevelLoeser(null, afg, lsg, false);
int lev = strLoeser.loeseAufgabe();
if (lev > 0) {
eindeutig = false;
System.out.print("Zweite Lösung gefunden. Check wird mit 'false' beendet.\n");
return false;
} else {
kopieren(aufgabe, afg, false);
}
}
}
}
}
eindeutig = true;
System.out.print("Check wird mit 'true' beendet.\n");
return true;
}
/**
* Überprüft für jede zu lösende Zelle, ob das Stradoku
* mit mehr als einem Wert gelöst werden kann.
* @return true wenneindeutig, sonst false
*/
public Boolean checkEindeutigkeit() {
int afg[] = new int[81];
int lsg[] = new int[81];
kopieren(aufgabe, afg, false);
for (int i = 0; i < 81; i++) {
int lw = loesung[i] & ~LWF;
if (loesung[i] <= LWRT && loesung[i] > 9) {
for (int k = 1; k <= 9; k++) {
if (lw != k) {
afg[i] = k;
strLoeser = new LevelLoeser(null, afg, lsg, false);
int lev = strLoeser.loeseAufgabe();
if (lev > 0) {
return false;
} else {
kopieren(aufgabe, afg, false);
}
}
}
}
}
return true;
}
/**
* Beantwortet für das überprüfte Stradoku die Frage auf Eindeutigkeit.
* @return true wenn eindeutig, sonst false
*/
public boolean is_eindeutig() {
hnwDialog.setVisible(false);
return eindeutig;
}
}
Zur Überprüfung, ob die Klasse auch korrekt arbeitet, habe ich eine Reihe von Ausgaben eingebaut. Für ein simples Beispiel sieht die erzeugte Testausgabe so aus:
Code:
Check wird durchgeführt.
Zelle 0
Kandidat 2 Lösungswert 1
Zweite Lösung gefunden. Check wird mit 'false' beendet.
Trotzdem gibt die Methode 'true' zurück. Was mache ich falsch, kann mir jemand bitte helfen?