// Die Implementierungs-Klasse für Sudoku
// In dieser Klasse ist die Lösungslogik
// Klaus Kusche, 2010

#ifndef SOLVER_H
#define SOLVER_H

#include "sudoku.h"

class Solver
{
  public:
    // gui ... Zeiger auf das Gui
    // (damit man dessen Funktionen zur Anzeige aufrufen kann)
    Solver(Sudoku *gui);

    // Löse das Sudoku
    //
    // Es sollen der Reihe nach alle Lösungen gesucht werden.
    //
    // Es soll jeder Zwischenschritt
    // (jedes Setzen / Ändern / Löschen einer Position) angezeigt werden.
    //
    // Returnwert: 
    // 3 Möglichkeiten:
    // * Die vorbelegten Zahlen sind ungültig, die Zahl n ist doppelt:
    //   - Returnwert: -n
    //   - Anzeige-Zustand ist der Anfangszustand
    // * Es gibt keine (weitere) Lösung:
    //   - Returnwert: Anzahl der gefundenen Lösungen
    //   - Anzeige-Zustand ist der Anfangszustand
    // * Eine der Gui-Funktionen returnierte "aufhören"
    //   - Returnwert: Anzahl der gefundenen Lösungen
    //   - Anzeige-Zustand ist der aktuelle Zustand
    int Go();

  private:

    // Überträgt die vorbelegten Zahlen aus dem GUI
    // mittels GetValue nach "value", prüft auf Gültigkeit,
    // und initialisiert xUsed, yUsed und zUsed entsprechend
    // Returnwert: 0 wenn alles ok,
    // n wenn die Zahl n in der Vorbelegung doppelt ist
    int GetInput();

    // Versucht, eine Zahl für Position pos zu finden
    // (und wenn es eine gefunden hat, rekursiv für die restlichen Positionen)
    // (alle davor sind schon richtig belegt)
    // Returnwert: 1 ... sofort aufhören, 0 ... weitersuchen
    // (*nicht* Erfolg / Mißerfolg!)
    int Solve(int pos);

    // Zeiger auf das Gui
    Sudoku *myGui;
    
    // Anzahl der bisher gefundenen Lösungen
    int solvCnt;
    
    // Aktuelle Belegung (0...9, 0 ist frei), zeilenweise
    int value[NUM_POS];

    // Abbildung value-Index auf Zeilennummer, Spaltennummer, Blocknummer 0-8
    // Konstant, im Konstruktor initialisiert
    int row[NUM_POS], col[NUM_POS], block[NUM_POS];
        
    // Welche Ziffern sind in Zeile i / Spalte i / Block i
    // aktuell schon vergeben?
    // Bitmaske: Letztes Bit...1, vorletztes Bit...2 usw.
    // Bit ist 0 wenn frei, 1 wenn vergeben
    int xUsed[NUM_COL], yUsed[NUM_COL], zUsed[NUM_COL];
};

#endif
