Question

my sudoku solver works pretty well and right now all I am trying to do is "check" when the user clicks the "solve" button. This is a user-input taking custom sudoku, so based on user's inputs on the boxes, the solver will solve.

I am trying to check whether the user is putting invalid values, such as " 1 1 2 3 4 5 6 7 8 ", which would be wrong because of " 1 1 ". Because I have my own checkRow, checkBox, checkCol methods, which are used to solve the puzzle, I was gonna check for any invalid values using those methods before running it - because if the user inputs invalid values the program will freeze.

The very weird thing is that my sysout inserted to try and debug, I get the following:

I, J, NUM 0 0 1

METHOD ROW : true

MAIN R: false

MAIN C: false

MAIN B:false

METHOD ROW : true

Check: 0, 0, false

METHOD ROW : true

which METHOD shows the return value of checkRow method, and Main R showing the return value when called from the solve actionListener, which is positioned in main().

Threading issues?? I'm not too familiar with JAVA so I did put majority of my code in main(I know it's not good, but I am still learning).

Thanks for any help in advance.

solve.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent event) {

            solve.setEnabled(false);

            for (int i=0; i<9; i++) {
                for (int j=0; j<9; j++) {

                    try {

                        problem[i][j]=Integer.parseInt(board[i][j].getText());  
                        System.out.println("I, J, NUM " +i+" "+j+" "+problem[i][j]);
                        System.out.println("TOP R: " + checkRow(i, problem[i][j]));
                        System.out.println("TOP C: " + checkCol(j, problem[i][j]));
                        System.out.println(("TOP B:" + checkBox(i, j, problem[i][j])));
                        if(problem[i][j] != 0){
                                System.out.println
                                ("Check: " + i +", "+j +", " +check(i, j, problem[i][j]));
                             if( !check(i, j, problem[i][j])) {
                                 solve.setEnabled(true);
                                 JOptionPane.showMessageDialog(null, "Bad Input!");
                                 clear_board();
                                 return;
                             }
                        }
                    }catch(NumberFormatException e) {

                        problem[i][j] = 0;
                    }
                }
            }
            try {

                solve_s(0,0);
            } catch (Exception e) {
            }               
        }
    });

/** Checks if num is an acceptable value for the given row */

protected static boolean checkRow( int row, int num )
{
  for( int col = 0; col < 9; col++ ) {
         if( problem[row][col] == num ) {
                System.out.println("ROW C: "+ (problem[row][col] == num));
            return false ;
    }
      return true;
   }

   /** Checks if num is an acceptable value for the given column */
   protected static boolean checkCol( int col, int num )
   {
      for( int row = 0; row < 9; row++ ){
        //  System.out.println("COL C: "+ (problem[row][col] == num));
         if( problem[row][col] == num )
            return false ;
      }
      return true ;
   }

   /** Checks if num is an acceptable value for the box around row and col */
   protected static boolean checkBox( int row, int col, int num )
   {
      row = (row / 3) * 3 ;
      col = (col / 3) * 3 ;

      for( int r = 0; r < 3; r++ ) {
         for( int c = 0; c < 3; c++ ) {
         if( problem[row+r][col+c] == num ) {
            // System.out.println("BOX C: "+ (problem[row][col] == num));
            return false ;
         }
         }
      }

      return true ;
   }
Was it helpful?

Solution

Yep, you have threading issues; if you run all of your code in one thread, it can't draw on a window AND run a loop. It will wait for the loop to finish before updating your GUI. Threads allow you to run multiple pieces of code at once, which can be dangerous.

Imagine two people who need to use the same bathroom. If those people are code, they throw errors, not tantrums. So, to avoid errors, threads SHOULD avoid modifying eachother's data (they can view eachother's data without too many issues and it's usually necessary). Your sudoku solving class should use the Runnable interface, which allows threads to be created. You'll need to provide a run() method which contains the code used for threads. Then, in your button's actionPerformed code, call new Thread(new SudokuChecker()).start();

Make sure that you are using swing as a thread (I forget the code, but it involves SwingUtilities.invokeRunnable..., and can be found all over the web. Threads are a huge nuisance to work with, but they don't cause many issues if they do their own thing. You run into issues when they start changing, rather than simply checking, the other thread's data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top