數獨終盤的隨機生成算法


數獨,是源自18世紀瑞士發明,流傳到美國的一種數學游戲。是一種運用紙、筆進行演算的邏輯游戲。玩家需要根據9×9盤面上的已知數字,推理出所有剩余空格的數字,並滿足每一行、每一列、每一個粗線宮內的數字均含1-9,不重復。

數獨中的數字排列千變萬化,那么究竟有多少種終盤的數字組合呢?

6,670,903,752,021,072,936,960(約為6.67×10的21次方)種組合,2005年由Bertram Felgenhauer和Frazer Jarvis計算出該數字,並將計算方法發布在他們網站上,如果將等價終盤(如旋轉、翻轉、行行對換,數字對換等變形)不計算,則有5,472,730,538個組合。數獨終盤的組合數量都如此驚人,那么數獨題目數量就更加不計其數了,因為每個數獨終盤又可以制作出無數道合格的數獨題目。
 
為了觸摸到所有的終盤情況,就不得不使用隨機填數的方法。

 

部分代碼:

  1 public void startGame() {
  7         int currentTimes;initM();
 15     }
 16 
 17 public void initM(){
 18             for (int row = 0; row < 9; row++) {  
 19                 if (row == 0) {  
 20                     currentTimes = 0;  
 21                     int[] randomArray = buildRandomArray();  
 22                     for (int i = 0; i < 9; i++) {
 23                         cardsMap[0][i].setNum(randomArray[i]);
 24                     }
 25                 } else {  
 26                     int[] randomArray = buildRandomArray();
 27                     for (int col = 0; col < 9; col++) {  
 28                         if (currentTimes < 100) {  
 29                             if (!isCandidateNmbFound(cardsMap, randomArray, row, col)) {
 30                                 for (int i = 0; i < 9; i++) {
 31                                     cardsMap[row][i].setNum(0);
 32                                 } 
 33                                 row -= 1;  
 34                                 col = 8;
 35                             }  
 36                         } else {
 37                             row = -1;  
 38                             col = 8;  
 39                             initNumber();
 40                         }  
 41                     }  
 42                 }  
 43             }
 44     }
 45     
 46     private boolean isCandidateNmbFound(Card[][] cardMap, int[] randomArray, int row, int col) {  
 47         for (int i = 0; i < randomArray.length; i++) {
 48             cardMap[row][col].setNum(randomArray[i]); 
 49             if (isSame(row,col)) {  
 50                 return true;  
 51             }  
 52         }  
 53         return false;  
 54     }
 55     
 56     public int[] buildRandomArray(){
 57         currentTimes++;
 58         int[] randomArray = new int[9];
 59         for (int i = 0; i < 9; i++) {
 60             randomArray[i] = i + 1;
 61         }
 62         Random random = new Random();
 63         for (int i = 0; i < 100; i++) {
 64             int r1 = random.nextInt(9);
 65             int r2 = random.nextInt(9);
 66             int temp = randomArray[r1];
 67             randomArray[r1] = randomArray[r2];
 68             randomArray[r2] = temp;
 69         }
 70         return randomArray;
 71     }
 72     
 73     public void initNumber(){
 74         for (int y = 0; y < 9; y++) {
 75             for (int x = 0; x < 9; x++) {
 76                 cardsMap[x][y].setNum(0);
 77             }
 78         }
 79     }
 80 
 81     public boolean isSame(int x,int y){
 82         boolean iS = true;
 83         for (int yy = y,xx = 0; xx <9 ; xx++) {
 84             if (xx==x) {
 85                 continue;
 86             }else{
 87                 if (cardsMap[xx][yy].getNum()==cardsMap[x][yy].getNum()) {
 88                     iS = false;break;
 89                 }
 90             }
 91         }
 92         if(iS){
 93             for (int yy = 0,xx = x; yy <9 ; yy++) {
 94                 if (yy==y) {
 95                     continue;
 96                 }else{
 97                     if (cardsMap[xx][yy].getNum()==cardsMap[xx][y].getNum()) {
 98                         iS = false;break;
 99                     }
100                 }
101             }
102         }
103         if(iS){
104         F:for (int yy = (y/3)*3; yy < (y/3)*3+3; yy++) {
105             for (int xx = (x/3)*3; xx < (x/3)*3+3; xx++) {
106                 if ((xx==x)&&(yy==y)) {
107                     continue;
108                 }else{
109                     if (cardsMap[xx][yy].getNum()==cardsMap[x][y].getNum()) {
110                         iS = false;break F;
111                     }
112                 }
113             }
114         }
115         }
116         return iS;
117     }

 

生成效果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM