For my end of term project, I've been working on a program that allows you to play sudoku, store your scores and times, create profiles, save and load games, the works. Starting off with the most basic bit, i.e. creating valid sudokus which are unique everytime the project is executed, I've been running into loads of problems.

Finally, I've made something that looks as if it'll work, and I wanted to have experienced eyes look over my program for generating sudokus for things that could be improved, and all. My basic outline was:

- Fill valid values randomly in the top and bottom row of the sudoku.
- Use a brute force while loop to fill in the rest of the values.
- Hide some values (randomly selected), and display the rest (60 for easy, 50 for medium, 40 for hard).
- Allow the user to solve it.

I've been working on generating full, unique sudokus at home, while the rest of my stuff is in my school computer. Originally, I was trying to fill valid values in every cell (by using random()), and not using the brute force thing at all. However, that was taking too long (because the values so filled couldn't make a valid sudoku game, and the computer would have to try near infinite combinations to get a valid game). So, in interests of expediency, I filled the top and bottom rows (so that sufficiently unique values could be generated without making the program go kaboom), and used the brute force thing. Unfortunately, sometimes, it still seems to go in 'forever calculating' mode.

I'm wondering: Is there a concept I could've applied that would've made things a lot easier? Is there something I've missed? Should I assign just one row instead of two, or something else? Would something do better than brute force?

I'd be grateful if you guys could help me answer this question.

#include<iostream.h> #include<conio.h> #include<stdlib.h> class sudoku { public: int arr[9][9]; int ch[9][9]; sudoku() { for(int x=0; x<9; x++) { for(int y=0; y<9; y++) {arr[x][y]=0; ch[x][y]=0;} } } void dis() { for(int x=0; x<9; x++) { for(int y=0; y<9; y++) {cout<<" "<<arr[x][y]<<" ";} cout<<"\n\n"; } } int comp(int num, int r, int c) { for(int x=0; x<9; x++) { if(arr[r][x]==num||arr[x][c]==num) {return 0;} } int row, col; //This stuff is for checking the 3x3 cell. if(r>=0&&r<=2) {row=0;} else if(r>=3&&r<=5) {row=3;} else if(r>=6&&r<=8) {row=6;} if(c>=0&&c<=2) {col=0;} else if(c>=3&&c<=5) {col=3;} else if(c>=6&&c<=8) {col=6;} for(x=row; x<row+3; x++) { for(int y=col; y<col+3; y++) {if(arr[x][y]==num) { if(x!=r&&y!=c) { return 0; } } } } return 1; } void assign() { randomize(); int row=0, col=0; int a; for(col=0; col<9; col++) { while(ch[row][col]==0) {a=random(9)+1; if(comp(a,row,col)==1) {arr[row][col]=a; ch[row][col]=a; break; } } } row=8; //I know, I could've used a dual for loop instead of this madness. Stupid me. for(col=0; col<9; col++) { while(ch[row][col]==0) { a=random(9)+1; if(comp(a,row,col)==1) { arr[row][col]=a; ch[row][col]=a; break; } } } } void brute() { int i=0,x,y; int flag; while(i<81) { flag=2; x = i/9; y = i%9; if(ch[x][y]==0) { flag=0; for(int j=arr[x][y]+1;j<10;j++) { if(comp(j,x,y)==1) { arr[x][y]=j; flag=1; break; } } } if(flag==0) { arr[x][y]=0; i--;} else { i++;} if(i==-1) { break;} } } }; void main() { int p=0; while(p<10)//This is just something I'm using to see how the code's working. Sometimes it works perfectly all 10 times, sometimes it goes into 'forever calculating mode' on the third try. { clrscr(); sudoku a; a.assign(); a.dis(); getch(); clrscr(); a.brute(); a.dis(); getch(); p++; } }