# sudoku in c++



## MasterOfTheDark (5. November 2008)

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

using namespace std;

int main(int argc, char *argv[])
{
    int s[81];//array
    int i;//laufvariable der for schleifen
    srand(time(NULL));
    for(i=0;i<81;i=i+1)
    {
                     s[i]=rand()%9+1;
    }
    //wagrecht
    for(i=0;i<9;i=i+1)//schleife wird 8 mal durchgeführt, in der schlefie wird überprüft ob es //gleiche zahlen in der selben reihe gibt
    {
                      while((s[i*9]==s[i*9+1])||(s[i*9]==s[i*9+2])||(s[i*9]==s[i*9+3])||(s[i*9]==s[i*9+4])||(s[i*9]==s[i*9+5])||(s[i*9]==s[i*9+6])||(s[i*9]==s[i*9+7])||(s[i*9]==s[i*9+8]))//schließt aus, dass die erste zahl in der zeile gleich mit allen anderen ist
                      {
                            s[i*9]=rand()%9+1;
                      }
                      while((s[i*9+1]==s[i*9])||(s[i*9+1]==s[i*9+2])||(s[i*9+1]==s[i*9+3])||(s[i*9+1]==s[i*9+4])||(s[i*9+1]==s[i*9+5])||(s[i*9+1]==s[i*9+6])||(s[i*9+1]==s[i*9+7])||(s[i*9+1]==s[i*9+8]))//schließt aus, dass die zweite zahl in der zeile gleich mit allen anderen ist, die nächsten schleifen machen genau das selbe mit der darauffolgenend zahl=>zahlen einer zeile sidn immer unterschiedlich
                      {
                            s[i*9+1]=rand()%9+1;
                      }
                      while((s[i*9+2]==s[i*9+1])||(s[i*9+2]==s[i*9])||(s[i*9+2]==s[i*9+3])||(s[i*9+2]==s[i*9+4])||(s[i*9+2]==s[i*9+5])||(s[i*9+2]==s[i*9+6])||(s[i*9+2]==s[i*9+7])||(s[i*9+2]==s[i*9+8]))  
                      {
                            s[i*9+2]=rand()%9+1;
                      }
                      while((s[i*9+3]==s[i*9])||(s[i*9+3]==s[i*9+1])||(s[i*9+3]==s[i*9+2])||(s[i*9+3]==s[i*9+4])||(s[i*9+3]==s[i*9+5])||(s[i*9+3]==s[i*9+6])||(s[i*9+3]==s[i*9+7])||(s[i*9+3]==s[i*9+8]))  
                      {
                            s[i*9+3]=rand()%9+1;
                      }
                      while((s[i*9+4]==s[i*9])||(s[i*9+4]==s[i*9+1])||(s[i*9+4]==s[i*9+2])||(s[i*9+4]==s[i*9+3])||(s[i*9+4]==s[i*9+5])||(s[i*9+4]==s[i*9+6])||(s[i*9+4]==s[i*9+7])||(s[i*9+4]==s[i*9+8]))  
                      {
                            s[i*9+4]=rand()%9+1;
                      }
                      while((s[i*9+5]==s[i*9])||(s[i*9+5]==s[i*9+1])||(s[i*9+5]==s[i*9+2])||(s[i*9+5]==s[i*9+3])||(s[i*9+5]==s[i*9+4])||(s[i*9+5]==s[i*9+6])||(s[i*9+5]==s[i*9+7])||(s[i*9+5]==s[i*9+8]))  
                      {
                            s[i*9+5]=rand()%9+1;
                      }
                      while((s[i*9+6]==s[i*9])||(s[i*9+6]==s[i*9+1])||(s[i*9+6]==s[i*9+2])||(s[i*9+6]==s[i*9+3])||(s[i*9+6]==s[i*9+4])||(s[i*9+6]==s[i*9+5])||(s[i*9+6]==s[i*9+7])||(s[i*9+6]==s[i*9+8]))  
                      {
                            s[i*9+6]=rand()%9+1;
                      }
                      while((s[i*9+7]==s[i*9])||(s[i*9+7]==s[i*9+1])||(s[i*9+7]==s[i*9+2])||(s[i*9+7]==s[i*9+3])||(s[i*9+7]==s[i*9+4])||(s[i*9+7]==s[i*9+5])||(s[i*9+7]==s[i*9+6])||(s[i*9+7]==s[i*9+8]))  
                      {
                            s[i*9+7]=rand()%9+1;
                      }
                      while((s[i*9+8]==s[i*9])||(s[i*9+8]==s[i*9+1])||(s[i*9+8]==s[i*9+2])||(s[i*9+8]==s[i*9+3])||(s[i*9+8]==s[i*9+4])||(s[i*9+8]==s[i*9+5])||(s[i*9+8]==s[i*9+6])||(s[i*9+8]==s[i*9+7]))  
                      {
                            s[i*9+8]=rand()%9+1;
                      }
    }
    //wagrecht sollte unterschiedlich sein
    printf("%d %d %d %d %d %d %d %d %d  \n",s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[9],s[10],s[11],s[12],s[13],s[14],s[15],s[16],s[17]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[18],s[19],s[20],s[21],s[22],s[23],s[24],s[25],s[26]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[27],s[28],s[29],s[30],s[31],s[32],s[33],s[34],s[35]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[36],s[37],s[38],s[39],s[40],s[41],s[42],s[43],s[44]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[45],s[46],s[47],s[48],s[49],s[50],s[51],s[52],s[53]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[54],s[55],s[56],s[57],s[58],s[59],s[60],s[61],s[62]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[63],s[64],s[65],s[66],s[67],s[68],s[69],s[70],s[71]);
    printf("%d %d %d %d %d %d %d %d %d  \n\n\n\n",s[72],s[73],s[74],s[75],s[76],s[77],s[78],s[79],s[80]);
    //senkrecht
    for(i=0;i<9;i=i+1)
    {
                      while((s[i+9]==s[i])||(s[i+9]==s[i+18])||(s[i+9]==s[i+27])||(s[i+9]==s[i+36])||(s[i+9]==s[i+45])||(s[i+9]==s[i+54])||(s[i+9]==s[i+63])||(s[i+9]==s[i+72]))//erste zahl einer spalte ist unterschiedlich mit den anderen
                      {
                            s[i+9]=rand()%9+1;
                      }
                      while((s[i+18]==s[i])||(s[i+18]==s[i+9])||(s[i+18]==s[i+27])||(s[i+18]==s[i+36])||(s[i+18]==s[i+45])||(s[i+18]==s[i+54])||(s[i+18]==s[i+63])||(s[i+18]==s[i+72]))//2.zahl einer spalte ist unterschiedlich mit den anderen usw...
                      {
                            s[i+18]=rand()%9+1;
                      }
                      while((s[i+27]==s[i])||(s[i+27]==s[i+9])||(s[i+27]==s[i+18])||(s[i+27]==s[i+36])||(s[i+27]==s[i+45])||(s[i+27]==s[i+54])||(s[i+27]==s[i+63])||(s[i+27]==s[i+72]))
                      {
                            s[i+27]=rand()%9+1;
                      }
                      while((s[i+36]==s[i])||(s[i+36]==s[i+9])||(s[i+36]==s[i+18])||(s[i+36]==s[i+27])||(s[i+36]==s[i+45])||(s[i+36]==s[i+54])||(s[i+36]==s[i+63])||(s[i+36]==s[i+72]))
                      {
                            s[i+36]=rand()%9+1;
                      }
                      while((s[i+45]==s[i])||(s[i+45]==s[i+9])||(s[i+45]==s[i+18])||(s[i+45]==s[i+27])||(s[i+45]==s[i+36])||(s[i+45]==s[i+54])||(s[i+45]==s[i+63])||(s[i+45]==s[i+72]))
                      {
                            s[i+45]=rand()%9+1;
                      }
                      while((s[i+54]==s[i])||(s[i+54]==s[i+9])||(s[i+54]==s[i+18])||(s[i+54]==s[i+27])||(s[i+54]==s[i+36])||(s[i+54]==s[i+45])||(s[i+54]==s[i+63])||(s[i+54]==s[i+72]))
                      {
                            s[i+54]=rand()%9+1;
                      }
                      while((s[i+63]==s[i])||(s[i+63]==s[i+9])||(s[i+63]==s[i+18])||(s[i+63]==s[i+27])||(s[i+63]==s[i+36])||(s[i+63]==s[i+45])||(s[i+63]==s[i+54])||(s[i+63]==s[i+72]))
                      {
                            s[i+63]=rand()%9+1;
                      }
                      while((s[i+72]==s[i])||(s[i+72]==s[i+9])||(s[i+72]==s[i+18])||(s[i+72]==s[i+27])||(s[i+72]==s[i+36])||(s[i+72]==s[i+45])||(s[i+72]==s[i+54])||(s[i+72]==s[i+63]))
                      {
                            s[i+72]=rand()%9+1;
                      }
                      
    }               
    //senkrecht sollte unterschiedlich sein  
    printf("%d %d %d %d %d %d %d %d %d  \n",s[0],s[1],s[2],s[3],s[4],s[5],s[6],s[7],s[8]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[9],s[10],s[11],s[12],s[13],s[14],s[15],s[16],s[17]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[18],s[19],s[20],s[21],s[22],s[23],s[24],s[25],s[26]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[27],s[28],s[29],s[30],s[31],s[32],s[33],s[34],s[35]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[36],s[37],s[38],s[39],s[40],s[41],s[42],s[43],s[44]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[45],s[46],s[47],s[48],s[49],s[50],s[51],s[52],s[53]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[54],s[55],s[56],s[57],s[58],s[59],s[60],s[61],s[62]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[63],s[64],s[65],s[66],s[67],s[68],s[69],s[70],s[71]);
    printf("%d %d %d %d %d %d %d %d %d  \n",s[72],s[73],s[74],s[75],s[76],s[77],s[78],s[79],s[80]);
    system("PAUSE");
    return EXIT_SUCCESS;
}
```

nun hab ich das problem, dass ich nicht weiß, wie ich das ganze zu einem "richtigen" sudoku zusammenfüge(ohne die regel, dass in jedem 3x3 quadrat jede zahl nur einmal vorkommen darf)
lg masterOfTheDark ;-)


----------



## Guillermo (6. November 2008)

Hallo!
Also ich weiß nicht, vielleicht bin ich ja zu dumm, aber ich werde aus deinem Code nicht schlau, obwohl dass was er erzeugt zumal nicht schlecht aussieht! Könnest du deinen Code vielleicht nochmal etwas genauer erläutern und erklären, was genau die Schleifen machen, werde nämlich wirklich nicht daraus schlau, vielleicht kann ich dir dann helfen, und was meinst du mit "richtigem" Sudoku?
Da ich mich auch mal mit Sudokus  befasst habe / befasse (Lösungsalorithmen), sag ich einfach mal was dazu:
Besser wäre es, wenn du ein 2 dimensionales Array anlegst also z.B. feld[x][y]
Dann könntest du auch viel einfacher das mit den Quadraten einbauen!

//Edit: Ich denke, am einfachsten wäre es, wenn man eine Funktion schreibt, die rekursiv agiert (Sich selbst aufruft) ! Falls du nicht weißt wie das gehen soll , sag mir bescheid


----------



## MasterOfTheDark (6. November 2008)

ich werd das heute mit einem 2dimensionalen array mal versuchen

in einem richtigen sudoku sind ja in jedem 3x3 feld,jedr spalte und jeder zeile immer die zahlen 1-9, das 3x3 feld ist mir jz noch egal, ich versuche mal nur das die regeln mit den spalten und zeilen stimmt, was mit oben eigentlich gelungen ist, aber wenn ich die ausgabe nach der 1. for schleife weglasse stimmen weder die reihen noch die spalten

lg MasterOfTheDark

PS:erklärung der schleifen stehen im code oben drin(reineditiert)


----------



## Guillermo (6. November 2008)

Hallo MasterOfTheDark,

ich versuche gleich mal einen Code aufzusetzten, ich sag dir bescheid , wenn ich fertig bin


----------



## Guillermo (6. November 2008)

So, bin jetzt fertig, habe aber ein bestimmtes System hinter diesem Algorithmus, d.h. erst muss ich dir ein paar Sachen dazu erzählen:
Mein Sudoku funktioniert so : 
Ich habe die 9 Quadrate einfach von 0 bis 8 durchnummeriert.
Und die x Koordinate auch von 0 bis 8 , genauso wie die y - Koordinate.
Hier ein Bild zum besseren verständnis:
http://legende.le.ohost.de/sudoku_system.jpg
Ja, und hier der Code, wenn du fragen hast, dann schreib einfach 
Der ist jetzt in C , das macht ja kein Unterschied, du musst einfach nur deine Includs ändern!

```
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int feld[9][9];

//In welchem quadrat liegt das feld mit den koordinaten x und y?
int welches_quadrat(int x,int y) {
    int quadrat;
    if(x >= 0 && x<=2 && y>= 0 && y<=2) quadrat=0;
    if(x >= 0 && x<=2 && y>= 3 && y<=5) quadrat=3;
    if(x >= 0 && x<=2 && y>= 6 && y<=8) quadrat=6;
    
    if(x >= 3 && x<=5 && y>= 0 && y<=2) quadrat=1;
    if(x >= 3 && x<=5 && y>= 3 && y<=5) quadrat=4;
    if(x >= 3 && x<=5 && y>= 6 && y<=8) quadrat=7;
    
    if(x >= 6 && x<=8 && y>= 0 && y<=2) quadrat=2;
    if(x >= 6 && x<=8 && y>= 3 && y<=5) quadrat=5;
    if(x >= 6 && x<=8 && y>= 6 && y<=8) quadrat=8;

    return quadrat;
}

//Ist die Zahl im quadrat schon vorhanden?
int vorhanden_quadrat (int quadrat,int zahl)
{
	int xBegin,yBegin,exists = 0;
	switch(quadrat) {
		case 0: xBegin = 0; yBegin = 0; break;
		case 1: xBegin = 3; yBegin = 0; break;
		case 2: xBegin = 6; yBegin = 0; break;
		case 3: xBegin = 0; yBegin = 3; break;
		case 4: xBegin = 3; yBegin = 3; break;
		case 5: xBegin = 6; yBegin = 3; break;
		case 6: xBegin = 0; yBegin = 6; break;
		case 7: xBegin = 3; yBegin = 6; break;
		case 8: xBegin = 6; yBegin = 6; break;
	}

	//Proves if Number already exists in this square
	for (int y = yBegin; y <= (yBegin + 2) ; y++) {
		for (int x = xBegin ; x <= (xBegin + 2) ; x++) {
			if (zahl == feld[x][y]) exists = 1;
		}
	}
	return exists;
}

//ist die zahl in der zeile y schon vorhanden?
int vorhanden_zeile(int y,int zahl) {
    int vorhanden = 0;
    for(int i=0;i<=8;i++) {
            if(feld[i][y]==zahl) vorhanden = 1;
    }
	return vorhanden;
}

//ist die zahl in der zeile x schon vorhanden?
int vorhanden_spalte(int x,int zahl) {
    int vorhanden = 0;
    for(int i=0;i<=8;i++) {
            if(feld[x][i]==zahl) vorhanden = 1;
    }
	return vorhanden;
}

//Schreibt eine Zahl in das Feld mit den einer bestimmten x und y koordinate
int zahl_erzeugen(int x,int y) {
    //Zufallszahl zwischen 1 und neun generieren
    int zufallszahl = rand()%9+1;
    //Schauen in welchem Quadrat das Feld liegt.
    int quadrat = welches_quadrat(x,y);
    
    if(vorhanden_quadrat(quadrat,zufallszahl) == 0 && vorhanden_spalte(x,zufallszahl)==0 && vorhanden_zeile(y,zufallszahl==0) ) return zufallszahl;
    else return zahl_erzeugen(x,y);
}

//sudoku ausgeben
void show(void)
{
	int x,y;
	printf("\n");
	for(y=0;y<=8;y++)
	{
		
		if (y%3 == 0 && y != 0) printf("-----------\n");

		for(x=0;x<=8;x++)
		{
			
			if (x%3 == 0 && x!=0) printf("|");
			

			printf("");
			if(feld[x][y] == 0) printf(" ");
			else printf("%i",feld[x][y]);
			printf("");
		}

		//Neue Zeile
		printf("\n");
		
	}
}

int main(int argc,char *argv[]) {
    srand(time(NULL));
    //Schleife für y-Koordinaten
    for(int y=0;y<9;y++){
            //Schleife für x-Koordinaten
            for(int x=0;x<9;x++) {
                    feld[x][y]=zahl_erzeugen(x,y);
            }
    }
    
    show();
    
    
    system("pause");
    return 0;
}
```

//Edit: Hier wird sogar die Quadratregel beachtet


----------



## engelmarkus (6. November 2008)

Hier ist der Code für einen Sudoku-Generator und -Löser, bei dem kannst du dir ein paar ganz interessante Sachen abschauen:
http://ostermiller.org/qqwing/qqwing.cpp.html


----------



## engelmarkus (6. November 2008)

Hier ist der Code für einen Sudoku-Generator und -Löser, bei dem kannst du dir ein paar ganz interessante Sachen abschauen:
http://ostermiller.org/qqwing/qqwing.cpp.html

EDIT: Sorry, hab aus Versehen auf F5 gedrückt(?)


----------



## MasterOfTheDark (6. November 2008)

hab leider überhaupt keine ahnung von algorythmen.


----------



## Guillermo (7. November 2008)

Da braucht mein keine Ahnung  Ist einfach Übung
Hast du ICQ, dann kann ich dir vll weiterhelfen...


----------



## CSANecromancer (7. November 2008)

@Master: 
http://de.wikipedia.org/wiki/Algorithmus
Wenn du dich ernsthaft mit Programmierung beschäftigen möchtest, gibt es noch ein hervorragendes Buch, das auch "Algorithmen" heißt:
http://www.amazon.de/Algorithmen-Ro...=sr_1_7?ie=UTF8&s=books&qid=1226041212&sr=8-7


----------



## bbros (14. Juni 2011)

Hallo ich habe das Sudoku von Guillermo mal in c++ umgesetzt. Kam bei dir in c auch ein Stack overflow ?

Wenn Ich in c++ die Random Funktion aufrufe und einen Wert über 12 nehmen läuft alles perfekt, aber ist der random wert (rand()%9+1) schmiert mein Programm fast instant ab und die Fehlermeldung ist Stackoverflow..

Kann mir da einer vielleicht weiterhelfen ?


----------



## deepthroat (14. Juni 2011)

Hi.





bbros hat gesagt.:


> Hallo ich habe das Sudoku von Guillermo mal in c++ umgesetzt. Kam bei dir in c auch ein Stack overflow ?
> 
> Wenn Ich in c++ die Random Funktion aufrufe und einen Wert über 12 nehmen läuft alles perfekt, aber ist der random wert (rand()%9+1) schmiert mein Programm fast instant ab und die Fehlermeldung ist Stackoverflow..


Also erstmal sollte man niemals etwas wie rand() % x verwenden. Gute Zufallszahlen erzeugt man so:

```
rand() / (RAND_MAX + 1.0) * x
```
Schreib dir eine Funktion dafür die Werte in einem bestimmten Interval zurückgibt.

Ein Stack-Overflow deutet darauf hin, das deine Rekursionstiefe zu hoch ist. Versuche das Problem iterativ zu lösen. Oder du hast einfach einen Fehler gemacht und eine Endlos-Rekursion programmiert... dann zeig deinen Code.

Gruß


----------



## bbros (14. Juni 2011)

Hier die Version Ohne deinen Vorschlag, so wie ich sie im moment noch "verwende" (wenns klappen würden  )


```
#include <iostream> 
#include <time.h>
#include <stdlib.h>

using namespace std;

int sfeld[9][9]; // "Spielfeld"

// Zum ermitteln in welchem Block die Koordinaten x, y liegen
int welcher_block(int x, int y)
{
	int block = 0;
	
	if((x >= 0 && x <= 2) && (y >= 0 && y <= 2)) block = 0;
	if((x >= 0 && x <= 2) && (y >= 3 && y <= 5)) block = 3;
	if((x >= 0 && x <= 2) && (y >= 6 && y <= 8)) block = 6;
	
	if((x >= 3 && x <= 5) && (y >= 0 && y <= 2)) block = 1;
	if((x >= 3 && x <= 5) && (y >= 3 && y <= 5)) block = 4;
	if((x >= 3 && x <= 5) && (y >= 6 && y <= 8)) block = 7;
	
	if((x >= 6 && x <= 8) && (y >= 0 && y <= 2)) block = 2;
	if((x >= 6 && x <= 8) && (y >= 3 && y <= 5)) block = 5;
	if((x >= 6 && x <= 8) && (y >= 6 && y <= 8)) block = 8;

	return block;
}

//Ermitteln der Startpositionen des übergeben Blocks
int pruefe_block(int block, int zahl)
{
	int begin_x = 0;
	int begin_y = 0;
	int exist = 0;
	
	switch(block)
	{
		case 0: begin_x = 0; begin_y = 0; break;
		case 1: begin_x = 3; begin_y = 0; break;
		case 2: begin_x = 6; begin_y = 0; break;
		
		case 3: begin_x = 0; begin_y = 3; break;
		case 4: begin_x = 3; begin_y = 3; break;
		case 5: begin_x = 6; begin_y = 3; break;
		
		case 6: begin_x = 0; begin_y = 6; break;
		case 7: begin_x = 3; begin_y = 6; break;
		case 8: begin_x = 6; begin_y = 6; break;
	}
	
	for(int y = begin_y; y <= (begin_y+2); y++)
	{
		for(int x = begin_x; x <= (begin_x+2); x++)
		{
			if(sfeld[x][y] == zahl)
				exist = 1;
		}
	}
	return exist;
}

// Prüfen ob die Zahl schon in der Reihe X vorhanden ist
int pruefe_reihe_x(int x, int zahl)
{
	int vorhanden = 0;
	for(int i = 0; i <9; i++)
	{
		if(sfeld[x][i] == zahl)
		vorhanden = 1;
	}
	return vorhanden;
}

// Prüfen ob die Zahl schon in der Reihe Y vorhanden ist
int pruefe_reihe_y(int y, int zahl)
{
	int vorhanden = 0;
	for(int i = 0; i <9; i++)
	{
		if(sfeld[i][y] == zahl)
		vorhanden = 1;
	}
	return vorhanden;
}

//Erzeugen der ZZahl an der Position X,Y
int erzeuge_zahl(int x, int y)
{
	int zahl = rand()%9+1;
	int block = welcher_block(x,y);
	
	if( ( pruefe_block(block,zahl) == 0 )&& 
			( pruefe_reihe_x(x, zahl) == 0) && 
				( pruefe_reihe_y(y,zahl) == 0) )
	{
			return zahl;
	}else return erzeuge_zahl(x,y);
}

//Anzeigen des befüllten "Spielfeldes"
void anzeigen(int array_feld[][9], int zeilen, int spalten)
{
	for(int y = 0; y < spalten; y++)
	{
		for(int x = 0; x < zeilen; x++)
		{
			cout << "\t " << array_feld[x][y] << " ";
		}
		if(y == 2 || y == 5 ||y == 8)
		{
			cout << endl;
		}
		cout << endl;
	}
}

int  main ()
{
	srand ( (unsigned) time (NULL));
	
	for(int y = 0; y < 9; y++)
	{
		for(int x = 0; x <9 ; x++)
		{
			erzeuge_zahl(x,y);
		}
	}
	
	anzeigen(sfeld);
	return 0;
}
```

Was ich noch festgestellt habe, ist dass wenn ich die rand() funktion mit Modulo verwende und den wert über auf 12 setzte --> rand()%12+1 --> Funktioniert es in den meisten fällen ohne dass er mir nen Stackoverflow erzeugt.. geh also alles über 12 funktioniert.. aber darunter hängt es sich direkt auf


// Hatte ich wohl nen kleinen Tippfehler drinne.. --> klappt aber trotzdem nicht


----------



## deepthroat (14. Juni 2011)

Ich erhalte folgende Fehlermeldungen:

```
sudoku.cpp: In function 'int erzeuge_zahl(int, int)':
sudoku.cpp:93:32: error: 'prufe_reihe_x' was not declared in this scope
sudoku.cpp:94:31: error: 'prufe_reihe_y' was not declared in this scope
sudoku.cpp: In function 'int main()':
sudoku.cpp:129:19: error: too few arguments to function 'void anzeigen(int (*)[9], int, int)'
sudoku.cpp:101:6: note: declared here
```
\edit: Ansonsten liegt das Problem in der erzeuge_zahl Funktion, die ständig selbst aufgerufen wird. In Kombination mit der Verwendung des Modulo-Operators um eine Zufallszahl im Bereich 1 bis 9 zu generieren geht das dann schief.

Die Lösung ist die Zufallszahlen anders zu generieren und Iteration statt Rekursion zu verwenden.

Gruß


----------



## bbros (24. August 2011)

Ich hab das Sudoku mal umgebastelt und zum laufen gebracht.
Ist zwar jetzt etwas anders als vorher, aber es läuft und hat sogar noch ein zwei zusatz funktionen bekommen. 


```
#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;
}
```

Falls Fragen dazu da sind, werde ich die gerne beantworten.

Mfg 

BBros


----------

