在java上制作数独游戏

时间:2014-06-30 16:26:59

标签: java sudoku

我是一名新程序员。通过我在java中的自学习制作一些程序后,现在我有兴趣用这种语言制作一个数独游戏。谁能解释我如何控制9x9网格并在每次程序运行时随机化数字?提前致谢。我刚刚编写了一个代码来自己输入整数。这是代码:

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();
            }
        });
}

}

感谢您的支持。我已经取得了很大进展。

    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;
}

}

但有两个问题。首先,正如您所看到的,数组总是给出一个我必须捕获的arrarindexoutofboundsexception。我正在努力工作的算法不能正常工作。第三,3x3网格的代码不起作用。有什么想法吗?

2 个答案:

答案 0 :(得分:0)

我首先要设计一个SudokuGrid类。您应该使用2-D数组作为后备存储。以下是我如何构建它:

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
    }

}

您可以使用此类来表示您的网格。设数组中的0表示空白方块。我首先将其创建为控制台程序,然后在获得数独逻辑工作后,您可以尝试使用swing。如果您想要任何其他说明或解释,请发表评论。

答案 1 :(得分:0)

真正的问题是,您是否要从3x3子网格或一个9x9网格构建网格。这就决定了你的数据结构。两者都有它们的用例,因为3x3子网格会在框中更容易地检查输入数字的有效性,但在9x9网格中稍微检查一行和一行中的唯一性更容易。我认为9x9方法稍微容易一些。

在任何一种情况下,你想要的是一个二维数组。

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

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

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

     ...
 }

你应该像我在这里描述的那样使用数独生成:Sudoku solver, not backtracking solver

附录:

要创建1到9的随机数,请使用以下方法:

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

编辑:

要随机化数组的内容,您将执行以下操作:

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