构造数独

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值