package com.detail.algorithm;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class ShuDu implements ActionListener{
static Integer[] values = {1,2,3,4,5,6,7,8,9};
JFrame mainFrame; //主面板
Container thisContainer;
JPanel centerPanel,southPanel,northPanel; //子面板
JTextField textfields[][] = new JTextField[9][9];//游戏按钮数组
int[][] numbers = new int[9][9];
JButton exitButton,newlyButton; //退出,重列,重新开始按钮
Integer[] pre;
Map<Integer,Integer[]> availableList = new HashMap();
Integer[] curidnex = new Integer[81];
public void init(){
mainFrame=new JFrame("数独游戏");
thisContainer = mainFrame.getContentPane();
thisContainer.setLayout(new BorderLayout());
centerPanel=new JPanel();
southPanel=new JPanel();
northPanel=new JPanel();
thisContainer.add(centerPanel,"Center");
thisContainer.add(southPanel,"South");
thisContainer.add(northPanel,"North");
southPanel.setLayout(new FlowLayout());
centerPanel.setLayout(new GridLayout(9,9));
for(int rows = 0;rows < 9;rows++){
for(int cols = 0;cols < 9;cols++ ){
if(numbers[rows][cols]!=0){
textfields[rows][cols]=new JTextField(String.valueOf(numbers[rows][cols]));
textfields[rows][cols].setEnabled(false);
}
else{
textfields[rows][cols]=new JTextField();
textfields[rows][cols].setEnabled(true);
}
textfields[rows][cols].addActionListener(this);
centerPanel.add(textfields[rows][cols]);
}
}
exitButton=new JButton("退出");
exitButton.addActionListener(this);
newlyButton=new JButton("重新开始");
newlyButton.addActionListener(this);
southPanel.add(exitButton);
southPanel.add(newlyButton);
mainFrame.setBounds(280,100,500,450);
mainFrame.setVisible(true);
}
public void assignNumber(){
Integer[] available;
int i=0;
int rows=0;
int cols=0;
int backdepth=1;
for(rows = 0;rows < 9;rows++){
for(cols = 0;cols < 9;cols++ ){
if(rows==0 && cols==0){
numbers[rows][cols]=(int)(Math.random()*9+1);
curidnex[0]=1;
available = values;
}
available = searchMatchNumber(rows,cols);
while(available.length<=0){
while(availableList.get(rows*9+cols-backdepth).length==1){
backdepth=backdepth+1;
if((cols-backdepth)<=0){
rows=rows-1;
cols=8;
available = searchMatchNumber(rows,cols);
}
}
while(curidnex[rows*9+cols-backdepth]>=availableList.get(rows*9+cols-backdepth).length-1){
backdepth=backdepth+1;
i=curidnex[rows*9+cols-backdepth];
System.out.println("------"+(cols-backdepth)+" i="+i);
if((cols-backdepth)<=0){
rows=rows-1;
cols=8;
available = searchMatchNumber(rows,cols);
}
}
i=curidnex[rows*9+cols-backdepth]+1;
curidnex[rows*9+cols-backdepth]=i;
System.out.println("格子重置 cols="+(cols-backdepth)+" i="+curidnex[rows*9+cols-backdepth]);
numbers[rows][cols-backdepth]= availableList.get(rows*9+cols-backdepth)[i];
System.out.println("格子重置:numbers["+rows+"]["+(cols-backdepth)+"]="+numbers[rows][cols-backdepth]+" i="+i);
cols = cols-backdepth+1;
backdepth=1;
available = searchMatchNumber(rows,cols);
}
if(available.length>=1){
Integer index = rows*9+cols;
availableList.put(index, available);
numbers[rows][cols] = available[0];
curidnex[rows*9+cols]=0;
}
}
}
}
public Integer[] searchMatchNumber(int rows,int cols){
Integer[] temp = TwoArrayDifference(ValidRowNumber(rows,cols),ValidColNumber(rows,cols));
// System.out.print("===========");
// print(temp);
// System.out.println();
Integer[] available = TwoArrayDifference(temp,ValidMatrixNumber(rows,cols));
System.out.print("~~~~~~~~~~");
print(available);
System.out.println();
return available;
}
public Integer[] ValidRowNumber(int row,int col){
System.out.println("rows="+row+" cols="+col);
Integer[] validrownumbers;
if(col==0)
validrownumbers = values;
else{
Integer[] existrowNumbers = new Integer[col];
for(int i=0;i<col;i++){
existrowNumbers[i] = numbers[row][i];
}
System.out.print("existrowNumbers:");
for(int j=0;j<existrowNumbers.length;j++){
System.out.print("--"+existrowNumbers[j]);
}
System.out.println();
validrownumbers = leftNumbers(existrowNumbers);
}
// System.out.print("validrownumbers: ");
// print(validrownumbers);
// System.out.println();
return validrownumbers;
}
public Integer[] ValidColNumber(int row,int col){
Integer[] validcolnumbers;
if(row==0)
validcolnumbers = values;
else{
Integer[] existcolNumbers = new Integer[row];
for(int i=0;i<row;i++){
existcolNumbers[i] = numbers[i][col];
}
validcolnumbers = leftNumbers(existcolNumbers);
}
// System.out.print("validcolnumbers: ");
// print(validcolnumbers);
// System.out.println();
return validcolnumbers;
}
public Integer[] ValidMatrixNumber(int row,int col){
//System.out.println("rows="+row+" cols="+col);
List existList = new ArrayList();
int index=0;
if(row==0 || row==3 || row==6){
for(int i=3*(col/3);i<col;i++){
if(numbers[row][i]!=0){
existList.add(numbers[row][i]);
//System.out.print("^^"+numbers[row][i]);
}
}
}
else if(row==1 || row==4 || row==7){
for(int i=3*(col/3);i<3*(col/3)+3;i++){
existList.add(numbers[row-1][i]);
}
for(int i=3*(col/3);i<=col;i++){
if(numbers[row][i]!=0)
existList.add(numbers[row][i]);
}
}
else if(row==2 || row==5 || row==8){
for(int i=3*(col/3);i<3*(col/3)+3;i++){
existList.add(numbers[row-1][i]);
}
for(int i=3*(col/3);i<3*(col/3)+3;i++){
existList.add(numbers[row-2][i]);
}
for(int i=3*(col/3);i<=col;i++){
if(numbers[row][i]!=0)
existList.add(numbers[row][i]);
}
}
Integer[] existmatrixNumbers = (Integer [])existList.toArray(new Integer[0]);
Integer[] validmatrixnumbers;
if((row==0 || row==3 || row==6) && col%3==0){
validmatrixnumbers=values;
}
validmatrixnumbers = leftNumbers(existmatrixNumbers);
// System.out.print("validmatrixnumbers: ");
// print(validmatrixnumbers);
// System.out.println();
return validmatrixnumbers;
}
public Integer[] leftNumbers(Integer[] exist){//求两个数组的差集
List valuesList= Arrays.asList(values);
Set hst = new HashSet(valuesList);
for(int i:exist){
if(!hst.add(i)){
hst.remove(i);
}
}
return (Integer []) hst.toArray(new Integer[0]);
}
public Integer[] TwoArrayDifference(Integer[] arr1,Integer[] arr2){
List result = new ArrayList();
List arr = Arrays.asList(arr1);
Set set = new HashSet(arr);
for(Integer i:arr2){
if(!set.add(i)){
result.add(i);
}
}
return (Integer []) result.toArray(new Integer[0]);
}
public void print(Integer[] arr){
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
public void removeValues(){
for(int i=0;i<25;i++){
int row = (int)(Math.random()*9);
int col = (int)(Math.random()*9);
while(numbers[row][col]==0){
row = (int)(Math.random()*9);
col = (int)(Math.random()*9);
}
numbers[row][col]=0;
}
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==this.exitButton)
System.exit(0);
if(e.getSource()==this.newlyButton){
rebuild();
}
for(int rows = 0;rows < 9;rows++){
for(int cols = 0;cols < 9;cols++ ){
if(e.getSource()==textfields[rows][cols]){
int value = Integer.parseInt(textfields[rows][cols].getText());
FillNumber(rows,cols,value);
if(isEnd()){
JOptionPane.showMessageDialog(null, "恭喜你,游戏成功", "success", JOptionPane.INFORMATION_MESSAGE);
}
}
}
}
}
private void rebuild() {
numbers=new int[9][9];
mainFrame.setVisible(false);
assignNumber();
removeValues();
init();
}
private void FillNumber(int row, int col, int values) {
textfields[row][col].setBackground(thisContainer.getBackground());
for(int i=0;i<9;i++){
if(numbers[row][i]!=0 && numbers[row][i]==values){
System.out.println("Error"+" numbers["+row+"]["+i+"]="+numbers[row][i]);
textfields[row][col].setBackground(Color.red);
return;
}
}
for(int i=0;i<9;i++){
if(numbers[row][i]!=0 && numbers[i][col]==values){
System.out.println("Error"+" numbers["+row+"]["+i+"]="+numbers[row][i]);
textfields[row][col].setBackground(Color.red);
return;
}
}
for(int i=3*(row/3);i<(3*(row/3))+3;i++){
for(int j=3*(col/3);j<(3*(col/3))+3;j++){
if(numbers[i][j]!=0 && numbers[i][j]==values){
System.out.println("Error"+" numbers["+i+"]["+j+"]="+numbers[i][i]);
textfields[row][col].setBackground(Color.red);
return;
}
}
}
}
public boolean isEnd(){
boolean end=true;
for(int rows = 0;rows < 9;rows++){
for(int cols = 0;cols < 9;cols++ ){
if(numbers[rows][cols]==0){
return false;
}
}
}
return end;
}
public static void main(String[] args) {
ShuDu game = new ShuDu();
game.assignNumber();
game.removeValues();
game.init();
}
}