Sudoku mittels Backtracking Problem

Hi ich hab ein Problem mit meinem Sudoku Programm.
Die relevante Stelle ist aus meiner Sicht die hier:
Java:
  boolean loese(int[][] f) {
    //    System.out.println(f[suche(f) % 10][(int) suche(f) / 10] + "," +
    //                       (suche(f) % 10) + "," + ((int) suche(f) / 10));
        int x = suche(f) % 10;
    int y = (int) suche(f) / 10;
    System.out.println(x + "," + y);

    int[][] test = new int[9][9];
    test = f;
    if (suche(f) == -1) {
      feld = test;

      for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
        NF[j][i].setText(Integer.toString(feld[j][i]));
        System.out.print(feld[j][i] + "," + ((j == 8) ? "\r\n" : ""));
        }
      }
    }



    for (int i = 1; i < 10; i++) {
    System.out.println(i+"zähler");
      if (reihe(i, y, f) && spalte(i, x, f) && block(i, x, y, f)) {
        test[x][y] = i;
        System.out.println(test[x][y]);
        loese(test);
      }
    }

    return false;
  }

Die Ausgabe ist bei leerer Eingabe:
1,2,3,4,5,6,7,8,9,
2,1,4,3,6,5,8,9,7,
3,4,1,2,7,8,9,6,5,
7,9,2,8,1,4,6,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0

Danach geht er zurück zu 0/0 und endet damit.

Es wäre nett von euch mir hierbei zu helfen, da ich es für ein Referat morgen bräuchte.
 
richtest du dich an Sudoku-Experten? wenn nicht-gepostete Methoden wie
> reihe(i, y, f) && spalte(i, x, f) && block(i, x, y, f)
allgemein bekannt sind, dann nimm doch diesen Standardcode, ich kann mir gut vorstellen dass man dazu jede Menge im Forum bzw. bei google findet,
ansonsten poste besser das ganze Programm,
> suche(f)
sieht besonders wichtig aus, was das wohl ist

-----

was mir technisch schon auffällt:
> int[][] test = new int[9][9];
> test = f;
das neu erstellte Array wird überhaupt nicht verwendet, im nächsten Schritt bist du wieder bei f, da wird keine Kopie angelegt wie du vielleicht vermutest, sondern test und f sind exakt dasselbe,
besser nicht zwei verschiedene Variablen für dasselbe Array verwenden

> feld = test;

> NF[j].setText(..

feld und NF scheinen noch zwei [][] zu sein, da wirds langsam kompliziert..
 
Tut mir Leid, ich habe grade bemerkt dass ich ausversehen eine überholte Ausgabe geposted habe, bei der ich noch einen weiteren Fehler hatte (Merke: Datei nicht in verschiedenen Ordnern speichern).

Der gesamte Quelltext lautet:
Java:
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.*;


/**
  *
  * Beschreibung
  *
  * @version 1.0 vom 15.11.2010
  * @author Christoph
  */
public class sudoku extends JFrame {
  // Anfang Attribute
  private JTextField[][] NF = new JTextField[9][9];
  int[][] feld = new int[9][9];
  private JButton jButton1 = new JButton();

  // Ende Attribute
  public sudoku(String title) {
    // Frame-Initialisierung
    super(title);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

    int frameWidth = 400;
    int frameHeight = 400;
    setSize(frameWidth, frameHeight);

    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);

    Container cp = getContentPane();
    cp.setLayout(null);

    // Anfang Komponenten
    for (int j = 0; j < 9; j++) {
      for (int i = 0; i < 9; i++) {
        NF[j][i] = new JTextField("0");
        NF[j][i].setBounds(65 + (j * 30), 16 + (i * 30), 30, 30);
        cp.add(NF[j][i]);
      }
    }

    jButton1.setBounds(160, 328, 75, 25);
    jButton1.setText("loesen");
    jButton1.setMargin(new Insets(2, 2, 2, 2));
    jButton1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
          jButton1_ActionPerformed(evt);
        }
      });
    cp.add(jButton1);
    // Ende Komponenten
    setResizable(false);
    setVisible(true);
  }

  // Anfang Methoden
  public void jButton1_ActionPerformed(ActionEvent evt) {
    speichern();
    if (!loese(feld)) {
      for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
          System.out.print(feld[j][i] + "," + ((j == 8) ? "\r\n" : ""));
        }
      }
    }
  }

  void speichern() {
    for (int i = 0; i < 9; i++) {
      for (int j = 0; j < 9; j++) {
        try {
          feld[j][i] = ((Integer.parseInt(NF[j][i].getText()) > 0)
                        ? Integer.parseInt(NF[j][i].getText()) : 0);
          System.out.print(feld[j][i] + "," + ((j == 8) ? "\r\n" : ""));
        } catch (Exception e) {
        }
      }
    }
  }

  boolean loese(int[][] f) {
    //    System.out.println(f[suche(f) % 10][(int) suche(f) / 10] + "," +
    //                       (suche(f) % 10) + "," + ((int) suche(f) / 10));
        int x = suche(f) % 10;
    int y = (int) suche(f) / 10;
    System.out.println(x + "," + y);

    int[][] test = new int[9][9];
    test = f;
    if (suche(f) == -1) {
      feld = test;

      for (int i = 0; i < 9; i++) {
        for (int j = 0; j < 9; j++) {
        NF[j][i].setText(Integer.toString(feld[j][i]));
        System.out.print(feld[j][i] + "," + ((j == 8) ? "\r\n" : ""));
        }
      }
    }



    for (int i = 1; i < 10; i++) {
    System.out.println(i+"zähler");
      if (reihe(i, y, f) && spalte(i, x, f) && block(i, x, y, f)) {
        test[x][y] = i;
        NF[x][y].setText(Integer.toString(test[x][y]));
        System.out.println(test[x][y]);
        loese(test);
      }
    }
    System.out.println("return"+x+","+y);
    return false;
  }

  boolean reihe(int z, int y, int[][] fel) {
    boolean gibtsnet = true;

    for (int i = 0; i < 9; i++) {
      if (z == fel[i][y]) {
        return false;
      }
    }

    return gibtsnet;
  }

  boolean spalte(int z, int x, int[][] fel) {
    boolean gibtsnet = true;

    for (int i = 0; i < 9; i++) {
      if (z == fel[x][i]) {
        return false;
      }
    }

    return gibtsnet;
  }

  boolean block(int z, int x, int y, int[][] fel) {
        int i_start = (int)(x/3) * 3;
    int j_start = (int)(y/3) * 3;

    for(int a=i_start; a<i_start+3; a++)
        for(int b=j_start; b<j_start+3; b++)
          if(fel[a][b] == z){
                return false;
                }


    return true;

  }

  int suche(int[][] fe, int z) {
    for (int i = 0; i < fe.length; i++) {
      for (int j = 0; j < fe.length; j++) {
        if (fe[j][i] == z) {
          return (10 * i) + j;
        }
      }
    }
     // System.out.println("falsch");
    return -1;
  }

  int suche(int[][] fe) {
    for (int i = 0; i < 9; i++) {
      for (int j = 0; j < 9; j++) {
        if (fe[j][i] == 0) {
          return (10 * i) + j;
        }
      }
    }

    return -1;
  }

  // Ende Methoden
  public static void main(String[] args) {
    new sudoku("sudoku");
  }
}

Die Ausgabe ist:
1,2,3,4,5,6,7,8,9,
4,5,6,7,8,9,3,2,1,
7,8,9,1,2,3,4,5,6,
2,1,4,3,6,5,8,9,7,
3,6,7,2,9,8,1,4,5,
5,9,8,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,

reihe(),spalte() und block() überprüfen ob die Zahl i in einer bereits vorkommt, also ob sie ungültig ist.
 
ich könnte es mir anschauen wenn du wenigstens
> int[][] test = new int[9][9];
> test = f;
erklärst
 
So wie ich das sehe hat der Teil nicht wirklich einen Sinn.
Ich bin noch Java Anfänger und dachte, dass ich eine Kopie erstelle und da ich wärend des programmierens nicht wusste ob ich ne Kopie brauche, habe ich einfach ne neue Variable genommen, es kommt mir nämlich nicht auf die geschwindigkeit an.
 
so, das war ja ein sehr klarer Fehler, sorry dass ich erst 2 Stunden weg war,
das Problem ist einfach, dass du beim Zurückgehen nicht das besetzte Feld wieder auf 0 löschst,
deshalb gehen die Prüfmethoden schief, es können keine anderen Kombinationen mehr ausprobiert werden,

Java:
  if (reihe(i, y, f) && spalte(i, x, f) && block(i, x, y, f)) {
        test[x][y] = i;
        loese(test);
        test[x][y] = 0; // neu
      }
das wars schon im wesentlichen, wie du weiter vorgehst musst du wissen,

-----

> if (suche(f) == -1)
paar Zeilen vorher ist die Bedingung für ein erfolgreich gelöstes Soduko,
bei lauter Nullen wird das ziemlich oft der Fall sein, mit vielen System.out.println() läuft das ganze ewig lange obwohl eigentlich schnell von Java zu rechnen, besonders wenn du auf das new int[9][9] verzichtest,
-----

wenn du die Berechnung in der actionPerformed() ausführst, dann ist die GUI solange blockiert, das ständige Update der Textfelder ist überhaupt nicht zu sehen,
du brauchst einen nebenläufigen Thread, etwa
Java:
	public void jButton1_ActionPerformed(ActionEvent evt) {
		Runnable r = new Runnable() {
			public void run() {
				speichern();
				loese(feld);
			}
		};
		new Thread(r).start();
	}
 
Vielen Dank für die schnelle und kompetente Hilfe, dass die Antwort 2 Stunden gedauert hat stört mich auch in keinster Weise, für ich wichtig ist nur dass es vor Morgen 8.10 Uhr funktioniert.
Ich denke auf die Threads wär ich nie im Leben gekommen, aber das mit dem test[x][y]=0; ist nur eine Alternative zu dem tatsächlichen erstellen einer Kopie eines Arrays. Die Proben sind alle für f aber die Änderungen werden in test vorgenommen, somit wäre eine Kopie eine andere Lösung, statt dem Referenz beibehalten und Stelle =0 setzen.
Also dann, ein widerholtes vielen Dank und freundliche Grüße.
"Wir sehn uns" dann bei meiner nächsen Frage( oder aber falls ich selbst jemand anderem helfen kann.):applaus::applaus:
 

Zurück
Oben