之前學習javascript時用javascript寫過一個數獨游戲,最近看了一點java的內容,于是就心血來潮想搞一個java版的數獨游戲。
現在將全部代碼分享出來和大家學習交流,當然代碼中有著各種各樣的問題和不足之處,望各位朋友批評指點。
以下是生成數獨地圖的核心算法,算法不是很好,也是之前參考過網上的一些思想:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
package hlc.shudu.src; /* * 數獨的幫助類,里面提供數據所需的所有算法 */ public class ShuduHelper { //數獨地圖數組 private static int[][] maps = new int[9][9]; //每個小九宮格可放置位置的數 private static int[] canPutSum = new int[9]; //用來存儲之前放置過的位置 static int[] used = new int[9]; //是否已經完成地圖的生成 static boolean isOk = true; /* * 得到數獨地圖數組 */ public static int[][] getMap() { //判斷是否已經完成地圖的生成,要是沒有完成就重新生成。 //從這里就可以看出算法還有待優化,如果回溯的好的話就一直可以通過回溯來重新生成,而這里是通過重新執行生成算法來重新生成。希望感興趣的朋友可以去實現以下。 do{ isOk = true; initMaps(); }while(!isOk); return maps; } /* * 初始化maps */ private static void initMaps() { // 初始化地圖數組中沒有填入任何數字 for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { maps[i][j] = -1; } } // 依次填入1~9 for (int num = 1; num <= 9; num++) { for (int i = 0; i < 9; i++) { used[i] = -1; canPutSum[i] = -1; } // 遍歷大九宮格中的每個小九宮格 for (int i = 0; i < 9; i++) { if (canPutSum[i]==-1) { canPutSum[i] = getCanPutSum(i, num); } if (canPutSum[i]==1) { used[i] = -1; } if (canPutSum[i] == 0) { canPutSum[i] = -1; used[i] = -1; // 如果當前小九宮格中不能放入數字num,則回到前一個小九宮格 if (i > 0) { // 將前一個九宮格中放num的位置清空 if (used[i-1]!=-1) { //maps[(int) (Math.floor(used[i-1]/3)+Math.floor((i-1)/3)*3)][used[i-1]%3+((i-1)%3)*3]=-1; clearNum(i - 1, num); } // i回退一個,因為等會for循環灰給i加一,所以這里減2 i -= 2; continue; } else { isOk = false; return; } } else { // 將num放入當前小九宮格中 boolean flag = false; while (!flag) { int j = (int) (Math.random() * 9); // 當前小方格橫坐標 int ii = (i / 3) * 3 + j / 3; // 當前小方格縱坐標 int jj = (i % 3) * 3 + j % 3; //System.out.println("num:"+num+"\tii:"+ii+"\tjj:"+jj); // 如果可以放置num則放置 if (maps[ii][jj] == -1 && j!=used[i] && isCanPut(ii, jj, num)) { maps[ii][jj] = num; used[i] = j; canPutSum[i] -= 1; flag = true; } } } } } } /* * 清空第i個小九宮格中的num */ private static void clearNum(int i, int num) { for (int j = 0; j < 9; j++) { // 當前小方格橫坐標 int ii = (i / 3) * 3 + j / 3; // 當前小方格縱坐標 int jj = (i % 3) * 3 + j % 3; // 判斷當前小方格是否可以放置 if (maps[ii][jj] == num) { maps[ii][jj] = -1; } } } /* * 得到當前小九宮格可以放入數字num的位置數目 */ private static int getCanPutSum(int i, int num) { int sum = 0; // 遍歷小九宮格 for (int j = 0; j < 9; j++) { // 當前小方格橫坐標 int ii = (i / 3) * 3 + j / 3; // 當前小方格縱坐標 int jj = i % 3 * 3 + j % 3; // 判斷當前小方格是否可以放置 if (maps[ii][jj] == -1 && isCanPut(ii, jj, num)) { ++sum; } } return sum; } /* * 指定橫縱坐標點是否可以放置num */ private static boolean isCanPut( int ii, int jj, int num) { // 判斷指定坐標點的同行或同列是否有相同數字,要是有則為false for ( int i = 0 ; i < 9 ; i++) { if (maps[ii][i] == num) { return false ; } if (maps[i][jj] == num) { return false ; } } return true ; } } |
完整程序包可在GitHub上下載:https://github.com/houlongchao/s
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://blog.csdn.net/da_keng/article/details/47778921