Thread: newbe needs some help

  1. #1
    Registered User
    Join Date
    Nov 2005
    Location
    Alpine, TX
    Posts
    31

    newbe needs some help sodoku puzzle

    Hello all. I am taking my first class in C and have a professor thats all about having you learn on your own. Anyway Im trying to write a solution to the Sodoku puzzle. What I dont know is how to scan a row for a number that I am trying to enter. professor says I should use an index. I have no clue how to set that up. Here is the part that Where I set up the initial puzzle

    Code:
    void getGivens(struct sudoCell grid[9][9]) /* User enters starting pattern */
    {
         int row, col, digit;
         char instring[50];
         printf("Enter Sudoku pattern line by line.\n");
         printf("Enter \'0\' for each undetermined cell\n");
         printf("Enter a digit 1..9 followed by a space for each starting cell\n");
         for (row=0; row<9; ++row)
         {
             /* Users dont understand rows numbered 0 */
             printf("Enter row %d: ", row+1);
             fgets(instring, sizeof(instring), stdin);
             sscanf(instring, "%d %d %d %d %d %d %d %d %d",
                  &grid[row][0].digit, &grid[row][1].digit,
                  &grid[row][2].digit, &grid[row][3].digit,
                  &grid[row][4].digit, &grid[row][5].digit,
                  &grid[row][6].digit, &grid[row][7].digit,
                  &grid[row][8].digit);
             for (col=0; col<9; ++col) 
                  grid[row][col].given = grid[row][col].digit>0;
         }
         return;
    }
    Last edited by Dr Spud; 11-23-2005 at 08:45 PM.

  2. #2
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    There is a few ways you could do this with arrays. You could try a 9 x 9 2 Dimensional array or if you're up for it, you could probably make it more efficient with a 3 Dimensional of 3 x 3 x 9. Visually you're options would look something like this:

    Code:
             2D  Array          
    [ ][ ][ ][ ][ ][ ][ ][ ][ ]
    [ ][ ][ ][ ][ ][ ][ ][ ][ ]
    [ ][ ][ ][ ][ ][ ][ ][ ][ ]
    [ ][ ][ ][ ][ ][ ][ ][ ][ ]
    [ ][ ][ ][ ][ ][ ][ ][ ][ ]
    [ ][ ][ ][ ][ ][ ][ ][ ][ ]
    [ ][ ][ ][ ][ ][ ][ ][ ][ ]
    [ ][ ][ ][ ][ ][ ][ ][ ][ ]
    [ ][ ][ ][ ][ ][ ][ ][ ][ ]
    
              3D  Array
    [ ][ ][ ]|[ ][ ][ ]|[ ][ ][ ]
    [ ][ ][ ]|[ ][ ][ ]|[ ][ ][ ]
    [ ][ ][ ]|[ ][ ][ ]|[ ][ ][ ]
    --------- --------- --------- 
    [ ][ ][ ]|[ ][ ][ ]|[ ][ ][ ]    0 1 2
    [ ][ ][ ]|[ ][ ][ ]|[ ][ ][ ]    3 4 5
    [ ][ ][ ]|[ ][ ][ ]|[ ][ ][ ]    6 7 8
    --------- --------- --------- 
    [ ][ ][ ]|[ ][ ][ ]|[ ][ ][ ]
    [ ][ ][ ]|[ ][ ][ ]|[ ][ ][ ]
    [ ][ ][ ]|[ ][ ][ ]|[ ][ ][ ]
    Essentially, the 3D array will break your array down into the managable 3 x 3 boxes. You just have to make sure you have each of these placed correctly. Something like how I have displayed to the right. This way you can do your checks based on the third index (each three by three box) and the same values of the first, for each 3 set of indexes ( array[0][0][0], array[0][0][1], array[0][0][2] ).

    Which of these two you choose is up to you, but personally, I think the latter would make the 3 x 3 box more visually appealing. Now how you display this on the screen could be tougher. Your best bet would be to output the array right at the beginning, then prompt a user for a move. Whenever a move is made, place it into the cooresponding array spot, clear the screen and output the array again. Do this until the puzzle is finished.
    Sent from my iPadŽ

  3. #3
    Registered User
    Join Date
    Nov 2005
    Location
    Alpine, TX
    Posts
    31
    thanks for the reply. to display the board I used the CP437 from wikipedia works great
    Code:
    ╔═══╤═══╤═══╦═══╤═══╤═══╦═══╤═══╤═══╗
    ║ 1 │ 2 │ 3 ║ 4 │ 5 │ 6 ║ 7 │ 8 │ 9 ║
    ╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
    ║ 1 │ 2 │ 3 ║ 4 │ 5 │ 6 ║ 7 │ 8 │ 9 ║
    ╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
    ║ 1 │ 2 │ 3 ║ 4 │ 5 │ 6 ║ 7 │ 8 │ 9 ║
    ╠═══╪═══╪═══╢═══╪═══╪═══╢═══╪═══╪═══╣
    ║ 1 │ 2 │ 3 ║ 4 │ 5 │ 6 ║ 7 │ 8 │ 9 ║
    ╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
    ║ 1 │ 2 │ 3 ║ 4 │ 5 │ 6 ║ 7 │ 8 │ 9 ║
    ╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
    ║ 1 │ 2 │ 3 ║ 4 │ 5 │ 6 ║ 7 │ 8 │ 9 ║
    ╠═══╪═══╪═══╢═══╪═══╪═══╢═══╪═══╪═══╣
    ║ 1 │ 2 │ 3 ║ 4 │ 5 │ 6 ║ 7 │ 8 │ 9 ║
    ╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
    ║ 1 │ 2 │ 3 ║ 4 │ 5 │ 6 ║ 7 │ 8 │ 9 ║
    ╟───┼───┼───╫───┼───┼───╫───┼───┼───╢
    ║ 1 │ 2 │ 3 ║ 4 │ 5 │ 6 ║ 7 │ 8 │ 9 ║
    ╚═══╧═══╧═══╩═══╧═══╧═══╩═══╧═══╧═══╝
    so if I convert it to a 3 dimensional array and start with the first cell.
    I want to put a 1 in it but have to make sure that row 1 and col 1 do not already contain a 1 I would use an if statement with an equivalent test (== "1") right?

  4. #4
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Your user would input something similar to this:

    Code:
    Input the following ( Row, Column, Value ): 5 7 8
    With that user input, create your algorithm to convert this to your array index, which would be array[0][1][5] (if you use the 3D array), after that you check to see if that has ANY value in it that isn't zero. If it's already filled, you could either produce an error message or you could prompt the user if they wish to replace the box, it's up to use. If it doesn't have anything in it, you fill it with the value. Then you move onto the part of the code that checks to see if the puzzle is complete.

    Nice grid by the way, were you able to output those non-standard characters in your program?
    Last edited by SlyMaelstrom; 11-23-2005 at 09:09 PM.
    Sent from my iPadŽ

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I wouldn't use a 3D array. It's way too complicated checking rows and columns that way. Much easier to use simple math on the row and column to check the 3x3 grid the entered coordinate falls in.


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Nov 2005
    Location
    Alpine, TX
    Posts
    31
    I have a function to have the user enter input. not sure if it is any good.
    Im a little sketchy about 3d arrays like I said Im very new to this perhaps if I post everything that I have you can help me work with what I have I dont want to get too far out of my means Im like a third grader when it comes to programming.
    Code:
    #include <stdio.h>
    
    /* Data declarations */
    struct sudoCell
    {
         int digit;
         int given;
    };
    
    /* Function declarations */
    void getGivens(struct sudoCell[9][9]); /* User enters starting grid */
    void sudoPrint(struct sudoCell[9][9]); /* Print current state */
    int sudoSolver(struct sudoCell[9][9]); /* Sudoku solver */
    
    int main()
    {
         int row, col, digit;
         struct sudoCell grid[9][9]; /* Sudoku grid */
         
         /* Get starting grid pattern fom user */
         getGivens(grid); /* Get starting pattern */
         sudoPrint(grid); /*Print starting pattern */
         
         /* Call solver for Sudoku pattern */
         while (sudoSolver(grid))
         {
              sudoPrint(grid);
              getchar();
         }
         
         printf("That's all folks\n");
         getchar();
         return 0;
    }
    
    void getGivens(struct sudoCell grid[9][9]) /* User enters starting pattern */
    {
         int row, col, digit;
         char instring[50];
         printf("Enter Sudoku pattern line by line.\n");
         printf("Enter \'0\' for each undetermined cell\n");
         printf("Enter a digit 1..9 followed by a space for each starting cell\n");
         for (row=0; row<9; ++row)
         {
             /* Users dont understand rows numbered 0 */
             printf("Enter row %d: ", row+1);
             fgets(instring, sizeof(instring), stdin);
             sscanf(instring, "%d %d %d %d %d %d %d %d %d",
                  &grid[row][0].digit, &grid[row][1].digit,
                  &grid[row][2].digit, &grid[row][3].digit,
                  &grid[row][4].digit, &grid[row][5].digit,
                  &grid[row][6].digit, &grid[row][7].digit,
                  &grid[row][8].digit);
             for (col=0; col<9; ++col) 
                  grid[row][col].given = grid[row][col].digit>0;
         }
         return;
    }
    
    void sudoPrint(struct sudoCell grid[9][9]) /* Print grid */
    {
         /* Line drawing characters from code page 437 */
         const char SP  = ' ';            const char HB  = 0xC4;
         const char VB  = 0xB3;           const char CRS = 0xC5;
         const char DVB = 0xBA;           const char DHB = 0xCD;
         const char DLL = 0xC8;           const char DLR = 0xBC;
         const char DUL = 0xC9;           const char DUR = 0xBB;
         const char DLT = 0xCC;           const char DRT = 0xB9;
         const char DTT = 0xCB;           const char DBT = 0xCA;
         const char DCR = 0xB6;           const char DLST = 0xC7;
         const char DRST = 0xB6;          const char DTST = 0xD1;
         const char DBST = 0xCF;          const char DVSB = 0xD7;
         const char DHSB = 0xD8;
         
         int row, col;
         char ch;
         
         /* Top Border */
         printf("%c", DUL);
         for (col=0;col<8; ++col)
              if (col%3 !=2)
                   printf("%c%c%c%c", DHB, DHB, DHB, DTST);
              else
                   printf("%c%c%c%c", DHB, DHB, DHB, DTT);
         printf("%c%c%c%c\n", DHB, DHB, DHB, DUR);
         
         /* Rows */
         for (row=0; row<9; ++row)
         {
              /* Data Row */
              printf("%c", DVB);
              for (col=0; col<9; ++col)
              {
                   if (grid[row][col].digit == 0) ch = SP;
                   else ch = grid[row][col].digit+'0';
                   
                   if (col%3 !=2) printf("%c%c%c%c", SP, ch, SP, VB);
                   else printf("%c%c%c%c", SP, ch, SP, DVB);
              }
              printf("\n");
              
              /* Border below data row */
              if (row<8)
              {
                   if (row%3 !=2)
                        printf("%c", DLST);
                   else
                        printf("%c", DLT);
                   for (col=0; col<8; ++col)
                   {
                        if (row%3 != 2)
                             printf("%c%c%c", HB, HB, HB);
                        else 
                             printf("%c%c%c", DHB, DHB, DHB);
                        if (col%3 != 2)
                             if (row%3 != 2)
                                  printf("%c", CRS);
                             else 
                                  printf("%c", DHSB);
                        else
                             if (row%3 != 2)
                                  printf("%c", DVSB);
                             else 
                                  printf("%c", DCR);
                   }
                   if (row%3 != 2)
                        printf("%c%c%c%c\n", HB, HB, HB, DRST);
                   else 
                        printf("%c%c%c%c\n", DHB, DHB, DHB, DRT);
              }
         }
         
         /* Bottom border */
         printf("%c", DLL);
         for (col=0; col<8; ++col)
              if (col%3 != 2)
                   printf("%c%c%c%c", DHB, DHB, DHB, DBST);
              else
                   printf("%c%c%c%c", DHB, DHB, DHB, DBT);
         printf("%c%c%c%c\n", DHB, DHB, DHB, DLR);
         
         return;
    }
    
    /* Solver for Sudoku grid */
    int sudoSolver(struct sudoCell grid[9][9])
    {
         return 0; /* for the time being until I figure you out */
    }
    now I have to test the first cell for anything in it I imagine with a if statement maybe if(grid[0][0].digit == '\0')
    then test for a 1 existing in the row I thought
    if(grid[row][0] == "1")
    but these dont work what am I doing wrong
    Last edited by Dr Spud; 11-23-2005 at 09:25 PM.

  7. #7
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    It's really your preference with the 2D array or 3D array. Either way you choose, one thing is gonna be nice and easy to check and the other will require some math. For me, I can visualize it better with a 3D array, but Quzah likes 2D. You seemed to have already implemented a 2D array, so I would just go with that, there is no point in changing it now.

    As of the way your program looks now, it's a real nice program that could output a pretty nice looking completed soduku puzzle.

    One thing I noticed is that you didn't intialize your array values which gives you some pretty funky looking results if you don't complete the input (Try one number for each row). Other than that, you look like you're in pretty good shape to start implementing the game part. There's plenty of ways to do it, so give it an attempt, and if you're having trouble, just post your attempt.
    Sent from my iPadŽ

  8. #8
    Registered User
    Join Date
    Nov 2005
    Location
    Alpine, TX
    Posts
    31
    now I have to test the first cell for anything in it I imagine with a if statement maybe if(grid[0][0].digit == '\0')
    then test for a 1 existing in the row I thought
    if(grid[row][0] == "1")
    but these dont even compile and every variation seems seems to be wrong but I cant think of anything else.

  9. #9
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    What are your errors? Most likely I'd expect a problem with this:

    if(grid[row][0] == "1")

    because there is a big difference between "1" and '1'.
    Sent from my iPadŽ

  10. #10
    Registered User
    Join Date
    Nov 2005
    Location
    Alpine, TX
    Posts
    31
    (grid[row][0] == "1")
    invalid operands to binary ==

    (grid[row][0] == '1')
    invalid operands to binary ==

    also Im writing this on Dev-C++ (also writes c programs)
    with their compiler
    not borlands compiler.

  11. #11
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Show me the code for that part.
    Sent from my iPadŽ

  12. #12
    Registered User
    Join Date
    Nov 2005
    Location
    Alpine, TX
    Posts
    31
    Code:
    /* Solver for Sudoku grid */
    int sudoSolver(struct sudoCell grid[9][9])
    {
         int row, col;
         if(grid[row][0] == "1")
         {
              if(grid[0][col] == "1")return 0;
              else printf("not working"); 
         }
         else printf("not working");
    }
    my plan was to start with this and input a 1 in the first cell and if everything runs without the message "not working" I could continue on but i keep getting the error
    "invalid operands to binary =="

  13. #13
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    That's because grid[][] is not a value, but grid[][].digit is. I also noticed that if your indexed value doesn't have it's expected "1", it gets trapped in the function forever.
    Last edited by SlyMaelstrom; 11-23-2005 at 10:05 PM.
    Sent from my iPadŽ

  14. #14
    Registered User
    Join Date
    Nov 2005
    Location
    Alpine, TX
    Posts
    31
    wow cant believe I missed that thx thats when you know you have been staring at the same piece of code for too long
    now by changing that I am attempting to compare an integer with a pointer and the compiler will give me a warning and the program will terminate without finishing. And thats the problem I had when I first came on the message board -- how can I change "1" to a pointer?

  15. #15
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Essentially, it is a pointer to a string literal that's placed into memory when the program is run. When it's compiled, it makes all those literals into constant strings to be put into memory and replaces them in the code with pointers to that memory. At least, I think that's what it does.

    In cases like this, you're supposed to convert the value to it's address, not the other way around.

    For me, I'm not getting that error. I'm also doing this on Dev-C++.

    Is your code like this?

    Code:
    int sudoSolver(struct sudoCell grid[9][9])
    {
         int row, col;
         if(grid[row][0].digit == "1")
         {
              if(grid[0][col].digit == "1") return 0;
              else printf("not working"); 
         }
         else printf("not working");
    }
    Last edited by SlyMaelstrom; 11-23-2005 at 10:27 PM.
    Sent from my iPadŽ

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbe question
    By RaisinToe in forum Game Programming
    Replies: 15
    Last Post: 01-28-2009, 06:01 PM
  2. Newbe request
    By Rokemet in forum C++ Programming
    Replies: 14
    Last Post: 09-20-2007, 11:41 PM
  3. Please help (newbe post)
    By Dmax in forum C++ Programming
    Replies: 4
    Last Post: 02-17-2005, 09:52 PM
  4. Newbe help
    By Kitu in forum C++ Programming
    Replies: 7
    Last Post: 08-01-2004, 03:49 AM
  5. WNDCLASSEX vs. WNDCLASS (Newbe) ???
    By niklaskr in forum Windows Programming
    Replies: 3
    Last Post: 06-19-2002, 09:44 AM