数独终盘的随机生成算法
数独,是源自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 }
生成效果: