Sudoku Löser


  • Mod

    KN4CK3R schrieb:

    du glaubst doch nicht ernsthaft, dass sich jemand 300 Zeilen (schlecht formatierten) Quellcode durchliest, nur um deine Debugarbeit zu erledigen oder?

    Meinem Compiler macht das nichts aus:

    test.cc: In function ‘int main()’:
    test.cc:41:19: warning: missing braces around initializer for ‘int [9]’ [-Wmissing-braces]
    test.cc:41:19: warning: missing braces around initializer for ‘int [9]’ [-Wmissing-braces]
    test.cc:41:19: warning: missing braces around initializer for ‘int [9]’ [-Wmissing-braces]
    test.cc:41:19: warning: missing braces around initializer for ‘int [9]’ [-Wmissing-braces]
    test.cc:41:19: warning: missing braces around initializer for ‘int [9]’ [-Wmissing-braces]
    test.cc:41:19: warning: missing braces around initializer for ‘int [9]’ [-Wmissing-braces]
    test.cc:41:19: warning: missing braces around initializer for ‘int [9]’ [-Wmissing-braces]
    test.cc:41:19: warning: missing braces around initializer for ‘int [9]’ [-Wmissing-braces]
    test.cc:41:19: warning: missing braces around initializer for ‘int [9]’ [-Wmissing-braces]
    test.cc: In function ‘void gotoxy(int, int)’:
    test.cc:101:4: error: ‘COORD’ was not declared in this scope
    test.cc:101:10: error: expected ‘;’ before ‘cur’
    test.cc:102:42: error: ‘STD_OUTPUT_HANDLE’ was not declared in this scope
    test.cc:102:59: error: ‘GetStdHandle’ was not declared in this scope
    test.cc:102:61: error: ‘cur’ was not declared in this scope
    test.cc:102:64: error: ‘SetConsoleCursorPosition’ was not declared in this scope
    test.cc: At global scope:
    test.cc:99:6: warning: unused parameter ‘x’ [-Wunused-parameter]
    test.cc:99:6: warning: unused parameter ‘y’ [-Wunused-parameter]
    test.cc:157:6: warning: unused parameter ‘x’ [-Wunused-parameter]
    test.cc:172:6: warning: unused parameter ‘y’ [-Wunused-parameter]
    test.cc:223:6: warning: unused parameter ‘x’ [-Wunused-parameter]
    test.cc:223:6: warning: unused parameter ‘y’ [-Wunused-parameter]
    test.cc:223:6: warning: unused parameter ‘xa’ [-Wunused-parameter]
    test.cc:223:6: warning: unused parameter ‘xe’ [-Wunused-parameter]
    test.cc:223:6: warning: unused parameter ‘ya’ [-Wunused-parameter]
    test.cc:223:6: warning: unused parameter ‘ye’ [-Wunused-parameter]
    test.cc: In function ‘void erhoehen(int (*)[9], int, int, int&, int&, int&, int, int, int, int)’:
    test.cc:301:17: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
    test.cc: At global scope:
    test.cc:242:6: warning: unused parameter ‘ye’ [-Wunused-parameter]
    

    Lass dich nicht von den unbekannten Windowsfunktionen stören, ich habe eben kein Windows. Aber die anderen Warnungen sind deuten teilweise auf ganz schön dicke Hauer hin. Ganz besonders Zeile 301. Die unbenutzten Variablen sind auch ein schlechtes Zeichen.



  • Die ungenützten Variablen werden zur Zeit (für Testläufe) nicht verwendet.
    Das mit den Windows Funktionen lässt sich beheben.
    Was wäre denn ein möglicher Fehler, wenn zum Beispiel die Zahlensuche mit einer 2 Funktioniert. Wenn ich für Testzwecke die Zahl jedoch verändere, zum Beispiel 3 läuft das Programm nicht mehr fertig durch oder bricht ab.


  • Mod

    christianklemm schrieb:

    Was wäre denn ein möglicher Fehler, wenn zum Beispiel die Zahlensuche mit einer 2 Funktioniert. Wenn ich für Testzwecke die Zahl jedoch verändere, zum Beispiel 3 läuft das Programm nicht mehr fertig durch oder bricht ab.

    Grundlagen!
    = Zuweisung
    == Vergleich



  • Um das Problem etwas einzugrenzen.
    Das ist die Funktion zur Überprüfung der Zeile:

    void horizontal(int iFeld[9][9], int x, int y, int & hwert)                                     
    { 
    for(int i = 0; i < 9; i++) 
    { 
        if(iFeld[y][i] == hwert) 
        { 
        hwert++; 
        //horizontal(iFeld,x,y,hwert); 
        i = 0; 
        } 
    } 
    }
    

    und das die Funktion für die dazugehörige Spalte:

    void vertical(int iFeld[9][9], int x, int y, int hwert, int & vwert)                            
    {
    for(int i = 0; i < 9; i++)
    {
        if(iFeld[i][x] == vwert || iFeld[i][x] == hwert)
        {
        vwert++;
        //vertical(iFeld,x,y,hwert,vwert);
        i = 0;
        }
    }
    }
    

    Hier dürfte das Problem nicht liegen aber wie ist es möglich das es mit einer 2 funktioniert und mit einer 3 nicht?



  • Vielleicht kommst du auch auf die Idee, einen STL-Container wie std::array zu benutzen? Der wirt eine Exception (brauchst nicht zu wissen was das ist, es gibt aber bei Fehlern was auf die Konsole aus was du (oder zumindest wir) deuten kannst), wenn du z.B. einen Index größer als erlaubt angibst.
    Und dann kannst du auch ein typedef benutzen, um die ganze (wiederkehrende Tipparbeit) zu sparen.

    typedef std::array< std::array < size_t /* Nummer für das Feld, 0 heißt Leer */, 9 >, 9 > sudokuArray_t;
    
    sudokuArray_t field;
    


  • Das mit typedef ist eine gute Idee.
    Da ich in c/c++ nur die Grundlagen kenne weiß ich jetzt nicht genau was du mit STL-Container meinst.



  • christianklemm schrieb:

    Das mit typedef ist eine gute Idee.
    Da ich in c/c++ nur die Grundlagen kenne weiß ich jetzt nicht genau was du mit STL-Container meinst.

    STL = Standard Template Library = Standard - Template (Schablonen) - Bibliothek

    Ist schon ein merkwürdiges Wort, nicht? Template? Um es kurz zu machen (tutorials gibt es genug): Du machst dir ein eigenes Array.

    std::vector<int> vec;
    

    Hier haben wir einen std::vector instanziiert. std::vector ist eine Template-Klasse, die intern ein Array des übergebenen Typs anlegt (in diesem Fall vom Typ int).
    Das schöne daran ist, dass es dieses Array für uns verwaltet und einigen Ärger erspart. Es gibt neben std::vector natürlich noch andere Container wie std::list, std::deque, std::queue und noch viele (wichtige) andere...
    Verschiedene Funktionen erleichtern uns sofort das Leben:

    vec.size();//Größe des vectors. Hier 0, weil er noch Leer ist (wir haben nichts hineingetan)
    vec.push_back(5);//Wir legen eine 5 an die hinterste Position und vergrößern dabei natürlich den Vector um 1 (size() ist jetzt 1).
    vec.push_front(1);//size() ist jetzt 2. Einziger Unterschied zu push_back(): 1 wird jetzt (wie der Name suggeriert) ganz nach vorne getan.
    vec.pop_back();//Und pop_front, der bruder: Beide entfernen ein Objekt aus dem vector, pop_back() hinten und pop_front - na, rate mal. size() = 1.
    
    vec[0] = 4; //Der wert, der vorher 1 war, ist jetzt 4. Das Element an Position 0 also.
    vec.at(0) = 5;//dito, nur prüft diese Funktion, ob der übergebene Index (hier 0) größer als erlaubt ist (bei z.B. 100 würde er eine Exception werfen).
    
    vec.clear();//Löscht alle Elemente im vector. size() = 0.
    

    Es gibt noch viel mehr Funktionen, und Konstruktoren und noch Algorithmen (für alle Container). Das ist alles furchtbar interessant, schau mal hier.

    Das ist BTW ein sehr großes Thema, denn du wirst feststellen dass auch iteratoren, templates und so weiter eine große Rolle in der STL Spielen. Klar dauert das ein wenig, nur ist die STL so ungefähr das selbstverständlichste für jeden (C++)-Programmierer. Also lohnt es sich definitiv mal vorbeizuschauen (was du sowieso irgendwann tun musst).

    Zurück zu deinem Beispiel. Ein std::array ist etwas anderes als std::vector, da es nicht ver-größerbarer oder -kleinerbarer ist. Seine Größe bleibt gleich, deswegen übergeben wir sie als template-parameter übergeben. Der muss nicht umbedingt ein unbekannter Typ sein, es kann auch ein integraler sein (integral = int, short, char, long, und evt. long long):

    std::array<int, 8> ar;
    

    Hier können wir auf jedes dieser 8 Elemente zugreifen. Das ist für dein Sudoku-Feld nützlich, da seine Größe ja nicht änderbar ist. Oder? Eine Referenz zu std::array findest du im Netz.



  • ok danke für den ausführlichen Beitrag.
    Werde mich mal damit beschäftigen.

    Eine Frage hat von euch schon jemand einmal einen Sudokulöser programmiert?



  • christianklemm schrieb:

    Eine Frage hat von euch schon jemand einmal einen Sudokulöser programmiert?

    Ja, schon längst. Mit GUI und allem drum und dran.
    Das System das ich benutzt hab, ist Bruteforce.



  • Asoo. Hast du dir meinen Quellcode durchgelesen? Eventuell auf Denkfehler/Programmierfehler gestoßen?



  • christianklemm schrieb:

    Asoo. Hast du dir meinen Quellcode durchgelesen? Eventuell auf Denkfehler/Programmierfehler gestoßen?

    Ich werde deinen Code nicht lesen. Stattdessen ein professioneller Tipp: refactoring. Mach lieber gleich alles nochmal, und diesmal schön formatieren, gut planen (besonders den Algorithmus) und konzentriert arbeiten. Dann dauerts nur halb solang.



  • Ja, ganz klassisch in C. 🙂



  • Asoo. Ok. Wie würde denn ein Gut formatierter Quellcode ausschauen? 😃
    Ich hatte mir gedacht mein Quellcode ist schön 😋



  • @Cybertec Kann ich mir deinen Quellcode ansehen? 😋



  • christianklemm schrieb:

    Asoo. Ok. Wie würde denn ein Gut formatierter Quellcode ausschauen? 😃
    Ich hatte mir gedacht mein Quellcode ist schön 😋

    Oh nein... 😮 😃

    Zum formatieren habe ich mal ein kleines Tutorial geschrieben, such mal danach (kann es bei bestem Willen nicht finden). Sonst schau mal wie andere "formattieren"...



  • christianklemm schrieb:

    @Cybertec Kann ich mir deinen Quellcode ansehen? 😋

    Gib mal Deine Mailadresse, dann schick ich Dir meinen.


Anmelden zum Antworten