Endlossschleife

Status
Nicht offen für weitere Antworten.
V

Viper8472

Gast
Hallo alle Zusammen,

Ich versuch mich nun seit kurzer Zeit am erlernen von Java und wollt mich jetzt mal an ein kleines Projekt wagen. Das entwickeln eines Sudoku generators.
Folgende Dinge gehen schon:
- Füllen der 81 Fleder mit Zufallszahlen zwischen 1 und 9
- Alle Zeilen entsprechen den Sudoku regelen ODER alle Spalten entsprechen den Regeln

So und jetzt kommt meine Problem: wenn ich Spalten und Zeilen nach den Regeln ausgeben will (allso von den 3x3 Boxen ist noch gar keine Rede) rennt mein Program in eine Endlosschleife.

Hier mal der Code:

Code:
//Für Random und BitSet
import java.util.*;

public class Sudoku {
	
	//Neuen Zufallszahlen Generator erzeugen
	private Random zufalls_zahl	= new Random();
	
	//Mehrdimensionales Array fuer die Spielzahlen
	private int[][] zahlen		= new int[9][9];
	
	//Kontroll BitSet zur Prüfung ob die Zahl schon ein mal in der ZEILE aufgetaucht ist
	private BitSet bS4Zeile		= new BitSet();
	
	//Array zu Aufnahme der Kontroll BitSets für die einzelnen SPALTEN
	private BitSet[] bS4Spalten	= new BitSet[9]; 
			
	//Konstruktor
	public Sudoku()
	{
		//Spalten BitSets erstellen
		for (int i = 0; i < 9; i++)
		{	
			bS4Spalten[i]	= new BitSet();
			 
		}
		
		
		//Array mit 9x9 Zufallszahlen füllen
		for (int i = 0; i < 9; i++){
			
			for (int j = 0; j < 9; j++)
			{
				//Kandidaten zwischenspeichern
				int tmp	= neueZahl(); 
						
				//Kandidat prüfen ob er ins Sudoku passt
				if (checkZufall(i,j,tmp) == true)
				{	
					zahlen[i][j] = tmp;
					
				} else {
					//j--;
				} 
			}
		}
	}//Ende Konstruktor
	
	//Lösung auf Kommandozeile ausgeben
	public void printLsg()
	{
		//Zeile		
		for (int i=0; i < zahlen.length; i++)
		{
			//Nach jedem 3er Block
			if (i%3 == 0)
			{
				System.out.println(" -------------  -------------  -------------");	
			}
						
			//Spalte
			for (int j=0; j < zahlen.length; j++)
			{
				
				//Nach jedem 3ten Element
				if (j%3 == 0 && j != 0)
				{
					System.out.print(" | ");	
				}
				
				//Element trenner
				System.out.print(" | ");
				
				//Element ausgeben
				System.out.print(zahlen[i][j]);
				
				//Zeilenende
				if (j == zahlen.length-1)
				{
					System.out.print(" |");
				}
			}
			
			//Zeilenumbruch
			System.out.println("");
			
			//Letzte Zeile
			if (i == zahlen.length-1)
			{
				System.out.println(" -------------  -------------  -------------");	
			}	
		}
	}
	
	//Zufallszahl generieren
	private int neueZahl()
	{
		//Zahl zwischen 0 und 9 erzeugen
		int zahl = zufalls_zahl.nextInt(9) + 1;
		
		return zahl;
	}
	
	//Sudoku Regeleinhaltung prüfen
	private boolean checkZufall(int zeile, int spalte, int zahl)
	{
				
		//Ist die Zahl schon mal verwendet wurden?
		if ( (bS4Zeile.get(zahl) == true ) || (bS4Spalten[spalte].get(zahl) == true) )
		{
			//Zahl ist schon mal aufgetaucht
			return false;
		
		} else {
					
			bS4Spalten[spalte].set(zahl);
			
			if (spalte != 8)
			{	
				
				//Zahl wird registriert
				bS4Zeile.set(zahl);
			
			} else {
				
				//Prüfung befindet sich in der letzten Spalte -> 
				//für die nächste Spalte wird ein leeres BitSet benötigt
				bS4Zeile.clear();
			
			}
			
			//Zahl OK
			return true;
		
		}		
	}
}//Ende Klasse

Sobald ich bei Zeile 44 den Komentar entferne ist alles zu spät :cry:

Ich hoffe ihr könnt mir diesbezüglich weiterhelfen.

Danke schon mal
 

Leroy42

Top Contributor
Ich habe dein Programm nicht genau analysiert,
aber das ist mir aufgefallen:
Code:
 for (int i = 0; i < 9; i++){ 
          
         for (int j = 0; j < 9; j++) 
         { 
            //Kandidaten zwischenspeichern 
            int tmp   = neueZahl(); 
                   
            //Kandidat prüfen ob er ins Sudoku passt 
            if (checkZufall(i,j,tmp) == true) 
            {    
               zahlen[i][j] = tmp; 
                
            } else { 
               //j--; 
            } 
         } 
      }

Das ist auf keinen Fall ein korrekter Backtracking-Algorithmus.

Wenn an irgendeinem Punkt dein checkZufall() dir sagt,
das deine gewählte Zufallszahl keine lösbares Sudoku
generiert, dann gehst du nur einen Schritt zurück und
probierst eine neue Zufallszahl.

Wenn der Fehler allerdings 2 oder mehrere Auswahlen
früher seinen Grund hatte, kann deine Konstruktion dies nicht
erkennen und versucht ewig eine Zahl zu finden, die es eben nicht gibt. :cry:
 

Leroy42

Top Contributor
Vorschlag:

Versuch' dich erstmal mit dem Grundprinzip des Backtrackings
anhand einfacher bekannter Problemstellungen (8-Damen-Problem, ...),
von denen es tausende fertiger Lösungen im Netz gibt (auch in Java)
vertraut zu machen, bevor du mit deinem Sudoku weitermachst.

Wenn du gut bist, kannst du das korrekte Prinzip innerhalb
von 1 Stunde verstehen. :wink:
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Oben