0
点赞
收藏
分享

微信扫一扫

MATLAB入门项目——数独游戏的设计与实现及简易求解算法

唯米天空 2022-01-13 阅读 110

此项目适合作为MATLAB入门练习用,能够对MATLAB的部分功能(GUI,神经网络工具箱等)进一步的熟悉,和加深对于代码逐句解释优势的感受。文章改自本人课设报告,若有具体实现问题欢迎与我交流~

游戏框架:

效果一览:

运行程序后,进入开始界面:

点击开始后,选择难度梯度,梯度分为三种,来自于分别存储的数独数据(由于图像失真,界面略丑请忽视TAT):

 选择难度后,进入游戏界面:

点击开始将矩阵数据传递给GUI:

胡乱填几个数字进去,点击完成弹出提示框:

点击确定查看答案,则后台将调用函数解算矩阵:

解算过程:

自编写的解算代码框架:

    经测试,代码能够解算大多数数独,面对过难的数独可能出现内存不足的情况,理论上均可完成求解,因为代码实际上是使用一种稍微巧妙的穷举。

function sodu1 = bs(sodu1)
global can;
global i;
global can1;
global sodun;
global flag;
global sodua;
if i>=81 || flag == 1
    flag =1;
    sodua = sodu1;
    return;
end

if isempty(cell2mat(can(i)))%判断队列是否为空
    i = i + 1;
    bs(sodu1);
else
    t = cell2mat(can(i));%得到候选
    t1 = length(t);%得到候选矩阵长度
    c = 0;%计数
    for j = 1:t1
        c = c + 1;
        sodu1(i) = t(j);%预填充
        t2 = mod(i,9);
        if t2 == 0 
            t2 = 9;
        end
        if Check(t2,ceil(i/9),sodu1,t(j))%判断填充是否成功
            sodu1 = allsolve(sodu1);%add
            
            i = i + 1;
                
            bs(sodu1);%成功时递归
            if i>=81 || flag == 1
                    flag =1;
                    return;
            end
        else
            sodu1(i) = 0;%失败时,清楚填充内容
            can = deletecell(can,i,1);%在本次遍历中,删除数组内容 
        end
        if c == t1
            can(i)=can1(i);%回补当前位置候选列,使其不影响判断
            for j = i:81
            sodu1(j) = sodun(j);
            end
            i = i - 1;%回溯
            while length(cell2mat(can(i)))<=1
                can(i) = can1(i);%回溯的同时回补候选列
                sodu1(i) = sodun(i);%回溯的同时重置各位置
                i = i - 1;%寻找本次遍历中有多个候选列的节点
            end
            if length(cell2mat(can(i)))>1
                can = deletecell(can,i,1);%删除回溯位置首个元素
                sodu1(i) = sodun(i);%重置回溯点
            end
            bs(sodu1);%递归
        end
    end
end
end

     作者尚在入门学习阶段,有建议欢迎交流,有问题我都会尽力解答~

举报

相关推荐

0 条评论