-3

I'm a new programmer. After making some programs through my self learning in java, now I'm interested to make a sudoku in that language. Can anyone explain me how to control the 9x9 grids and randomising the numbers each time the program runs? Thanks in advance. I have just written a code to take the input of only integers myself. Here's the code :

import javax.swing.UIManager.LookAndFeelInfo;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.border.Border;
import javax.swing.*;

    public class GUI_project extends JFrame {

    private JMenuBar menuBar;
    private JTextField textfield1;
    String k;


public GUI_project(){

    this.setTitle("GUI_project");
    this.setSize(500,400);
    this.setJMenuBar(menuBar);


    JPanel contentPane = new JPanel(null);
    contentPane.setPreferredSize(new Dimension(500,400));
    contentPane.setBackground(new Color(192,192,192));

    textfield1 = new JTextField();
    textfield1.setBounds(105,109,148,108);
    textfield1.setBackground(new Color(255,255,255));
    textfield1.setForeground(new Color(0,0,0));
    textfield1.setEnabled(true);
    textfield1.setFont(new Font("sansserif",0,12));
    textfield1.setText("");
    textfield1.setVisible(true);


    textfield1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                chkdl();
            }
        });
    textfield1.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent evt){
                chkdl();
            }

            public void keyTyped(KeyEvent evt){
                chkdl();
            }

            public void keyReleased(KeyEvent evt){
                chkdl();
            }
        });


    contentPane.add(textfield1);


    this.add(contentPane);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.pack();
    this.setVisible(true);
}


private void chkdl () {
    //TODO
    String f = textfield1.getText();


        try{
            int g = Integer.parseInt(f);
            if(g>0 && g<10){
                textfield1.setText(Integer.toString(g));
                k=Integer.toString(g);
                textfield1.setEditable(true);
            }
            else{
                textfield1.setText(k);
                textfield1.setEditable(true);
            }
        }
        catch(NumberFormatException ex){
            if(f.equals("")){
                textfield1.setText("");
                k="";
            }
            else{
            textfield1.setText(k);
            textfield1.setEditable(true);}
        }
}

public static void main(String[] args){
    System.setProperty("swing.defaultlaf", "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new GUI_project();
            }
        });
}

}

Thanks for your support. I have progressed that far.

    import java.util.*;
    class rnd{
    public static void main(String [] args){
    int [][] game = new int[10][10];
    for(int o = 0;o<9;o++){
        for(int o2 = 0;o2<9;o2++){
            game[o][o2]=0;
        }
    }
    int a = 0;
    Random r = new Random();
    int row = 1;
    int clm = 1;
    int cnt = 0;
    int chk=0;
    int fill = 0;
    while(row<9){
        while(clm<9){
            fill = r.nextInt(9)+1;
            chk = 0;
            if(clm==1 || clm==4 || clm==7){
                for(int cnc = clm;cnc!=(clm+2);cnc++){
                     chk=retchk(row,game,cnc,fill);
                }
            }
            else if(clm==2 || clm==5 || clm==8){
                for(int cnc = (clm-1);cnc!=(clm+1);cnc++){
                     chk=retchk(row,game,cnc,fill);
                }
            }
            else if(clm==3||clm==6||clm==9){
                for(int cnc = (clm-2);cnc!=clm;cnc++){
                    chk=retchk(row,game,cnc,fill);}
            }
            for(int rw = 0;rw!=9;rw++){
                if(game[row][rw]==fill){
                    chk=1;
                    cnt++;
                    break;
                }
            }
            if(chk==0){
                for(int c = 0;c!=9;c++){
                    if(game[c][clm]==fill){
                        chk=1;
                        cnt++;
                        break;
                    }
                }
                if(chk==0){
                    int qa = 0;
                    try{
                        qa = (game[row][clm]=fill);}
                    catch(ArrayIndexOutOfBoundsException ml){
                        System.out.print("\n"+row+"\n"+clm);
                    }
                    System.out.print(qa+" ");
                    clm++;
                }
                if(clm==9){
                    clm=0;
                    System.out.print("          Row "+(row)+" filled up\n");
                    row++;
                  }
              }
           }
        }
    }

 public static int retchk(int row,int [][] game,int cnc,int fill){
    int chk = 0;
    if(row==1 || row==4 || row==7){
        for(int cnr = row;cnr!=(row+2);cnr++){
            if(game[cnr][cnc]==fill){
                chk=1;
                break;
            }
        }
    }
    else if(row==2 || row==5 || row==8){
        for(int cnr = (row-1);cnr!=(row+1);cnr++){
            if(game[cnr][cnc]==fill){
                chk=1;
                break;
            }
        }
    }
    else if(row==3 || row==6 || row==9){
        for(int cnr = (row-2);cnr!=row;cnr++){
            if(game[cnr][cnc]==fill){
                chk=1;
                break;
            }
        }
    }
    return chk;
}

}

But two problems are there. First of all, as you can see, the array is always giving an arrarindexoutofboundsexception that i have to catch. And the algorithm i'm tring to work in, is not properly working. And the third, the code for the 3x3 grids is not working. Have any idea?

Subhranil
  • 851
  • 1
  • 8
  • 23
  • 6
    I honestly believe you should make a Console project first, because Swing just adds unnecessary complication to your learning efforts, as what you're asking is basically just simple 2D int array management, and using the *Random* class, as Random random = new Random(); random.nextInt(9)+1;. As for randomizing a grid, check out my answer here: http://stackoverflow.com/questions/24354568/sudoku-solver-not-backtracking-solver/24355225#24355225 – EpicPandaForce Jun 30 '14 at 16:29
  • but in console is it possible to put the number in any of the empty grid in that game? – Subhranil Jun 30 '14 at 16:33
  • Of course, you would need to type the row and column index you want to select, and the number you want to place there. It can work, and obviously he needs basic Java (and programming in general) practice more than messing with Swing. – EpicPandaForce Jun 30 '14 at 16:34

2 Answers2

0

I would start by designing a SudokuGrid class. You should use a 2-D Array of ints as your backing storage. Here's how I would structure it:

public class SudokuGrid {

    // private instance variables
    private int[] grid;

    // constructor initializes sudoku grid with random values
    public SudokuGrid() {
        // TODO - I'll let you complete this method
    }

    // add value to the grid; throws an exception if an invalid value is added
    public void addValue(int value, int x, int y) {
        // TODO - I'll let you complete this method
    }

}

You can use this class to represent your grid. Let a 0 in the array represent a blank square. I would create this as a console program first, then you can experiment with swing once you get the sudoku logic working. Please leave a comment if you would like any additional clarifications or explanations.

Cytomat
  • 5
  • 2
0

The real question is whether you want to construct the grid from 3x3 subgrids, or one 9x9 grid. That's what would determine your data structure. Both have their use-cases, as the 3x3 subgrid would make checking the validity of inputted number easier in the box, but checking the uniqueness in a line and row is easier by a bit in the 9x9 grid. I think the 9x9 approach is slightly easier.

In either case though, what you want is a two-dimensional array.

public class Grid
{
     private int[][] grid;

     public Grid()
     {
         grid = new int[9][9];
     }

     public int[][] getGrid()
     {
          return grid;
     }

     ...
 }

And you should use the generation of Sudoku as I described here: Sudoku solver, not backtracking solver

Addendum:

To create a random number from 1 to 9, use the following method:

Random random = new Random();
int randomNumber = random.nextInt(9)+1; //generates from 0 to 8, adds +1

EDIT:

To randomize the contents of an array, what you would do is the following:

int[] array = new int[9];
for(int i = 0; i < array.length; i++)
{
    array[i] = i+1; //result is array {1,2,3,4,5,6,7,8,9};
}
for(int i = 0; i < array.length; i++)
{
    int random_i_index = random.nextInt(array.length);
    int random_j_index = random.nextInt(array.length);

    //swapping
    int temp = array[random_i_index];
    array[random_i_index] = array[random_j_index];
    array[random_j_index] = temp;
}
//result is array with numbers from 1 to 9 in randomized order
Community
  • 1
  • 1
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • can i random an int array? – Subhranil Jul 01 '14 at 12:26
  • In your case, I wouldn't do that, because you need your Sudoku to be valid. Filling up an array with random numbers would just be for(int i = 0; i < 9; i++) { array[i] = random.nextInt(9)+1; } but as I said that will not result in a valid sudoku, the shifting method I linked is much better for this purpose. The way I would "randomize" the Sudoku compared to that is by randomly swapping elements in the initial 9-length array that is used to generate the numbers. – EpicPandaForce Jul 01 '14 at 12:29
  • By shifting method I'm referring to http://stackoverflow.com/questions/24354568/sudoku-solver-not-backtracking-solver/24355225#24355225 that I linked above. – EpicPandaForce Jul 01 '14 at 12:32
  • But it seems that your example will have a sudoku with only the way in which the arrays are initialised. Isn't it? – Subhranil Jul 03 '14 at 05:37
  • Well, yes, it follows a specific pattern, but I really don't think people would notice the rule behind it, considering you're removing numbers from it. The initial array order is randomized, so that it's not just 1 to 9. – EpicPandaForce Jul 03 '14 at 06:04
  • You need to generate a `valid` sudoku *somehow*. – EpicPandaForce Jul 03 '14 at 07:47
  • Yes. And that's looking like a seroius question. Can you think something else than the conventional ways? I'm looking for it. – Subhranil Jul 04 '14 at 15:59
  • Well, I did give you a particular way of making a valid sudoku, I've linked it twice by now. Other than that, I'm not sure. I think that works pretty well, if you manually figure out which ones you can remove without creating more than one solutions, you can pick from those at somewhat random. Either that, or implement a "not so stupid" brute forcer mechanism that checks for all solutions, but not by iterating through all numbers from 1 to 9, but only the numbers that are valid. – EpicPandaForce Jul 04 '14 at 18:50