Sudoku solving algorithm C++ -


i'm trying make sudoku solving program couple of days i'm stuck methods. found algorithm here don't understand it:

  1. start @ first empty cell, , put 1 in it.
  2. check entire board, , see if there conflicts
  3. if there coflicts on board, increase number in current cell 1 (so change 1 2, 2 3, etc)
  4. if board clean move, start @ step 1 again.
  5. if 9 possible numbers on given cell cause conflict in board, set cell empty, go previous cell, , start again step 3 (this 'backtracking' comes in).

here code. think wrong help_solve(...) function. can me identify problem, please?

    #include <iostream> #include <iomanip> #include <time.h> #include <cstdlib> #include <windows.h> using namespace std;  class sudoku   {     private:     int board[9][9];     int change[9][9];     public:     sudoku();     void print_board();       void add_first_cord();       void solve();     void help_solve(int i, int j);     bool check_conflicts(int p, int i, int j);   };  sudoku game;    void setcolor(unsigned short color)                 //the function you'll use {                                                   //set colour     handle hcon = getstdhandle(std_output_handle);     setconsoletextattribute(hcon,color); }  sudoku::sudoku()   {     for(int = 1; <= 9; i++)       for(int j = 1; j <= 9; j++)         board[i][j] = 0;               }  void sudoku::print_board()   {     for(int = 1; <= 9; i++)       {         for(int j = 1; j <= 9; j++)           {             if(change[i][j] == 1)                {                 setcolor(12);                 cout << board[i][j] << " ";                 setcolor(7);                          }               else cout << board[i][j] << " ";                 if(j%3 == 0) cout << "| ";           }         cout << endl;         if(i%3 == 0) cout << "------+-------+---------" << endl;        }                       }  void sudoku::add_first_cord()   {     board[1][1] = 5; change[1][1] = 1;     board[1][2] = 3; change[1][2] = 1;          board[1][5] = 7; change[1][5] = 1;           board[2][1] = 6; change[2][1] = 1;       board[2][4] = 1; change[2][4] = 1;            board[2][5] = 9; change[2][5] = 1;       board[2][6] = 5; change[2][6] = 1;      board[3][2] = 9; change[3][2] = 1;           board[3][3] = 8; change[3][3] = 1;        board[3][8] = 6; change[3][8] = 1;          board[4][1] = 8; change[4][1] = 1;         board[4][5] = 6; change[4][5] = 1;         board[4][9] = 3; change[4][9] = 1;         board[5][1] = 4; change[5][1] = 1;      board[5][4] = 8; change[5][4] = 1;       board[5][6] = 3; change[5][6] = 1;       board[5][9] = 1; change[5][9] = 1;        board[6][1] = 7; change[6][1] = 1;      board[6][5] = 2; change[6][5] = 1;        board[6][9] = 6; change[6][9] = 1;       board[7][2] = 6; change[7][2] = 1;       board[7][7] = 2; change[7][7] = 1;       board[7][8] = 8; change[7][8] = 1;       board[8][4] = 4; change[8][4] = 1;      board[8][5] = 1; change[8][5] = 1;        board[8][6] = 9; change[8][6] = 1;      board[8][9] = 5; change[8][9] = 1;        board[9][5] = 8; change[9][5] = 1;       board[9][8] = 7; change[9][8] = 1;       board[9][9] = 9; change[9][9] = 1;     }  bool sudoku::check_conflicts(int p, int i, int j)   {     for(int k = 1; k <= 9; k++)       if(board[i][k] == p) return false;      for(int q = 1; q <= 9; q++)       if(board[q][j] == p) return false;      /*       *00       000       000     */     if((j == 1 || j == 4 || j == 7) && (i == 1 || == 4 || == 7))       {          if(board[i][j+1] == p || board[i][j+2] == p || board[i+1][j] == p ||               board[i+2][j] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||                   board[i+2][j+1] == p || board[i+2][j+2] == p)return false;            }        /*       000       000       *00     */       if((j == 1 || j == 4 || j == 7) && (i == 3 || == 6 || == 9))       {          if(board[i-1][j] == p || board[i-2][j] == p || board[i][j+1] == p ||               board[i][j+2] == p || board[i-1][j+1] == p || board[i-1][j+2] == p ||                   board[i-2][j+1] == p || board[i-2][j+2] == p)return false;          }      /*       000       *00       000     */                 if((j == 1 || j == 4 || j == 7) && (i == 2 || == 5 || == 8))       {          if(board[i-1][j] == p || board[i+1][j] == p || board[i-1][j+1] == p ||               board[i][j+1] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||                   board[i][j+2] == p || board[i+1][j+2] == p)return false;         }        /*       0*0       000       000     */                 if((j == 2 || j == 5 || j == 8) && (i == 1 || == 5 || == 7))       {          if(board[i-1][j] == p || board[i+1][j] == p || board[i-1][j+1] == p ||               board[i][j+1] == p || board[i+1][j+1] == p || board[i+1][j+2] == p ||                   board[i][j+2] == p || board[i+1][j+2] == p)return false;         }      /*       000       0*0       000     */                 if((j == 2 || j == 5 || j == 8) && (i == 2 || == 5 || == 8))       {          if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j+1] == p ||               board[i][j+1] == p || board[i][j-1] == p || board[i+1][j+1] == p ||                   board[i][j] == p || board[i+1][j-1] == p)return false;         }       /*       000       000       0*0     */                 if((j == 2 || j == 5 || j == 8) && (i == 3 || == 6 || == 9))       {          if(board[i][j-1] == p || board[i][j+1] == p || board[i-1][j] == p ||               board[i-1][j+1] == p || board[i-1][j-1] == p || board[i-2][j] == p ||                   board[i-1][j+1] == p || board[i-2][j-1] == p) return false;         }        /*       00*       000       000     */                 if((j == 3 || j == 6 || j == 9) && (i == 1 || == 4 || == 7))       {          if(board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p ||               board[i+1][j-1] == p || board[i+1][j-2] == p || board[i+2][j] == p ||                   board[i+2][j-1] == p || board[i+2][j-2] == p) return false;         }       /*       000       00*       000     */                 if((j == 3 || j == 6 || j == 9) && (i == 2 || == 5 || == 8))       {          if(board[i-1][j] == p || board[i-1][j-1] == p || board[i-1][j-2] == p ||               board[i][j-1] == p || board[i][j-2] == p || board[i+1][j] == p ||                   board[i+1][j-1] == p || board[i+1][j-2] == p) return false;         }      /*       000       000       00*     */                 if((j == 3 || j == 6 || j == 9) && (i == 3 || == 6 || == 9))       {          if(board[i][j-1] == p || board[i][j-1] == p || board[i-1][j] == p ||               board[i-1][j-1] == p || board[i-1][j-2] == p || board[i-2][j] == p ||                   board[i-2][j-1] == p || board[i-2][j-2] == p) return false;         }            return true;                             }  void sudoku::help_solve(int i, int j)   {     if(j <= 0)        {         = i-1;         j = 9;       }     if(change[i][j] == 1) return game.help_solve(i, j-1);     for(int p = 1; p <= 9; p++)       if(game.check_conflicts(p, i, j))          {           board[i][j] = p;           return;         }     return game.help_solve(i, j-1);    }  void sudoku::solve()   {                                 for(int = 1; <= 9; i++)         {           for(int j = 1; j <= 9; j++)             {               if(board[i][j] == 0 && change[i][j] == 0)                 {                   game.help_solve(i, j);                            }                   }               }        for(int = 1; <= 9; i++)         for(int j = 1; j <= 9; j++)           if(board[i][j] == 0) game.help_solve(i, j);    }   int main() {   game.add_first_cord();   game.solve();   game.print_board();      system("pause");   return 0; } 

edit: need use recursion right? maybe parameters give function wrong. don't know. in add_first_cord() declare starting values every sudoku has in beginning. here values use: http://bg.wikipedia.org/wiki/%d0%a4%d0%b0%d0%b9%d0%bb:sudoku-by-l2g-20050714.gif. expect see solved sudoku shown in wikipedia. solved values right others not. here in console enter image description here

suggested approach

  1. implement generic graph search algorithm
    • could use either idfs or a* graph search
      • i prefer second
    • do general directed graph
      • node type tnode
      • node successor function tnode => vector<tnode>
  2. define sudoku states
    • a state 9x9 array number 1, 2, ..., or 9 or blank in each position
  3. define goal sudoku state
    • all 81 cells filled in
    • all 9 rows have numbers {1, 2, ..., 9} in them
    • all 9 columns have numbers {1, 2, ..., 9} in them
    • all 9 3x3 squares have numbers {1, 2, ..., 9} in them
  4. define valid sudoku state successor function
    • a state s can have number n added @ row i, column j if:
      • cell (i,j) empty
      • there no other n in row i
      • there no other n in column j
      • there no other n in 3x3 square containing (i,j)
    • the state successor function maps state s vector of states satisfy these rules
  5. apply generic graph search algorithm (1) sudoku state graph (2-4)
  6. (optional) if choose use a* graph search, can define heuristic on sudoku state space potentially drastically increase performance
    • how design heuristic whole problem, that's more of art science

current approach

your current approach mixes specification of graph searched , implementation of search algorithm. you're going have lot of difficulty if mix two. problem naturally separates 2 distinct pieces -- algorithm , graph -- can , should exploit in implementation. make simpler.

the other benefit if go separation able reuse graph search algorithm on huge number of problems - cool!


Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -