数独游戏的算法实现
程序员文章站
2022-05-21 19:58:12
...
首先,数独游戏的界面是由9*9共81个方框组成,每个方框内填入1-9之间数字,部分方框已经填入了数字,玩家需要根据已有数字推测并填入空白方框。
如图所示:
数独游戏规则非常简单,满足一下三条规则:
- 横向上9个数字满足1-9不重复;
- 竖向上9个数字满足1-9不重复;
- 将大网格拆分为9个3*3的小网格,每个小网格内同样满足1-9不重复。
如果要制作一个数独游戏,首先需要生成一组完整的满足数独规则的数据。那么这里就来介绍一种简单的生成算法。
第一步,考虑到数组的规则和数字组成方式,我们先将数组划分为9个3*3的格网,用二维数组a[3][3]表示,每个格网内又有3*3个小方框,同样用二维数组表示b[3][3],那么整个数独数组由数组a和b组合后可以用一个四维数组表示c[3][3][3][3]。
第二步,由于每个3*3格网必须满足1-9不重复,那么首先采用随机方式生成第一个格网数组;
第三步,根据第一个格网,在横向上生成另外两个格网,根据数组规则,横向两个格网不能与第一个格网排列规则相同,此时需要对第一个网格数字进行排列组合,首先横向上顺序不能变化,只能在纵向上调整位置,以此生成另外两个格网,这样就完成了9个3*3格网第一行的排列;
第四步,对剩余格网的排列。剩余格网通过第一行已有格网,每一列参考第一列格网进行竖向上排列组合,同样可以生成另外两个格网,完成剩余三列的格网生成后,整个数独游戏的数字就全部组合完毕。
实现代码:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class CaculateSudokuNumbers {
int[][][][] arr;
private void initArr() {
arr = new int[3][3][3][3];
fillArr();
}
private void fillArr() {
creatFirstGrid(); // 创建第一个格网
createFirstLineXGrid(); // 创建第一行另外两个格网
createRestGrid(); //生成剩余格网
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.println(arr[i][j][0][0] + "," + arr[i][j][0][1] + "," + arr[i][j][0][2] + ","
+ arr[i][j][1][0] + "," + arr[i][j][1][1] + "," + arr[i][j][1][2] + "," + arr[i][j][2][0] + ","
+ arr[i][j][2][1] + "," + arr[i][j][2][2]);
}
}
}
private void creatFirstGrid() {
List<Integer> tempList = new ArrayList<>();
for (int i = 1; i <= 9; i++) {
tempList.add(i);
}
for (int i = 0; i < 9; i++) {
int size = tempList.size();
int x = i % 3;
int y = i / 3;
Random random = new Random();
int index = random.nextInt(size);
arr[0][0][y][x] = tempList.get(index);
tempList.remove(index);
}
}
private void createFirstLineXGrid() {
int[] arr1 = new int[] { 2, 0, 1 };
int[] arr2 = new int[] { 1, 2, 0 };
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int yIndex = arr1[i];
arr[0][1][i][j] = arr[0][0][yIndex][j];
}
}
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int yIndex = arr2[i];
arr[0][2][i][j] = arr[0][0][yIndex][j];
}
}
}
private void createRestGrid() {
int[] arr1 = new int[] { 2, 0, 1 };
int[] arr2 = new int[] { 1, 2, 0 };
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
int xIndex = arr1[j];
for (int k = 0; k < 3; k++) {
arr[1][i][k][j] = arr[0][i][k][xIndex];
}
}
for (int j = 0; j < 3; j++) {
int xIndex = arr2[j];
for (int k = 0; k < 3; k++) {
arr[2][i][k][j] = arr[0][i][k][xIndex];
}
}
}
}
public static void main(String[] args) {
new CaculateSudokuNumbers().initArr();
}
}