9*9“数独”小游戏

目录

1.目的

2.代码结构

1)APPStart.java

2)ShuduHelper.java

3)SelectNumFrame.java

4)ShuduCanvers.java

5)ShuduCell.java

6)ShuduMain.java

3.代码运行结果

​编辑

4.相关图片

1)背景图

 2)按钮

 3)图标

4)变身按钮


1.目的

       编写程序实现9*9“数独”小游戏,游戏中包含9个3×3格的小九宫格,并提供一定数量的数字。根据这些数字,利用逻辑和推理,在其它的空格上填入1到9的数字。每个数字在每个小九宫格内只能出现一次,每个数字在每行、每列也只能出现一次。每次游戏开始给出部分数字,根据给定数字进行推理填充剩余空格数据,并编写GUI界面实现游戏。

2.代码结构

1)APPStart.java

这个类的作用是启动数独应用程序。

package hlc.shudu.app;

import hlc.shudu.ui.ShuduMainFrame;

public class AppStart {

    /**
     * 主方法是Java应用程序的入口点。
     * @param args 一个用于接收命令行参数的字符串数组
     */
    public static void main(String[] args) {
        // 创建一个ShuduMainFrame类的实例,这是应用程序的主窗口。
        ShuduMainFrame mainFrame = new ShuduMainFrame();
        
        // 将mainFrame设置为可见,这将启动并显示数独应用程序的主窗口。
        mainFrame.setVisible(true);
    }

}

2)ShuduHelper.java

这个类通过随机选择位置并检查规则来生成一个有效的数独棋盘。

package hlc.shudu.src;

public class ShuduHelper {
    private static int[][] maps = new int[9][9]; // 定义一个名为ShuduHelper的公共类。

    private static int[] canPutSum = new int[9];
    static int[] used = new int[9];
    static boolean isOk = true;

    // 声明三个静态变量:
    // canPutSum:一个长度为9的一维数组,用来记录每一行中可以放置某个数字的位置数。
    // used:一个长度为9的一维数组,用来记录某个数字已经使用的位置。
    // isOk:一个布尔变量,用来标记棋盘是否成功生成。
    
    public static int[][] getMap() {
        do {
            isOk = true;
            initMaps();
        } while (!isOk);
        return maps;
    }
    // 定义一个公共静态方法getMap,用来生成并返回数独棋盘。
    // 通过调用initMaps方法初始化棋盘,如果isOk为false,则重新生成,直到生成成功。

    private static void initMaps() {
        for (int i = 0; i < 9; i++) {
            for (int j = 0; j < 9; j++) {
                maps[i][j] = -1;
            }
        }
        // 初始化maps数组,把所有位置设置为-1,表示空位。

        for (int num = 1; num <= 9; num++) {
            for (int i = 0; i < 9; i++) {
                used[i] = -1;
                canPutSum[i] = -1;
            }
            // 遍历数字1到9,并在每次循环开始时初始化used和canPutSum数组的元素为-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;
                    if (i > 0) {
                        if (used[i - 1] != -1) {
                            clearNum(i - 1, num);
                        }
                        i -= 2;
                        continue;
                    } else {
                        isOk = false;
                        return;
                    }
                } else {
                    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;

                        if (maps[ii][jj] == -1 && j != used[i] && isCanPut(ii, jj, num)) {
                            maps[ii][jj] = num;
                            used[i] = j;
                            canPutSum[i] -= 1;
                            flag = true;
                        }
                    }
                }
            }
        }
    }
    // 这个部分负责在数独棋盘中放置数字:
    // 检查canPutSum[i]是否为-1,如果是则调用getCanPutSum方法计算可以放置数字的位置数。
    // 如果某行中只有一个位置可以放置数字,则将used[i]设置为-1。
    // 如果没有位置可以放置数字且当前行不为第一行,则调用clearNum方法清除上一行的数字并重新尝试。
    // 在找到可以放置的位置后,将数字放置在该位置,并更新used和canPutSum。

    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;
            }
        }
    }
    // 定义clearNum方法,清除某行中指定的数字。

    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;
    }
    // 定义getCanPutSum方法,计算并返回某行中可以放置指定数字的位置数。

    private static boolean isCanPut(int ii, int jj, int num) {
        for (int i = 0; i < 9; i++) {
            if (maps[ii][i] == num) {
                return false;
            }
            if (maps[i][jj] == num) {
                return false;
            }
        }
        return true;
    }
}

3)SelectNumFrame.java

这个类创建了一个自定义的对话框,用于数独游戏中选择数字。

package hlc.shudu.ui;

import javax.swing.*;
import java.awt.*;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class SelectNumFrame extends JDialog implements MouseListener {
//定义一个名为SelectNumFrame的公共类,继承自JDialog并实现MouseListener接口。
//这个类是一个对话框,能够响应鼠标事件。
	p
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值