#include <iostream>
#include <time.h>
using namespace std;
int anz_felder = 9;
int block_groesse = 3;
int zu_loesen = 0;
int versuche = 0;
int sfeld[9][9];
char rfeld[9][9];
// Durchsucht die Reihe X nach Zahl.
// Wenn false zurück gegeben wird ist die Zahl nicht in der Reihe X
// Richtung 1 --> horizontal | Richtung 2 --> vertikal
bool pruefe_reihe(int z, int zahl, int richtung)
{
for(int i = 0; i < anz_felder; i++)
{
if(richtung == 1)
{
if(sfeld[z][i] == zahl)
return true;
}if(richtung == 2)
{
if(sfeld[i][z] == zahl)
return true;
}
}
return false;
}
// Durchsucht den 3x3 / 4x4 Block nach der angegeben Zahl
bool pruefe_block(int x, int y, int zahl)
{
int x_start = (x/block_groesse)*block_groesse;
int y_start = (y/block_groesse)*block_groesse;
for(int yy = y_start; yy < y_start+block_groesse; yy++)
{
for (int xx = x_start; xx < x_start+block_groesse; xx++)
{
if(sfeld[xx][yy] == zahl)
return true;
}
}
return false;
}
// Verbindet pruefe_block mit pruefe_reihe
// True --> Zahl vorhanden || False --> Zahl nicht vorhanden
bool check(int x, int y, int zahl)
{
if(pruefe_reihe(x,zahl,1)== true)
return true;
if(pruefe_reihe(y,zahl,2) == true)
return true;
if(pruefe_block(x,y,zahl) == true)
return true;
return false;
}
// Eine zufallszahl wird erstellt zwischen 1 und 9
int erzeuge_zahl(int x, int y)
{
int zahl = rand()%9+1;
if(check(x,y,zahl)== false)
{
return zahl;
}
return erzeuge_zahl(x,y);
}
// Ein Block wird zufällig mit 9 Zahlen gefuellt
void fuelle_block(int x, int y)
{
if(x<9)
{
for(int yy = y; yy < y+block_groesse; yy++)
{
for (int xx = x; xx < x+block_groesse; xx++)
{
sfeld[xx][yy] = erzeuge_zahl(xx,yy);
}
}
fuelle_block(x+3,y+3);
}
}
// Kopiere das INT Array in CHAR --> um Buchstaben abzuspeichern
void kopiere_feld(int spiel_feld[][9], char kopie_feld[][9])
{
for(int y= 0; y < anz_felder; y++)
{
for(int x = 0; x < anz_felder; x++)
{
kopie_feld[x][y] = spiel_feld[x][y]+48;
}
}
}
//
void ersetze_feld( int x, int y, char buchstabe)
{
rfeld[x][y] = buchstabe;
}
void ersetze_auf_feld(int anzahl_felder)
{
char buchstabe = 'a';
for(int i = 0; i < anzahl_felder; i++)
{
int x = rand() % anz_felder + 1;
int y = rand() % anz_felder + 1;
if(rfeld[x][y] >= 49 && rfeld[x][y] <= 57)
ersetze_feld(x, y, buchstabe+i);
else i--;
}
}
// Auswahl des Schwierigkeitsgrad
void schwierigkeit(int stufe)
{
int anzahl_felder = 1;
switch(stufe)
{
case 1: anzahl_felder = 10;
zu_loesen = anzahl_felder;
ersetze_auf_feld(anzahl_felder);
break;
case 2: anzahl_felder = 18;
zu_loesen = anzahl_felder;
ersetze_auf_feld(anzahl_felder);
break;
case 3: anzahl_felder = 25;
zu_loesen = anzahl_felder;
ersetze_auf_feld(anzahl_felder);
break;
default: anzahl_felder = 10;
zu_loesen=anz_felder;
ersetze_auf_feld(anzahl_felder);
break;
}
}
// zum ueberpruefen ob der eingegeben Wert für den eingegebenen Buchstaben
// richtig ist.
int pruefe_eingabe(char buchstabe, int zahl)
{
int richtig = 0;
for(int y = 0; y < anz_felder; y++)
{
for(int x = 0; x < anz_felder; x++)
{
if(rfeld[x][y] == buchstabe)
{
if(sfeld[x][y] == zahl)
{
rfeld[x][y] = zahl+48;
return richtig = 1;
}
}
}
}
return richtig;
}
int geloest (char array_feld[][9])
{
int geloest = 1;
for(int x = 0; x < anz_felder; x++)
{
for(int y = 0; y < anz_felder; y++)
{
if(array_feld[x][y] >= 97)
geloest = 0; // Noch nicht alle werte richtig
}
}
return geloest;
}
//anzeigen von den verschiedenen Feldern (arrays) { 1 --> sfeld (spielfeld) 2 --> rfeld (Ratefeld)}
void anzeigen(int i)
{
cout <<"|===|===|===||===|===|===||===|===|===|"<<endl;
for(int y = 0; y <anz_felder; y++)
{
for(int x = 0; x < anz_felder; x++)
{
if(i==1)
{
if(x == 2 || x == 5 || x == 8)
{
cout <<"| "<< sfeld[x][y] <<" |";
} else cout <<"| " << sfeld[x][y] << " ";
}else if(i==3)
{
if(x == 2 || x == 5 || x == 8)
{
cout <<"|"<<x<<"/"<<y<<"|";
}else cout <<"|" <<x<<"/"<<y<< "";
}else {
if(x == 2 || x == 5 || x == 8)
{
cout <<"| "<< rfeld[x][y] <<" |";
} else cout <<"| " << rfeld[x][y] << " ";
}
}
if(y == 2 || y == 5 || y == 8)
cout << endl <<"|===|===|===||===|===|===||===|===|===|"<< endl;
else cout << endl <<"|---|---|---||---|---|---||---|---|---|"<< endl;
}
}
//fuelle das Feld an pos(x,y) mit dem int Wert
void fuelle_feld(int x, int y, int wert)
{
sfeld[x][y] = wert;
}
// Loesen des Sudokus.
bool loese(int x, int y)
{
if(y == anz_felder)
{
x++;
if(x == anz_felder)
return true; // Man ist am letzten Feld des Spielfeldes angelangt
y = 0;
}
if(sfeld[x][y] > 0)
return loese(x, y+1);
for(int z = 1; z <= anz_felder; z++)
{
if(check(x, y, z) == false) // Wenn check --> False --> Zahl nicht vorhanden
{
sfeld[x][y] = z; // setze an Position x, y --> Zahl
if(loese(x,y+1) == true)// Wenn loese --> true --> abbruch
return true;
}
}
sfeld[x][y] = 0; // Falls kein Abbruch durch return true --> spielfeld auf 0 setzten
return false;
}
// Zum eingeben eines eigenen Sudokus (begint oben Links bei Feld 0,0)
// bei einem Leeren Feld muss eine 0 eingetragen werden.
void erstelle_eigenes(int groesse, int bgroesse, int edit)
{
int x = 0, y = 0, eingabe;
int ende = 0;
if(edit == 1)
anzeigen(1);
else { cout << "Beispiel:"<<endl;
anzeigen(3);
}
cout << "Geben Sie (0) - fuer leeres Feld \n (10) - zum beenden \n (12) - Feld zurueck\n";
do{
cout << "Bitte Ihren Wert fuer "<<x<< "/" <<y<<" eingeben:";
cin >> eingabe;
if(eingabe == 12)
{
x--;
}
if(eingabe != 10 && eingabe != 12)
{
fuelle_feld(x,y,eingabe);
x++;
if(x == anz_felder)
{
y++; x = 0;
if(x == anz_felder && y == anz_felder)
{
ende = 1;
}
}
}else ende = 1;
}while(ende != 1);
kopiere_feld(sfeld, rfeld);
cout << "Ihre eingaben: \n";
anzeigen(1);
cout <<"Sind die Daten korrekt? \n (1) - ja \n (2) nein. bearbeiten" <<endl;
cin >> eingabe;
if(eingabe == 1)
{
cout <<"Hier Ihr geloestet Sudoku."<<endl;
loese(0,0);
anzeigen(1);
}else erstelle_eigenes(groesse, bgroesse, 1);
}
void erstelle_sudoku(int groesse, int bgroesse)
{
int eingabe = 0;
char auswahl = ' ';
anz_felder = groesse;
block_groesse= bgroesse;
fuelle_block(0,0);
loese(0,0);
kopiere_feld(sfeld,rfeld);
cout << "Willkommen zum Sudoku."<<endl;
cout << "Waehlen Sie Ihren Schwierigkeitsgrad: \n(1) - leicht \n(2) - mittel \n(3) - schwer "<<endl;
cin >> eingabe;
schwierigkeit(eingabe);
do{
anzeigen(2);
cout << "Es sind noch "<<zu_loesen<<" Felder zu loesen."<<endl;
cout << "Welches Feld moechten Sie loesen? (Eingabe: Buchstabe Zahl): "<< endl;
cin >> auswahl >> eingabe;
if(pruefe_eingabe(auswahl, eingabe) == 1)
{
cout << "Richtig! " <<endl;
zu_loesen--;
}
else {
cout << "Leider Falsch ! "<<endl;
versuche++;
}
} while(geloest(rfeld) == 0);
cout << "Herzlichen Glueckwunsch Sie haben das Sudoku geschafft.\nSie haben "<< versuche<<" x Falsch gelegen." <<endl;
}
// Menue zur auswahl zwischen Spielen / Eingeben eines Sudokus / Beenden
void menue()
{
int eingabe = 0;
cout << "Willkommen zu SUdoku"<<endl;
cout << "Bitte waehlen Sie aus: \n (1) - ein Sudoku spielen \n (2) - ein Sudoku eingeben \n (0) - beenden"<<endl;
cin >>eingabe;
switch (eingabe)
{
case 1: erstelle_sudoku(9,3); break;
case 2: erstelle_eigenes(9,3,0); break;
case 0: break;
default: erstelle_sudoku(9,3);
}
}
int main()
{
srand((unsigned) time(0));
menue();
return 0;
}