Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Old 05-28-2006, 04:36 PM   #1 (permalink)
Manan
Registered User
 
Join Date: Jul 2005
Posts: 16
Manan is on a distinguished road
Sudoku Board Generation Algorithm. HELP!

Hi. I'm creating a Sudoku game for a C++ project. I'm still on the first step, and trying to generate a random Sudoku Board. My plan is to generate a fully complete board, then remove numbers from it one at a time, checking after each time whether it is solvable.
However, I can't get the computer to generate a correct board. So far, I can get it to display the columns correctly, each column containing the number 1 through 9 exactly once. But the rows and boxes both have repeating numbers in them. My algorithm is as follows:

1) For each column, put the number 1 through 9 in each column in random locations.
2) After that, I basically use brute force and randomization. Since the rows and boxes most likely won't be correct, keep on generating a random board and check after each time whether the board is correct or not(whether row/box has a repeating number).

So the problem is that using brute force takes way too long, and the program freezes before generating a good board. It goes through about 75,000 to 100,00 bad board iterations before it freezes. Help greatly appreciated!
-I know there is another sudoku algorithm thread, but that one involves solving, not generating a board.
Manan is offline   Reply With Quote
Old 05-29-2006, 06:37 PM   #2 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
Solving is harder than pure generation because you're searching for a specific solution.
I think you can be a bit smarter in your generation if instead of generating random digits 1-9, you instead make pools of numbers (I would use linked lists to represent the pools), and remove digits from the pool as you fill in the puzzle row by row. If I understand the rules of the game correctly, you'd need one pool for each column, one for each row, and one for each of the 9 3x3 blocks.

So you algorithm would be to randomly generate the first row, remove the digits you used from the corresponding pools, then as you generate each consecutive row, you pull a number from that row's pool, check to see that the digit you are trying to assign is in the column's pool, and the block pool before you assign it, then remove it from the pools. If your number is missing from one of the pools, go back to the row pool and try again.
It should guarantee that anything you generate is a valid puzzle board. I'm not sure if it will get stuck in an unassignable state towards the end though.
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 05-30-2006, 01:39 AM   #3 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
Hmm, so based on my testing, the algorithm I proposed never seems to make it past 44 squares before it gets stuck and needs to delete a number of steps and start over.
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 05-30-2006, 02:46 AM   #4 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
Okay so applying a bit more brainpower to the problem, all sudoku puzzles are basicaly the same but with the numbers in a different order, so if you have one vaild solution, you can use those numbers as a template for any others. The easiest one I can see is:
Code:
1 2 3|4 5 6|7 8 9|
4 5 6|7 8 9|1 2 3|
7 8 9|1 2 3|4 5 6|

2 3 4|5 6 7|8 9 1|
5 6 7|8 9 1|2 3 4|
8 9 1|2 3 4|5 6 7|

3 4 5|6 7 8|9 1 2|
6 7 8|9 1 2|3 4 5|
9 1 2|3 4 5|6 7 8|
If you treat those numbers as indexes into an array where each digit only appears once, you can generate any random puzzle. Here're two examples:
Code:
array:[9, 8, 7, 6, 5, 4, 3, 2, 1]
9 8 7|6 5 4|3 2 1|
6 5 4|3 2 1|9 8 7|
3 2 1|9 8 7|6 5 4|

8 7 6|5 4 3|2 1 9|
5 4 3|2 1 9|8 7 6|
2 1 9|8 7 6|5 4 3|

7 6 5|4 3 2|1 9 8|
4 3 2|1 9 8|7 6 5|
1 9 8|7 6 5|4 3 2|

array:[3, 7, 2, 5, 1, 4, 9, 6, 8]
8 6 9|4 1 5|2 7 3|
4 1 5|2 7 3|8 6 9|
2 7 3|8 6 9|4 1 5|

6 9 4|1 5 2|7 3 8|
1 5 2|7 3 8|6 9 4|
7 3 8|6 9 4|1 5 2|

9 4 1|5 2 7|3 8 6|
5 2 7|3 8 6|9 4 1|
3 8 6|9 4 1|5 2 7|
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 05-30-2006, 03:11 AM   #5 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
I imagine there's probably more than one valid template, or else people'd probably get bored much quicker.
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 05-30-2006, 03:27 AM   #6 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
Hmm wikipedia says there are 5,472,730,538 templates.
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 05-30-2006, 01:45 PM   #7 (permalink)
Manan
Registered User
 
Join Date: Jul 2005
Posts: 16
Manan is on a distinguished road
Thanks, teknomage.
As for your "pool of possibilites" idea, there could be a step to make it work. Couldn't it be possible to redo the entire row when a random number is generated. It may take longer, but this way, it will never reach an unassignable state, because it can just start that row over again.

I like the template idea, and thought I could add to that. It would be possible to randomly turn the board 90, 180, or 270 degrees to offer three new templates based off of just 1. I could also shift every row or column by 3 or 6 squares to offer even more possible templates based off of 1.
Manan is offline   Reply With Quote
Old 05-30-2006, 05:50 PM   #8 (permalink)
Manan
Registered User
 
Join Date: Jul 2005
Posts: 16
Manan is on a distinguished road
Also, for the template thing, you won't always have the same puzzle even if you have the same template. After filling the board with the template, I can take out different numbers, and then it'll basically be a different challenge altogether.
Manan is offline   Reply With Quote
Old 05-30-2006, 11:34 PM   #9 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
That's true, and even with a single template you still have 9! (362880) possibilities just from doing the relabelling. And each extra template you add yeilds another 9! solutions.
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 06-01-2006, 02:58 PM   #10 (permalink)
Manan
Registered User
 
Join Date: Jul 2005
Posts: 16
Manan is on a distinguished road
Matrix as reference parameters

Well, I've got the template system to work properly and generate a correctly filled-in grid. Now, I'm going to remove one number at a time, and check to see if it is solvable after each number is removed. If it isn't solvable, go back and put the number back in.

I'm constantly getting an error when I try to pass a matrix as a reference parameter. Here is my code:
Code:
void FillPossibilities(int &Buffer[9][9])
When I do this I get the following error:
error: declaration of 'Buffer' as array of references

Why can't I pass the matrix as a reference parameter? Is there something wrong with my syntax? Or, is it possible to return a matrix from a function? Any help is greatly appreciated.
Manan is offline   Reply With Quote
Old 06-01-2006, 03:10 PM   #11 (permalink)
kyoryu
Registered User
 
Join Date: Apr 2003
Posts: 34
kyoryu is on a distinguished road
Arrays are passed as pointers anyway, so there's no need to pass it in as a reference.
kyoryu is offline   Reply With Quote
Old 06-01-2006, 03:47 PM   #12 (permalink)
Manan
Registered User
 
Join Date: Jul 2005
Posts: 16
Manan is on a distinguished road
Oh. I haven't learned pointers yet in my c++ class. I'll check it out in the book and see what I can do. If I can't figure it out, I'll just come here for help.
Manan is offline   Reply With Quote
Old 06-13-2006, 06:55 PM   #13 (permalink)
Manan
Registered User
 
Join Date: Jul 2005
Posts: 16
Manan is on a distinguished road
I've decided to use a template, because I have way too little time to actually do a totally random board generator. But I'm having another problem declaring 2d arrays.
Code:
if(randTemplate == 1)
	{ //If template 2 is chosen
		int buffer[9][9] = {

             {n[6],n[7],n[8], n[1],n[0],n[4], n[2],n[5],n[3] },
             {n[1],n[4],n[5], n[2],n[8],n[3], n[6],n[0],n[7] },
             {n[2],n[0],n[3], n[5],n[7],n[6], n[4],n[1],n[8] },

             {n[8],n[2],n[1], n[7],n[6],n[0], n[5],n[3],n[4] },
             {n[5],n[3],n[0], n[4],n[2],n[8], n[1],n[7],n[6] },
             {n[7],n[6],n[4], n[3],n[1],n[5], n[8],n[2],n[0] },

             {n[0],n[5],n[7], n[8],n[4],n[2], n[3],n[6],n[1] },
             {n[4],n[1],n[2], n[6],n[3],n[7], n[0],n[8],n[5] },
             {n[3],n[8],n[6], n[0],n[5],n[1], n[7],n[4],n[2] }
          };
}
The above segment of code works perfectly. However, I want to declare int buffer[][] outside the if statement. This is because, it is currently a local variable and I want to use it outside the if statement. Here is what I'm trying to do:
Code:
int buffer[9][9];
if(randTemplate == 1)
	{ //If template 2 is chosen
		buffer[][] = {

             {n[6],n[7],n[8], n[1],n[0],n[4], n[2],n[5],n[3] },
             {n[1],n[4],n[5], n[2],n[8],n[3], n[6],n[0],n[7] },
             {n[2],n[0],n[3], n[5],n[7],n[6], n[4],n[1],n[8] },

             {n[8],n[2],n[1], n[7],n[6],n[0], n[5],n[3],n[4] },
             {n[5],n[3],n[0], n[4],n[2],n[8], n[1],n[7],n[6] },
             {n[7],n[6],n[4], n[3],n[1],n[5], n[8],n[2],n[0] },

             {n[0],n[5],n[7], n[8],n[4],n[2], n[3],n[6],n[1] },
             {n[4],n[1],n[2], n[6],n[3],n[7], n[0],n[8],n[5] },
             {n[3],n[8],n[6], n[0],n[5],n[1], n[7],n[4],n[2] }
          };
}
I get about 50-60 errors when I do this. I've even tried getting rid of the [][], and I also tried making it [9][9], but it won't work. Help is greatly appreciated
Manan is offline   Reply With Quote
Old 06-30-2006, 06:33 PM   #14 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
Sorry, I missed your array question earlier. I think you just need to maybe initialize your buffer when you declare it, then assign to it via buffer = {...},

Also Peter Norvig (important AI coder at Google amongst other things), has posted an excellent sudoku article here: http://norvig.com/sudoku.html
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 07-01-2006, 07:36 PM   #15 (permalink)
Manan
Registered User
 
Join Date: Jul 2005
Posts: 16
Manan is on a distinguished road
Its ok. I figured it out, thanks to help from my teacher. I can only use ({..}, {...}) that technique when initializing the matrices, and not for already initialized matrices. Therefore, I used the memcpy command. So basically:
Code:
int buffer[9][9];
if(randTemplate == 1)
	{ //If template 2 is chosen
	     int buffer2[9][9] = {

             {n[6],n[7],n[8], n[1],n[0],n[4], n[2],n[5],n[3] },
             {n[1],n[4],n[5], n[2],n[8],n[3], n[6],n[0],n[7] },
             {n[2],n[0],n[3], n[5],n[7],n[6], n[4],n[1],n[8] },

             {n[8],n[2],n[1], n[7],n[6],n[0], n[5],n[3],n[4] },
             {n[5],n[3],n[0], n[4],n[2],n[8], n[1],n[7],n[6] },
             {n[7],n[6],n[4], n[3],n[1],n[5], n[8],n[2],n[0] },

             {n[0],n[5],n[7], n[8],n[4],n[2], n[3],n[6],n[1] },
             {n[4],n[1],n[2], n[6],n[3],n[7], n[0],n[8],n[5] },
             {n[3],n[8],n[6], n[0],n[5],n[1], n[7],n[4],n[2] }
             };
             memcpy (buffer, buffer2, sizeof buffer);
      }
Manan is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ Sudoku Algorithm priley86 Standard C, C++ 0 05-21-2006 07:52 AM
Weigh Board Salchester MS Technologies ( ASP, VB, C#, .NET ) 3 11-14-2005 09:51 AM
Help with Fractal Terrain Generation Algorithm brad_galloway Standard C, C++ 5 04-17-2005 07:48 PM
Munske's Algorithm brad_galloway Standard C, C++ 5 03-18-2005 10:40 PM
Discussion board of your dreams - Simple Machnies Forums Phoenix PHP 0 08-10-2003 02:59 PM


All times are GMT -8. The time now is 08:57 AM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8





Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting