Don't have an account? Register now to chat, post, use our tools, and much more.
» Goto page 1, 2  Next
I was incredibly bored after school today (I only had science to study for!), i decided to make a sudoku program.

Here it is
NOTE: This is not finished, i still have to finish the int main() {
section of the code, i am working on that now

Code:
```// This is my test program for Sudoku made in c++ // I suck at c++ and did pretty much all of it from memory // (the debugger also helped...) #include <iostream> #include <stdlib.h> #include <time.h> using namespace std; int r,c,t,g,a; bool i; int grid; int rand(int); int check(void); void disp(void); int main() {     srand(time(NULL));     cout << "\n\n\n\n\n\n\n\n\n\nGenerating puzzle...";     r = 0;     while (r <= 8) {           g = 0;           c = 0;     while (c <= 8) {           disp(); return 0; }                                                             int rand(void) {     return rand() % 9; } void disp(void) {      int n,m;      for (n=0; n<=8; n++){          cout << "\n";          for (m=0; m<=8; m++) {              cout << grid[n][m] << " ";              }              }              return 0              } int check(void) {      int n,m,p,z;      i = 0;      //Horizontal check      n = r;      for (m=0; m<=8; m++) {          if (grid[n][m] == t)          i = 1;          }          if (i)          return 0;                //Vertical check      m = c;      for (n=0; n<=8; n++) {          if (grid[n][m] == t)          i = 1;          }          if (i)          return 0;      // Square check      if (r <= 2)      n = 0;      if (r >= 3 and r <= 5)      n = 3;      if (r >= 6)      n = 6;      if (c <= 2)      m = 0;      if (c >= 3 and c <= 5)      m = 3;      if (c >= 6)      m = 6;      p = m + 3;            for (z = 0; z <= 8; z++) {          if (grid[n][m]== t)          i = 1;          m++;          if (m == p) {                m = m-3;                n++;                }                }                return 0                } ```

OK i finished the code and for some reason, it doesn't run the disp() function at the end (display the 2d array that contains the puzzle)

OH WEL... I will finish and rewrite it after schhol is out, meanwhile i was REALLY bored so i made a program that basically does this (looks cool at the very beginning) Code:
```#include <iostream> using namespace std; int a,b; int main() {     cout << "\n\n\n\n\n\n\n\n\n\nEnter a number to count up to:";     cin >> a;     for (b = 0; b <= a; b++) {         cout << b << " ";         }         }         ```

Now you can tell that i was REALLY bored this looks cool, can't wait to see it done
rivereye wrote:
this looks cool, can't wait to see it done

I need to totally recode it though... I realized right after i posted it that i had left out the return 0's in about 2 of the functions I think i will try to finish it after Friday though!

even after my edits I discovered that the function:
void disp(void) {
works, but is not being called correctly by the program... I am really wondering what the problem is with all of the code...

Tested it even more (after more changes) and i don't think anything is working! it sucks... Like i said though, i think i will rewrite the entire thing Friday.
You said you are in 7th grade, right Harq? I'm very impressed that you know C++ and are able to make a sudoku game. You da man Lol... I am in seventh grade, but i still did not code it correctly... The thing is, i am not sure how c++ responds to changing a for loop variable.. That was kind of the center of it, but i do not know wheather it stores a separate copy to use as a counter... I did a quick rewrite changing them to while loops because i wasn't sure of that, but i also think my functions were just a bit messed up... (oh and also, i pretty much got all the info i needed from reading the first 12 or so chapters of a c++ book, i still do not get the pointer and file stream bit...)

Also, i bet that Kllrnohj could do that better since he seems to have a very good grasp on the language.
egad, formatting dude...jeez... Get yourself a good IDE with auto-indenting. Use the actual tab character (as in hit the tab key and set the IDE to use the \t character for tabs rather than spaces), and set the tab width to 8. Each loop, function, if-else, etc... statement gets indented one level deeper than the previous

Ok, couple things. Try to avoid global variables like the plague - its not good coding practice, and makes it extremely difficult to follow. For example, rather than

Code:
```int b; [....] for (b = 0; b <= a; b++) {```

do

Code:
`for (int b = 0; b <= a, b++) {`

not only is it shorter, but whoever is reading it can see what b is, and why it is being used. It also makes it local to the For loop, reducing RAM usage, as b doesn't exist until it is needed, and deleted when the For loop is done

Please post up your finished code and I'll go through it then, but I see some problems...

Code:
```int rand(void) {     return rand() % 9; }```

That function will recurse until infinity (it will never end), and will overflow the stack (this is bad)

Another pitfal I am seeing is horrid variable naming. Just using letters (like n, m, etc..) doesn't cut it in a computer program. In disp, change n and m to something more descriptive, like row and column, x and y, etc....

Just post up that finished code!

Oh, and why do you start off every program with "\n\n\n\n\n\n\n\n\n\n\n"?
Kllrnohj wrote:
egad, formatting dude...jeez... Get yourself a good IDE with auto-indenting. Use the actual tab character (as in hit the tab key and set the IDE to use the \t character for tabs rather than spaces), and set the tab width to 8. Each loop, function, if-else, etc... statement gets indented one level deeper than the previous

Ok, couple things. Try to avoid global variables like the plague - its not good coding practice, and makes it extremely difficult to follow. For example, rather than

Code:
```int b; [....] for (b = 0; b <= a; b++) {```

do

Code:
`for (int b = 0; b <= a, b++) {`

not only is it shorter, but whoever is reading it can see what b is, and why it is being used. It also makes it local to the For loop, reducing RAM usage, as b doesn't exist until it is needed, and deleted when the For loop is done

Please post up your finished code and I'll go through it then, but I see some problems...

Code:
```int rand(void) {     return rand() % 9; }```

That function will recurse until infinity (it will never end), and will overflow the stack (this is bad)

Another pitfal I am seeing is horrid variable naming. Just using letters (like n, m, etc..) doesn't cut it in a computer program. In disp, change n and m to something more descriptive, like row and column, x and y, etc....

Just post up that finished code!

Oh, and why do you start off every program with "\n\n\n\n\n\n\n\n\n\n\n"?

OK now... I use the dev bloodshed studio (pretty good, a bit touchy but still...) It seems like when i go back and change code it doesn't redo the }'s

And also, the \n\n\n\n\n\n\n continues to the next line, i prefer that to cout << endl (also if you didn't know \ indicates that the next character is a special command when in quotes, use \\ to actually print a \)

And on the last bit, yes, i do suck at variable naming... I should starting making a sheet with the name and function of every variable i use on it (maybe just put it in as a large comment /*)

I now set it to use the tab character and size 8, thanks (do you think i should use crimson editor instead?)

I might start doing my editing in Crimson editor and only compiling it in dev, except that dev has a syntax check function... Helps a lot... Anyways, I have got to finish studying for my math and social studies exam ok, let me rephrase that, why do you have 8 or so newlines at the beggining of your programs? (I know what \n means, I know what escapte characters are, just answer my question in the context it was asked - what is the PURPOSE of all those \n or newlines?)

You can safely assume your program will always start off on a newline, so you never need to output any newlines first, however, you should always END your program on a newline

And incase you don't know, endl = \n, NOT endl = \n\n\n\n\n\n\n\n (although technically, endl = \r\n on windows platforms, and endl = \n on POSIX platforms, but I think that is a bit over your head right now )
OK basically i like to get it off from the text a bit, but i think i got carried away, lol
OK here is a rewritten version, it does actually display everything and starts making a puzzle, but i don't think my technique works...

Code:
``` /* OK, this is my rewrite of my earlier Sudoku program. I am not sure the technique works, but we shall see... ################################################################# If you do not know C++ and you are reading this code, just know that arrays start with 0 (measures distant from start really), not 1 */ #include <iostream> #include <time.h> #include <stdlib.h> #include <math.h> using namespace std; int row,column,num,counter,repeat; int grid; void disp(void); int sudrand(void); int check(int n); int main() {           srand(time(NULL)); //Sets rand seed                      cout << "\n   Generating puzzle...";                      for(row = 0; row <= 8; row++) {  // Y loop           disp();              repeat = 0;              for (column = 0; column <= 8; column++) { // X llop                 num = sudrand(); //Calls sudrand and gets a random number                 counter = check(num); //counter = the return value of check(num)                           //0 if move is legal, 1 if illegal                 if (counter) {                    repeat++;                    counter = 0;                    column = column - 2;                 }                  if (counter == 0)                 grid[row][column] = num;                 if (repeat >= 25 and row > 1) {  //if illegal move was made 25 or more times, restart last row                    repeat = 0;                    column = 8;                    row = row - 2;                 }                 }              }              disp();  //displays the resulting puzzle              cout << endl;              cin >> counter;           }                             void disp() {  //displays puzzle    int t;    cout << endl;    for (int r = 0; r <= 8 ; r++) {       cout << endl;       for (int c = 0; c <= 8; c++) {          cout << grid[r][c] << " ";       }    }    return; } int sudrand() {  //generates a random number, 1 - 9    return rand() % 9; } int check(int n) {    int r,c,max;    //Horizontal check    r = row;    for (c = 0; c <= 8; c++) {       if (grid[r][c] == n)       return 1;    }        //Vertical check    c = column;    for (r = 0; r <= 8; r++) {       if (grid[r][c] == n)       return 1;    }        //square check        if (row <= 3)    r = 1;    if (row >= 4 and row <= 6)    r = 4;    if (row >= 7)    r = 7;              if (column <= 3)    c = 1;    if (column >= 4 and column <= 6)    c = 4;    if (column >= 7)    c = 7;        max = c+3;           for (int d = 0;d <= 8; d++) {       if (c == max) {          c = c-3;          r = r+1;       }       if (grid[r][c] == n)       return 1;       c++;    } } ```

Atleast i added comments and it is more organized this time! P.S. It never seems to get by the 3rd row, 8th column...

I think with the way i implemented it, it just keeps looping back the second it finishes the 3rd line, the only way to actually see what it is doing is to use print screen (i should create a conditional statement so it won't speed by...)

EVery move isn't even legal! (or maybe it jsut displayed like that because it doesn't write over the lines... OK i think i have an idea, but its almost 9 here, so i gtg!)
IT ACTUALLY WORKS!!!!!!

and i am an idiot... THe problem was that in the area of the code that checks to see if there is the same number in the square, I forgot that the arrays in c++ start with 0, not 1, but i FIXED IT!!!!!!!!!!!!

Here is the code (a full puzzle was generated in about 2-3 seconds, and EVERYTHING was accurate, i even implemented a check when it is done to make sure everything is correct

Thank god for the debugger tools in dev c++, i put one breakpoint and just kept going through, and then i saw the error This works roughly 9/10 times that you run it, for some reason it sometimes stops after the first 2 or so lines...

And does anyone have an idea why this program generates a file called gmon.out whenever i run it?

Here is the code:

(this is the updated version, includes saving the puzzles into files)

Code:
``` /* OK, this is my rewrite of my earlier Sudoku program. I am not sure the technique works, but we shall see... ########################################################################################### If you do not know C++ and you are reading this code, just know that arrays start with 0  (measures distant from start really), not 1. ############################################################################################  IT WORKS!!! */ #include <iostream> #include <time.h> #include <stdlib.h> #include <math.h> #include <fstream> using namespace std; int row,column,num,counter,repeat; int grid; void disp(void); void overwrite(void); int sudrand(void); int check(int n); char filename; int main() {    char pause;           srand(time(NULL)); //Sets rand seed                      cout << "\n   Generating puzzle...";                      for(row = 0; row <= 8; row++) {  // Y loop           disp();                 repeat = 0;              for (column = 0; column <= 8; column++) { // X loop                 num = sudrand(); //Calls sudrand and gets a random number                 counter = 0;                 counter = check(num); //counter = the return value of check(num)                           //0 if move is legal, 1 if illegal                 if (counter == 1) {                    repeat++;                    column--;                 }                  if (counter == 0) {                 grid[row][column] = num;                 repeat = 0;             }                 if (repeat >= 80 and row > 1 and counter == 1) {  //if illegal move was made 25 or more times, restart last row                    row = row - 2;                    overwrite();                    column = 8;                    }                }             }              disp();  //displays the resulting puzzle              cout << "\n\n";              cout << "Enter filename to write the puzzle too, nothing to exit:";              cin.getline(filename,79);                if (strlen(filename) == 0)              return 0;              ofstream file_out(filename);              if (! file_out) {                 cout << "\n\n" << filename << " could not be opened!";                 cin.getline(pause,1);                 return -1;              }              if (file_out) {                  cout << "\n\nCopying puzzle to " << filename << " ...";                  for (int r = 0; r <= 8; r++) {                     file_out << endl;                     for (int c = 0; c <= 8; c++) {                        file_out << grid[r][c] << " ";                     }                  }               }               cout << "\nEnter to exit";              cin.getline(pause,1);              return 0;           }                             void disp() {  //displays puzzle    int t;    cout << endl;    for (int r = 0; r <= 8 ; r++) {       cout << endl;       for (int c = 0; c <= 8; c++) {          cout << grid[r][c] << " ";       }    }    return; } int sudrand() {  //generates a random number, 1 - 9    return (rand() % 9)+1; } int check(int n) {    int r,c,max;    //Horizontal check    r = row;    for (c = 0; c <= 8; c++) {       if (grid[r][c] == n)       return 1;    }        //Vertical check    c = column;    for (r = 0; r <= 8; r++) {       if (grid[r][c] == n)       return 1;    }        //square check        if (row <= 2)    r = 0;    if (row >= 3 and row <= 5)    r = 3;    if (row >= 6)    r = 6;              if (column <= 2)    c = 0;    if (column >= 3 and column <= 5)    c = 3;    if (column >= 6)    c = 6;        max = c+3;           for (int d = 0;d <= 8; d++) {       if (c == max) {          c = c-3;          r++;       }       if (grid[r][c] == n)       return 1;       c++;    }    return 0; } void overwrite() {    for (int r = row+1; r <= row+2; r++) {       for (int c = 0; c <=8; c++) {          grid[r][c] = 0;       }    }    return; } ```

I do have an optomized version, but leave it like this for now
does it check to make sure the puzzle is actually solveable? Cause it doesn't look like it does, so someone could waste a whole bunch of time on an unsolveable puzzle Kllrnohj wrote:
does it check to make sure the puzzle is actually solveable? Cause it doesn't look like it does, so someone could waste a whole bunch of time on an unsolveable puzzle Yes, look at the end of main()

It runs a check on the entire puzzle (checkall or something like that), and if it is not valid then it redoes it, but it is always valid anyways!

I need to add a routine so that if it freezes (its actually about 1/2 the time, after running more tests) it will restart the puzzle (It doesn't really freeze, it just keeps going in a loop, not sure why though)

Could you answer my question on the gmon.out file? Why is it created when i run the program? (nevermind, i am 99%\$ sure it is the debugger output)

Oh and screw the 2-3 seconds, it is almost always 1 second (even with displaying the steps every row)

Today's job is finished, tommorrow i will add a routine to make sure it does not freeze up (god i h8 debugging ) Oh yeah, it just generates a full puzzle for now, i might add something to actually take out numbers later, but not now (i would probably use a separate routine as the main part of that to organize it a little)
Harq wrote:
Yes, look at the end of main()

It runs a check on the entire puzzle (checkall or something like that), and if it is not valid then it redoes it, but it is always valid anyways!

That just checks that the puzzle is valid, NOT that it is solveable. The only way to make sure it is solveable is to have the program auto-solve it. If it succeeds, then the puzzle is solveable, if it fails, the puzzle isn't solveable and it should then attempt to generate a new one.

Oh, and here is the vastly cleaned up code (clean in that it follows sane formatting - much, much more readable)

Code:
``` /* OK, this is my rewrite of my earlier Sudoku program. I am not sure the technique works, but we shall see... ################################################################# If you do not know C++ and you are reading this code, just know that arrays start with 0  (measures distant from start really), not 1. */ #include <iostream> #include <time.h> #include <stdlib.h> #include <math.h> using namespace std; int row,column,num,counter,repeat; int grid; void disp(void); void overwrite(void); int sudrand(void); int check(int n); int totalcheck(void); int main() {    srand(time(NULL)); //Sets rand seed    cout << "\n   Generating puzzle...";    counter = 1;    while (counter == 1) {       for(row = 0; row <= 8; row++) {  // Y loop          disp();          repeat = 0;          for (column = 0; column <= 8; column++) { // X loop             num = sudrand(); //Calls sudrand and gets a random number             counter = 0;             counter = check(num); //counter = the return value of check(num)                         //0 if move is legal, 1 if illegal             if (counter == 1) {                repeat++;                column--;             }             if (counter == 0) {                grid[row][column] = num;                repeat = 0;             }             if (repeat >= 80 and row > 1 and counter == 1) {                 //if illegal move was made 25 or more times, restart last row                row = row - 2;                overwrite();                column = 8;             }          }       }       counter = totalcheck();    }    disp();  //displays the resulting puzzle    cout << "\n\n";    if (counter == 0)       cout << "All numbers are legal";    cout << endl;    cin >> counter; } void disp() {  //displays puzzle    int t;    cout << endl;    for (int r = 0; r <= 8 ; r++) {       cout << endl;       for (int c = 0; c <= 8; c++) {          cout << grid[r][c] << " ";       }    }    return; } int sudrand() {  //generates a random number, 1 - 9    return (rand() % 9)+1; } int check(int n) {    int r,c,max;    //Horizontal check    r = row;    for (c = 0; c <= 8; c++) {       if (grid[r][c] == n)          return 1;    }    //Vertical check    c = column;    for (r = 0; r <= 8; r++) {       if (grid[r][c] == n)          return 1;    }    //square check    if (row <= 2)       r = 0;    if (row >= 3 and row <= 5)       r = 3;    if (row >= 6)       r = 6;    if (column <= 2)       c = 0;    if (column >= 3 and column <= 5)       c = 3;    if (column >= 6)       c = 6;    max = c+3;    for (int d = 0;d <= 8; d++) {       if (c == max) {          c = c-3;          r++;       }       if (grid[r][c] == n)          return 1;       c++;    }    return 0; } void overwrite() {    for (int r = row+1; r <= row+2; r++) {       for (int c = 0; c <=8; c++) {          grid[r][c] = 0;       }    } } int totalcheck() {    int checkc;    for (int r = 0; r <= 8; r++) {       for (int c = 0; c <= 8; c++) {          checkc = check(grid[r][c]);          if (checkc == 1)             return 1;       }    }    return 0; } ```

I will look over it/optimize it now

EDIT: Nevermind about the valid/solveable thing, I now notice that you aren't removing numbers to actually make the puzzle itself, just generating a matrix of numbers.

However, I have yet to have it actually WORK. It keeps going into an infinite loop....

Oh, and you shouldn't be displaying the puzzle until it has found a valid one. That way the user is spammed with invalid puzzles....
THIS ONLY CREATES A COMPLETE PUZZLE, IT DOES NOT TAKE OUT ANY NUMBERS RIGHT NOW!!!

Ok? I might add that later, but not yet, right now i am glad it makes a full and valid puzzle

Also, like i said, my project for tommorow is to get rid of the glitch where it freezes after the first line

OK run it about 3-4 times, like i said, my project for tommorow is to get rid of the loop!

Here is a pic of a puzzle that it generated: P.S. I also have a more optimized version, small optimizations, but they still help
Moved to Community News subforum. Looks like a good effort so far.
Harq wrote:
Also, like I said, my project for tommorow is to get rid of the glitch where it freezes after the first line

OK run it about 3-4 times, like I said, my project for tommorow is to get rid of the loop!

Yes, I'm not just talking about the freezing after the first line. I mean I have yet to have it finish executing as it should. After several dozen runs, it has yet to actually exit cleanly.

No offense, but your coding is horrible (this is to be expected for a new programmer). I am going to recode it (using the same rough algorithms) to show you how much better coding practices lead to much less debugging Look back at my last post, i just posted up the new code (I am not going to keep posting new versions with slight changes in a new post, waste of space).
Also, i added a picture. This version now asks for a file to save the puzzle to (whatever type you want, .txt or anything), so you can save the puzzle. I still have no idea why it sometimes freezes, do you have any idea (besides an infinite loop, i know thats the cause, but i am wonder why it is doing that) why it keeps freezing like that? (I already gave up on debugging it with the debugger, to get that to work correctly for such a subtle bug i had to put break points almost every line to actually have it report the variables...
You should really do a partial rewrite to get rid of ALL global variables.

The freezing is an infinite loop, obviously, and my only guess is that you are backing up 2 rows instead of 1

Quote:
if (repeat >= 80 and row > 1 and counter == 1) {
//if illegal move was made 25 or more times, restart last row
row = row - 2;
overwrite();
column = 8;

I'm having too much trouble following your code to know if this is the problem or not, so seriously dude, get rid of the dang global vars.

For example, here is a check() function that uses no global vars, and takes just 3 arguments. Also, something like check should return type bool, not int, as that is confusing, since anyone reading it is expecting check() to return some sort of a significant int, not just 1 or 0. Also note the heavy commenting - this makes it MUCH easier for others when you are asking for help, as they can then actually read what you were thinking. Do note, this function HAS been debugged, and I am 99% sure that is works as long as 0<=x<=8 and 0<=y<=8

Code:
```//x and y are the location of the number to check in grid bool check(int x, int y, int grid) {    int s_x, s_y;    //Horiz check    for (int i = 0; i < 9; i++) {       if ((grid[i][y] == grid[x][y]) and (i != x)) {          return false;       }    }    //Vert check    for (int i = 0; i < 9; i++) {       if ((grid[x][i] == grid[x][y]) and (i != y)) {          return false;       }    }    //Square check    //Set square X offset    if ((x >= 0) and (x < 3)) {       s_x = 0;    } else if ((x >= 3) and (x < 6)) {       s_x = 3;    } else {       s_x = 6;    }        //Set square Y offset    if ((y >= 0) and (y < 3)) {       s_y = 0;    } else if ((y >= 3) and (y < 6)) {       s_y = 3;    } else {       s_y = 6;    }        //Check the square    for (int i_x = 0; i_x < 3; i_x++) {       for (int i_y = 0; i_y < 3; i_y++) {          if ((grid[i_x + s_x][i_y + s_y] == grid[x][y]) and              (i_x + s_x != x) and (i_y + s_y != y)) {             return false;          }       }    }        return true; }```

There are other optimizations, like this:

Code:
```            if (counter == 1) {                repeat++;                column--;             }             if (counter == 0) {                grid[row][column] = num;                repeat = 0;             } ```

should be

Code:
```            if (counter) {                repeat++;                column--;             } else {                grid[row][column] = num;                repeat = 0;             } ```

As counter can never be anything besides 1 or 0, and it can't be both at the same time, so there is no reason to use two if statements instead of an if-else. And since counter never gets used aside from that, you could even just replace "if (counter)" with "if (check(num))", and not using the counter variable at all

Just as one last tip, it is much easier to debug each individual function in isolated programs, and then piece the program back together. Then you can be sure that the problem is in the main function, as all the sub functions have already been tested. Obviously, this requires that you don't use global vars, but you shouldn't be using them anyway. Every function should be an isolated section of code that requires nothing external aside from its arguments
It goes back 2 rows because when the loop ends, it will go ahead another row, so it ends up being 1 row back. I suck at writing optomized code, but hey, I just started learning c++ recently and i am just now starting the actual OOP area of the language.

couldn't this:

Quote:

Code:
```  //Square check    //Set square X offset    if ((x >= 0) and (x < 3)) {       s_x = 0;    } else if ((x >= 3) and (x < 6)) {       s_x = 3;    } else {       s_x = 6;    }        //Set square Y offset    if ((y >= 0) and (y < 3)) {       s_y = 0;    } else if ((y >= 3) and (y < 6)) {       s_y = 3;    } else {       s_y = 6;    } ```

Be replaced by 2 switch - case statement (or can you not do multiple conditions/checks other than ==?) ?

I have gone through and taken out all global variables.

Oh yeah, do you mean 4 arguments? because you need the random number too

Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

»
» Goto page 1, 2  Next
» All times are GMT - 5 Hours

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum