I'm writing a function that should generate random sudoku puzzles for a simulation project; this funcion takes as argoument the number of cells to generate then it generates the indexes of cells and numbers to put in those cells.
I have a problem in generation of cells indexes, I'm not an expert in programming and i can't find a good routine to generate indexes and to check out not to be the same index couple two times or more. The funcion is:
void gen_puzzle(int quanti)
{
if(quanti>81) exit(1);
indexes* ij=new indexes[quanti];
int f,g,k, controllo=1;
do
{
for(f=0; f<9; f++)
for(g=0; g<9; g++)
{
puzzle[f][g].num=0;//puts 0 in the sudoku puzzle
puzzle[f][g].p=0;
}
//////////////section to improve
out:
srand(int(time(0)+clock()));
for(k=0; k<quanti; k++)
ij[k].i=casuale()-1, ij[k].j=casuale()-1;//generates random indexes of sudoku cells where put random nubers
for(f=0; f<quanti; f++)
for(g=f+1; g<quanti; g++)
{
if(ij[f].i==ij[g].i && (ij[f].j==ij[g].j)) goto out;
}
////////////////////
for(k=0; k<quanti; k++)
puzzle[ij[k].i][ij[k].j] . num=casuale();//puts random numbers in cells
}
while(dataNotGood()); //till sudoku isn't good
}
I ask help for section where the funcion puts random indexes in ij[]
array, i used a goto
but it's not a good solution and it doesn't work well if quanti
is bigger then 17 about.
casuale()
just returns a random number between 1 and 9.
First of all, I'd strip out all the #pragma omp parallel
directives until you have code that works. Right now it just reduces readability.
Second, if you want to generate "unsolved" sudoku's (i.e. those where most numbers are not filled in) what you usually do is you fill in a few numbers at random and you test the sudoku by letting the computer solve it. If the comupter succeeds it means you started with a proper sudoku. Here you find a nice explanation of an algorithm that solves sudokus.
Third, be aware that the numbers you want to put in a sudoku puzzle are constrained quite a bit. If a 3x3 block (or a 9x1 line or column) contains a 1, you can't add additional 1's to the block (line, column), if a 9x9 block contains nine 1's you can't add additional 1's to it, etc. So probably it is better to fill an array of arrays with all the numbers you can add (nine arrays of 1-9 for all 3x3 blocks) and randomly take elements out of these arrays and put them into the puzzle in the corresponding 3x3 block. This way you at least avoid the situation where you add duplicate numbers to the same 3x3 block.
You don't need a random number generation algorithm. You already know the numbers: they are unique, and are in the range 1..n
, where n
should be <= 9
for sudoku boards of size 9x9 or smaller. What you need is a way to shuffle the numbers 1..n
, and then assign them to 'indices'. For shuffling, Fisher-Yates shuffle is pretty simple, and efficient.
Using that will eliminate the need for a random number generation, and hopefully the goto
as well.
My suggestion: create a complete (solved) puzzle using some algorithm found elsewhere, then you randomly erase a certain percentage of the cells.