# Soduku-Löser



## ReVonX (8. Mai 2007)

Ich arbeite gerade an einem Programm für die Lösung eines Soduku-Lösers ! Ich brauche eine Abfrage um zuprüfen ob sich die eingegebene Zahl zwischen 1 und 9 befinden wenn ja soll "zulässig" wenn nicht "unzulässig" ausgegeben werden!  Im weiteren soll geprüft werden ob sich es bei der Eingabe vielleicht um einen Buchstaben handelt! 

Kann mir jemand weiter helfen.


----------



## giofyxle (8. Mai 2007)

Hallo!

Du gibst etwas wenig Infos. 
In C/C++ kannst Du das so machen:

Lese den Inhalt des Eingabefelds in eine Variable char [] strText ein:

int iValue = atoi(strText);
if((iValue > 0) && (iValue <= 9))
{
// dann eine Zahl zwischen 1 und 9
}
else
{
sonst wurde keine Zahl oder eine andere Zahl ausser 1,....,9 eingegeben
}


Reicht das?


Was mich interessieren würde:

Erkennt Dein Sudokulöser auch, ob das Sudoku nur eine oder mehrere Lösungen hat?

Grüße,

giofyxle


----------



## ReVonX (9. Mai 2007)

Ok das versuch ich mal!
Da es zuwenig Infos waren hier mal der Lösungsansatz:

```
#include <cstdlib>
#include <iostream>

using namespace std;

//Funktionsprototypen
void eingabe (void);

int Feld [9][9];


//Funktionsdefinitionen
void eingabe ()
{
      for (int i = 0; i <=8; i++ )
    {
          
          for (int j = 0; j <= 8; j++)
              {
                cout << "Bitte geben sie die " << (j+1) << ". Zahl der " << (i+1) << ". Reihe ein!" << endl;
                cin >> (Feld[i] [j]);       
              }
           
    }
    
    cout << endl;
}

// Definition der Variablen
int sudoku[9][9] = {0};

// Definition der Funktionsprototypen
int Gueltigkeit_pruefen(int, int, int);

// Funktionsdefinition für die Prüfung der Felder
int Gueltigkeit_pruefen(int Zeile, int Spalte, int Zu_pruefende_Zahl)
{
    for (int i=0;i<8;i++)
     {
             if(Zu_pruefende_Zahl == sudoku [i] [Spalte])
              {
               return 0;
              }
     }
     
     for (int i=0;i<8;i++)
     {
             if(Zu_pruefende_Zahl == sudoku [Zeile] [i])
              {
               return 0;                         
              }
     }     
     return 1;
}



//Aufruf Hauptprogramm
int main()
{
    char f = 'n';

  void eingabe();
    while ( f=='n')
    {
    
   int Zahl = 0;
   int Z = 0;
   int S = 0;
   cout << "Geben Sie eine Zahl ein, die auf Gueltigkeit geprueft werden soll!\n";
   cin >> Zahl;
   cout << "Geben Sie im Folgenden die Position der Zahl an: \n";
   cout << "Zeile : ";
   cin >> Z;
   cout << "Spalte: ";
   cin >> S;
      
   // Prüfung der eingegebenen Zahl aufrufen:
   int OK = 0;
   OK = Gueltigkeit_pruefen (Z-1,S-1,Zahl);
   
   // Ergebnis ausgeben:
   if ( OK == 1 )
    cout <<"Zahl zulaessig!\n";
   else
    cout <<"Zahl nicht zulaessig!\n";  
    
   //Anfang der Ausgabe in Tabelle!
   
    cout << "+------------------------------------------------------------------------+" << endl;
    
    for (int i=0; i <= 8; i++)
     {
         cout << "| " << int (Feld[i][0]) 
              << "\t |  " << int (Feld[i][1])  << "\t |  " << int (Feld[i][2]) 
              << "\t |  " << int (Feld[i][3])  << "\t |  " << int (Feld[i][4]) 
              << "\t |  " << int (Feld[i][5]) << "\t |  " << int (Feld[i][6]) << "\t |  "
              << int (Feld[i][7]) << "\t  |  " << int (Feld[i][8]) << "\t |  " << endl;
         cout << "+------------------------------------------------------------------------+" << endl;     
     }
    
    //Abfrage ob Angaben korrekt sind!
    cout << "Sind ihre Angaben korrekt? (y / n)" << endl;
    cin >> f;
    } 
    

    
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
```

Ob das Programm erkennen kann ob es eine oder mehrere Lösungen gibt darüber hab ich noch nicht nachgedacht aber die Idee ist gut!

Gruß ReVonX


----------



## zerix (9. Mai 2007)

Hallo,

also wenn dein Programm die Sudokus selbst generiert, dann musst du einfach noch soviele Zahlen anzeigen, dass das Sudoku noch eindeutig ist. 
Ein Bekannter von mir hat es so gemacht. Sein Programm generiert sich komplette Sudokus und lässt dann einfach Zahlen weg. Lässt aber noch soviele Zahlen da, dass es noch eindeutig zu lösen ist.
Wenn du das genau so löst, hast du das Problem mir der Prüfung nicht mehr, ob es mehrere Lösungen gibt.

MFG

zEriX


----------



## the_undertaker (11. Mai 2007)

Hallo, wenn ihr die Code-Tags benutzt wird das ganze ein bisschen übersichtlicher.


----------



## ReVonX (16. Mai 2007)

Vielen Dank für eure Tipps aber wirklich weitergeholfen haben sie mir bisher nicht.
Hier die neue Version des Programmes. Problem ist nun nach dem kompilieren geht das Programm sofort zur Ausgabe über und überspring meine Eingabe!!

```
#include <cstdlib>
#include <iostream>

using namespace std;

// Definition der Variablen
int sudoku[9][9] = {0};

int Z,S,Zahl;
// Definition der Funktionsprototypen
int Gueltigkeit_pruefen(int, int, int);

//Funktionsprototyp
void ausgabe (void);

//Funktionsprototyp
void eingabe (void);

void ausgabe (void){
int x,y;

    for(int x=0; x!=9; x++)
    {
            for(int y=0; y!=9;y++)
            {
                    cout << sudoku[x][y]<< " ";}
                    cout << "" << endl;
                    }
}



      void eingabe (void) {
      int a,b;
      
    do {
    cout << "Geben Sie eine Zahl für die X-Achse an." << endl;
    cin >> a; 
    cout << "Geben Sie eine Zahl für die Y-Achse an." << endl;
    cin >> b;
    
    cout << "Geben sie eine Zahl ein, die sie in dem Feld haben möchten! (1-9)" << endl;
    cin >> sudoku[a-1][b-1];
    cout << sudoku[a-1][b-1]<< endl;
    cout << "" << endl;
    cout << "Hier sieht man das ganze Sodoku:" << endl;
    
    ausgabe();
    
}
while (sudoku[a-1][b-1]!=0);
}

// Definition der Funktionsprototypen
int Gueltigkeit_pruefen(int, int, int);

// Funktionsdefinition für die Prüfung der Felder
int Gueltigkeit_pruefen(int Zeile, int Spalte, int Zu_pruefende_Zahl)
{
    for (int i=0;i<8;i++)
     {
             if(Zu_pruefende_Zahl == sudoku [i] [Spalte])
              {
               return 0;
              }
     }
     
     for (int i=0;i<8;i++)
     {
             if(Zu_pruefende_Zahl == sudoku [Zeile] [i])
              {
               return 0;                         
              }
     }     
     return 1;
}



//Aufruf Hauptprogramm
int main()
{
 char f;
  void eingabe();

      
   // Prüfung der eingegebenen Zahl aufrufen:
   int OK = 0;
   OK = Gueltigkeit_pruefen (Z-1,S-1,Zahl);
   
   // Ergebnis ausgeben:
   if ( OK == 1 )
    cout <<"Zahl zulaessig!\n";
   else
    cout <<"Zahl nicht zulaessig!\n";  
    
   //Anfang der Ausgabe in Tabelle!
   
    cout << "+------------------------------------------------------------------------+" << endl;
    
    for (int i=0; i <= 8; i++)
     {
         cout << "| " << int (sudoku[i][0]) 
              << "\t |  " << int (sudoku[i][1])  << "\t |  " << int (sudoku[i][2]) 
              << "\t |  " << int (sudoku[i][3])  << "\t |  " << int (sudoku[i][4]) 
              << "\t |  " << int (sudoku[i][5]) << "\t |  " << int (sudoku[i][6]) << "\t |  "
              << int (sudoku[i][7]) << "\t  |  " << int (sudoku[i][8]) << "\t |  " << endl;
         cout << "+------------------------------------------------------------------------+" << endl;     
     }
    
    //Abfrage ob Angaben korrekt sind!
    cout << "Sind ihre Angaben korrekt? (y / n)" << endl;
    cin >> f;
     
    

    
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
```


----------



## deepthroat (16. Mai 2007)

Hi.

Verwende doch bitte die *Code-Tags* für deinen Quelltext - d.h. du solltest C++ Code in [code=cpp]...[/code] Tags einschließen.. Ich persönlich schaue mir solch unleserlichen Code nicht mehr an.

Gruß


----------



## the_undertaker (16. Mai 2007)

Genau das, was ich auch schon gepostet habe, es hat nur anscheinend niemanden erreicht. Ich bin auch der Meinung, dass es einfach sonst zu unuebersichtlich ist!


----------



## ReVonX (22. Mai 2007)

So bitte hier hab ihr eure Tags!!
Aber wirklich weiter bin ich trotzdem noch nicht !!


----------



## the_undertaker (22. Mai 2007)

*Welche* Eingabe meinst du denn, die übersprungen wird?


----------



## Proko (22. Mai 2007)

jup, was genau meinst du mit die eingabe wird übersprungen?

ruft er die methode gar nicht auf, oder schreibt er zwar die dinge hin und fragt nach keiner eingabe, oder kommt er nicht in die do while schleife?

ich habe schon vor längerer zeit mit C++ eine com schnittstelle entwickelt, die man dann z.bsp. unter excel oder VB verwenden konnte, um ein Array zu lösen und _Alle_ möglichen sudoku lösungen geliefert bekommt

ich würde einfach mal ein bisschen debuggen, überlegen wegen deinen bedingungen, warum du da nicht reinkommst etc... wenn du nicht in Visual studio programmierst, dann gib einfach am anfang von der eingabe() mal was aus, und schau obst da reinkommst, usw... sonst einfach richtig debuggen

hier sind ein paar dinge die mir aufgefallen sind:
int sudoku[9][9] = {0}; ? da ich jetz mehr java programmiere, bin ich mir nicht sicher, aber für mich sieht das sehr sehr komisch aus.

bei mir sieht ein 2 dimensionales array in C++ so aus:

```
int** a;
int dimension;

a = new int*[dimension];
for (int i = 0; i < dimension; i++)
  a[i] = new int[dimension];
und dann in einer doppeltverschachtelten for schleife alle elemente mit 0 initialsieren
for 
  for
    a[i][j] = 0;
```

so würde ich in c++ ein 2-dim array machen, wenn das wirklich so kurz geht, schön ^^

und noch ein paar dinge die mir bezüglich sudoku selbst aufgefallen sind
deine gültigkeitsprüfung sieht definitiv falsch, ich habs nur überflogen, aber das ist nicht alles was ein sudoku haben muss

mach 3 methoden die bool liefern und verknüpfe diese mit einem und, wenn also eine davon falsch ist, ist das ganze nicht gültig
1. methode: zahl darf nur einmal in der reihe vorkommen
2. methode: zahl darf nur einmal in der spalte vorkommen
3. zahl darf nur einmal im quadrat vorkommen

ein guter sudokusolver ist gar nicht so leicht zu implementieren
wenn es dir nur darum geht das dein benutzer immer eine zahl mehr eingibt und du überprüfst obs noch stimmt, und dann die nächste zahl einliest, dann reicht dir diese gültigkeitsprüfung

wenn du das ganze vom computer berechnen lassen willst, gibt es 2 ansätze: zufälliges einfügen von zahlen, und probieren ob valid, wenn nicht, zurücksetzen neue zahl

oder mittels backtracking, dann werden auch _Alle_ lösungen gefunden, was aber bei einem 9x9 soduku mit ca. 5 zahlen vorgeben sehr sehr viele lösungen sind, das is dann zu beachten wie du dich entscheidest

und vielleicht darf ich noch die frage stellen, warum du einen Sudoku solver mit C++ machst? musst das für deine Schule / Studium machen? weil sonst gibts wirklich bessere sprachen dafür, wo man z.bsp. mit hilfe von grafischer oberfläche verwendet oder z.bsp. als COM schnittstelle under Excel verwendet

aber diese consolen geschichte als sudoku solver ist ja ziemlich eine wildes unterfangen

mfg


----------



## deepthroat (24. Mai 2007)

Hi.





ReVonX hat gesagt.:


> So bitte hier hab ihr eure Tags!!
> Aber wirklich weiter bin ich trotzdem noch nicht !!


Du wolltest nicht zufällig in Zeile 84 eigentlich die Funktion "eingabe" aufrufen, oder?

Das tust du aber nicht, das was da steht ist eine Funktionsdeklaration - die absolut nichts bewirkt. Nimm mal das Schlüsselwort "void" da weg.

Gruß


----------



## ReVonX (29. Mai 2007)

Das mit dem void war gut das hatte ich total übersehen und die anderen probleme sind auch schon teilweise gelöst.
Danke


----------

