java 数独为什么不显示数独的最终结果
java sudoku why it doesnt show me the final result of sudoku
晚上好,我尝试创建一个生成初始数独并尝试使用 A* 算法完成它的应用程序,在执行时,它显示的是初始状态,但是当它开始解决时,程序关闭而不显示结果,为什么?
更新说明:
我创建了初始数独,我必须使用链表和 Astar 算法从中得出最终解决方案,这里使用的启发式算法是最小剩余值。我希望我解释了问题。
===============================
控制台预览:
0 0 0 0 6 6 0 0 0
3 0 0 0 9 7 0 0 7
0 0 5 1 0 6 0 0 0
0 0 0 7 3 0 0 6 7
8 0 0 0 0 8 0 0
0 5 9 0 0 0 6 2 9
0 0 0 0 9 5 1 8 0
0 0 0 0 0 1 0 0 0
0 0 0 7 0 9 0 7 0
===============================
package sudoku;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.*;
public class Sudoku extends JFrame implements Comparable<Object>
{
/**
*
*/
private static final long serialVersionUID = 1L;
private int idp;
private int id;
private int[][] sudoku;
private int astar;
private LinkedList <Sudoku> sons ;
private boolean isFinished;
private boolean isValid;
public Sudoku()
{
isValid = false;
isFinished = false;
idp = 0;
id = 0;
sudoku = new int[9][9];
astar = 0;
sons = new LinkedList<Sudoku>();
init();
}
public Sudoku(int id,int[][] s)
{
isValid = false;
isFinished = false;
idp = id;
id = id+1;
sudoku = s;
astar = astar();
sons = new LinkedList<Sudoku>();
}
public void init()
{
int diff = 31;
Random r = new Random();
while(diff>0)
{
int x = r.nextInt(9);
int y = r.nextInt(9);
sudoku[x][y] = 1+ r.nextInt(9);
astar += sudoku[x][y];
diff--;
}
astar = 405 - astar;
}
public int astar()
{
int res=0;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
res += sudoku[i][j];
}
}
res = 405-res;
return res;
}
public void checkFinish()
{
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(sudoku[i][j]!=0)
{
isFinished = true;
}
else
{
isFinished = false;
return;
}
}
}
}
public boolean isValidSudoku(int[][] sudoku)
{
if(isFinished)
{
if (sudoku == null || sudoku.length != 9 || sudoku[0].length != 9)
return false;
// check each column
for (int i = 0; i < 9; i++)
{
boolean[] m = new boolean[9];
for (int j = 0; j < 9; j++)
{
if (sudoku[i][j] != 0)
{
if (m[ (sudoku[i][j] - 1)])
{
return false;
}
m[ (sudoku[i][j] - 1)] = true;
}
}
}
//check each row
for (int j = 0; j < 9; j++)
{
boolean[] m = new boolean[9];
for (int i = 0; i < 9; i++)
{
if (sudoku[i][j] != 0)
{
if (m[ (sudoku[i][j] - 1)])
{
return false;
}
m[ (sudoku[i][j] - 1)] = true;
}
}
}
//check each 3*3 matrix
for (int block = 0; block < 9; block++)
{
boolean[] m = new boolean[9];
for (int i = block / 3 * 3; i < block / 3 * 3 + 3; i++)
{
for (int j = block % 3 * 3; j < block % 3 * 3 + 3; j++)
{
if (sudoku[i][j] != 0)
{
if (m[(int) (sudoku[i][j] - 1)])
{
return false;
}
m[(int) (sudoku[i][j] - 1)] = true;
}
}
}
}
return true;
}
else
{
System.out.println("not finished yet");
}
return false;
}
public void checkSolution()
{
if(isValidSudoku(sudoku))
{
isValid = true;
}
else
{
isValid = false;
}
}
public void viewSolution()
{
checkSolution();
if(isValid)
{
JFrame frame = new JFrame("Sudoku");
JTextField[][] s = new JTextField[9][9];
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setSize(500, 500);
for(int i =0;i<9;i++)
{
for(int j =0;j<9;j++)
{
s[i][j].setText(String.valueOf(sudoku[i][j]));
s[i][j].setVisible(true);
s[i][j].setSize(50, 50);
s[i][j].setLocation(50*i, 50*j);
frame.add(s[i][j]);
}
}
}
}
public void show()
{
for(int i =0;i<9;i++)
{
for(int j =0;j<9;j++)
{
System.out.print(sudoku[i][j]+" ");
}
System.out.println("");
}
}
public void solve(Sudoku sudoku)
{
for(int i = 0;i<9;i++)
{
for(int j = 0;j<9;j++)
{
int[][] ts = sudoku.getSudoku();
if(ts[i][j]==0)
{
for(int k=0;k<9;k++)
{
ts[i][j] = k+1;
Sudoku t = new Sudoku(id,ts);
sons.add(t);
}
}
}
}
Iterator<Sudoku> iter = sons.iterator();
Collections.sort(sons);
while(iter.hasNext() && iter.next().getAstar()>0)
{
Sudoku temp = iter.next();
temp.solve(temp);
}
checkFinish();
if(sudoku.isFinished)
{
viewSolution();
}
}
public int getIdp()
{
return idp;
}
public int getId()
{
return id;
}
public int[][] getSudoku()
{
return sudoku;
}
public int getAstar()
{
return astar;
}
public LinkedList<Sudoku> getSons()
{
return sons;
}
public int compareTo(Object other)
{
Sudoku temp = (Sudoku)other;
if (this.astar < temp.astar)
return 1;
else if (this.astar > temp.astar)
return -1;
else
return 0;
}
}
=========================================== =====
package sudoku;
public class Main
{
public static void main(String[] args)
{
Sudoku s = new Sudoku();
s.show();
s.solve(s);
}
}
您的 show() 方法覆盖了 java.awt.Window.show() 方法。您需要调用 super.show() 作为该方法的第一行。所以你的新方法是:
public void show()
{
super.show();//Call to super class to let it paint the window
for(int i =0;i<9;i++)
{
for(int j =0;j<9;j++)
{
System.out.print(sudoku[i][j]+" ");
}
System.out.println("");
}
}
我进行此更改后,它显示了 JFrame。我还使 JFrame 居中并固定它,以便在单击 X 时关闭应用程序。下面是我修改后的 Main class。 JFrame 只显示灰色背景。看起来您仍然需要做一些工作来渲染您的组件。我希望这能让您更接近您的解决方案。
package sudoku;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
public class Main
{
public static void main(String[] args)
{
Sudoku s = new Sudoku();
s.setSize(400, 400);
//Center the JFrame
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
s.setLocation(dim.width/2-s.getSize().width/2, dim.height/2-s.getSize().height/2);
//Close application when the user clicks the X
s.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
s.show();
s.solve(s);
}
晚上好,我尝试创建一个生成初始数独并尝试使用 A* 算法完成它的应用程序,在执行时,它显示的是初始状态,但是当它开始解决时,程序关闭而不显示结果,为什么?
更新说明: 我创建了初始数独,我必须使用链表和 Astar 算法从中得出最终解决方案,这里使用的启发式算法是最小剩余值。我希望我解释了问题。
===============================
控制台预览:
0 0 0 0 6 6 0 0 0
3 0 0 0 9 7 0 0 7
0 0 5 1 0 6 0 0 0
0 0 0 7 3 0 0 6 7
8 0 0 0 0 8 0 0
0 5 9 0 0 0 6 2 9
0 0 0 0 9 5 1 8 0
0 0 0 0 0 1 0 0 0
0 0 0 7 0 9 0 7 0
===============================
package sudoku;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;
import javax.swing.*;
public class Sudoku extends JFrame implements Comparable<Object>
{
/**
*
*/
private static final long serialVersionUID = 1L;
private int idp;
private int id;
private int[][] sudoku;
private int astar;
private LinkedList <Sudoku> sons ;
private boolean isFinished;
private boolean isValid;
public Sudoku()
{
isValid = false;
isFinished = false;
idp = 0;
id = 0;
sudoku = new int[9][9];
astar = 0;
sons = new LinkedList<Sudoku>();
init();
}
public Sudoku(int id,int[][] s)
{
isValid = false;
isFinished = false;
idp = id;
id = id+1;
sudoku = s;
astar = astar();
sons = new LinkedList<Sudoku>();
}
public void init()
{
int diff = 31;
Random r = new Random();
while(diff>0)
{
int x = r.nextInt(9);
int y = r.nextInt(9);
sudoku[x][y] = 1+ r.nextInt(9);
astar += sudoku[x][y];
diff--;
}
astar = 405 - astar;
}
public int astar()
{
int res=0;
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
res += sudoku[i][j];
}
}
res = 405-res;
return res;
}
public void checkFinish()
{
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(sudoku[i][j]!=0)
{
isFinished = true;
}
else
{
isFinished = false;
return;
}
}
}
}
public boolean isValidSudoku(int[][] sudoku)
{
if(isFinished)
{
if (sudoku == null || sudoku.length != 9 || sudoku[0].length != 9)
return false;
// check each column
for (int i = 0; i < 9; i++)
{
boolean[] m = new boolean[9];
for (int j = 0; j < 9; j++)
{
if (sudoku[i][j] != 0)
{
if (m[ (sudoku[i][j] - 1)])
{
return false;
}
m[ (sudoku[i][j] - 1)] = true;
}
}
}
//check each row
for (int j = 0; j < 9; j++)
{
boolean[] m = new boolean[9];
for (int i = 0; i < 9; i++)
{
if (sudoku[i][j] != 0)
{
if (m[ (sudoku[i][j] - 1)])
{
return false;
}
m[ (sudoku[i][j] - 1)] = true;
}
}
}
//check each 3*3 matrix
for (int block = 0; block < 9; block++)
{
boolean[] m = new boolean[9];
for (int i = block / 3 * 3; i < block / 3 * 3 + 3; i++)
{
for (int j = block % 3 * 3; j < block % 3 * 3 + 3; j++)
{
if (sudoku[i][j] != 0)
{
if (m[(int) (sudoku[i][j] - 1)])
{
return false;
}
m[(int) (sudoku[i][j] - 1)] = true;
}
}
}
}
return true;
}
else
{
System.out.println("not finished yet");
}
return false;
}
public void checkSolution()
{
if(isValidSudoku(sudoku))
{
isValid = true;
}
else
{
isValid = false;
}
}
public void viewSolution()
{
checkSolution();
if(isValid)
{
JFrame frame = new JFrame("Sudoku");
JTextField[][] s = new JTextField[9][9];
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setSize(500, 500);
for(int i =0;i<9;i++)
{
for(int j =0;j<9;j++)
{
s[i][j].setText(String.valueOf(sudoku[i][j]));
s[i][j].setVisible(true);
s[i][j].setSize(50, 50);
s[i][j].setLocation(50*i, 50*j);
frame.add(s[i][j]);
}
}
}
}
public void show()
{
for(int i =0;i<9;i++)
{
for(int j =0;j<9;j++)
{
System.out.print(sudoku[i][j]+" ");
}
System.out.println("");
}
}
public void solve(Sudoku sudoku)
{
for(int i = 0;i<9;i++)
{
for(int j = 0;j<9;j++)
{
int[][] ts = sudoku.getSudoku();
if(ts[i][j]==0)
{
for(int k=0;k<9;k++)
{
ts[i][j] = k+1;
Sudoku t = new Sudoku(id,ts);
sons.add(t);
}
}
}
}
Iterator<Sudoku> iter = sons.iterator();
Collections.sort(sons);
while(iter.hasNext() && iter.next().getAstar()>0)
{
Sudoku temp = iter.next();
temp.solve(temp);
}
checkFinish();
if(sudoku.isFinished)
{
viewSolution();
}
}
public int getIdp()
{
return idp;
}
public int getId()
{
return id;
}
public int[][] getSudoku()
{
return sudoku;
}
public int getAstar()
{
return astar;
}
public LinkedList<Sudoku> getSons()
{
return sons;
}
public int compareTo(Object other)
{
Sudoku temp = (Sudoku)other;
if (this.astar < temp.astar)
return 1;
else if (this.astar > temp.astar)
return -1;
else
return 0;
}
}
=========================================== =====
package sudoku;
public class Main
{
public static void main(String[] args)
{
Sudoku s = new Sudoku();
s.show();
s.solve(s);
}
}
您的 show() 方法覆盖了 java.awt.Window.show() 方法。您需要调用 super.show() 作为该方法的第一行。所以你的新方法是:
public void show()
{
super.show();//Call to super class to let it paint the window
for(int i =0;i<9;i++)
{
for(int j =0;j<9;j++)
{
System.out.print(sudoku[i][j]+" ");
}
System.out.println("");
}
}
我进行此更改后,它显示了 JFrame。我还使 JFrame 居中并固定它,以便在单击 X 时关闭应用程序。下面是我修改后的 Main class。 JFrame 只显示灰色背景。看起来您仍然需要做一些工作来渲染您的组件。我希望这能让您更接近您的解决方案。
package sudoku;
import java.awt.Dimension;
import java.awt.Toolkit;
import javax.swing.JFrame;
public class Main
{
public static void main(String[] args)
{
Sudoku s = new Sudoku();
s.setSize(400, 400);
//Center the JFrame
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
s.setLocation(dim.width/2-s.getSize().width/2, dim.height/2-s.getSize().height/2);
//Close application when the user clicks the X
s.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
s.show();
s.solve(s);
}