Java 编写数独游戏 窗体程序 完整源码

今天为大家分享数独游戏的开发与制作,目前系统已经完成了初步功能,后续会进一步完善。整个系统界面漂亮,有完整得源码,希望大家可以喜欢。喜欢的帮忙点赞和关注。一起编程、一起进步

开发环境

开发语言为Java,开发环境Eclipse或者IDEA都可以。运行主程序,或者执行打开JAR文件即可以运行本程序。

系统框架

利用JDK自带的SWING框架开发,不需要安装第三方JAR包。纯窗体模式,直接运行Main文件即可以。同时带有详细得设计文档。

主要功能

游戏原理

数独(shù dú)是源自18世纪瑞士的一种数学游戏。是一种运用纸、笔进行演算的逻辑游戏。玩家需要根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫(3*3)内的数字均含1-9 。数独盘面是个九宫,每一宫又分为九个小格。在这八十一格中给出一定的已知数字和解题条件,利用逻辑和推理,在其他的空格上填入1-9的数字。使1-9每个数字在每一行、每一列和每一宫中都只出现一次,所以又称“九宫格”。

解题原理

摒除法:用数字去找单元内唯一可填空格,称为摒除法,数字可填唯一空格称为排除法 (Hidden Single)。

根据不同的作用范围,摒余解可分为下述三种:

数字可填唯一空格在「宫」单元称为宫排除(Hidden Single in Box),也称宫摒除法。

数字可填唯一空格在「行」单元称为行排除法(Hidden Single in Row),也称行摒除法。

数字可填唯一空格在「列」单元称为列排除法(Hidden Single in Column),也称列摒除法。

游戏主要功能

1 运行AppStart.java文件

2 程序出现数独游戏的面板

3 在橙色的面板地方单击下,会弹出一个3*3的小窗口,单击具体的数字,实现数字的回填

4 系统实时显示当前的时间和玩游戏的使用时间

5 程序分为N关,每关的模板不一样,需要补充的数字不一样,难度有所差异

运行效果

关键代码

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;
    }
}
  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计算机程序

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值