Matlab入门3 GUI图形界面编程(连连看)

赞赏码 & 联系方式 & 个人闲话

配套课件可访问https://github.com/BIMK/MATLAB下载,是安徽大学Matlab本科教学课件,逻辑清晰,简洁明了,颇为实用,用来入门再好不过(机器学习方向)。

本系列博文是课后练习的个人解答,通过几个小实验展示matlab基本语法和技巧。接触Matlab也有几年了,略有心得,分享给大家。

 

【实验名称】GUI图形界面编程(连连看)

 

【实验目的】

1. 熟悉matlab图形界面编程的基本方法

2. 掌握基本的非可视化GUI编程语法

3. 掌握回调函数的使用方法

 

【实验内容】

1. 编写一个连连看游戏程序。

2. 两个数字相同且可通过三条或以内直线连接(不经过其它方格)的两个方格,可同时选中并消除。

3. 当有两个按钮被按下时,判断它们是否可连接;如果可连接则消除它们,否则取消选中它们

垂直判断:遍历每个红色的方格。如下图所示,每个红色方格可唯一决定一条由起点经过该方格到终点的最短路径;判断该路径上是否存在障碍即可。

水平判断:遍历每个红色的方格。如下图所示,每个红色方格可唯一决定一条由起点经过该方格到终点的最短路径;判断该路径上是否存在障碍即可。

代码(详见注释)

function task3()
close all;
global M;
global judge;
M = ones(12,12);
M([1,end],:) = 0;
M(:,[1,end]) = 0;
judge = [];
fig = figure('MenuBar','none','ToolBar','none','NumberTitle','off','Position',[0,0,500,500]);
movegui(fig,'center');
for i = 1:10
    for j = 1:10
        h(i,j) = uicontrol('style','togglebutton','Units','Normalized',...
                           'Position',[(i-1)/10,(j-1)/10,0.1,0.1],...
                           'FontSize',12);
        h(i,j).String = num2str(randi([0,9]));
        h(i,j).Callback = @(~,~)link(h,i,j);
    end
end
for i = 1:10
    for j = 1:10
        h(i,j).Callback = @(~,~)link(h,i,j);
    end
end
end
% 回调函数
function link(h,i,j)
global M;
global judge;
% 若上步已经处理完毕,恢复按钮状态
if size(judge,1) == 2
    h(judge(1,2),judge(1,1)).Value = 0;
    h(judge(2,2),judge(2,1)).Value = 0;
    judge = [];
end
% 如果按下且不是重复点击则存入if h(i,j).Value && (size(judge,1) == 0 || (size(judge,1) == 1 && ~(judge(1,1) == j && judge(1,2) == i)))
    judge = [judge;j,i,str2double(h(i,j).String)];% 注意行列顺序
% 若取消已存入按钮则取消
elseif ~h(i,j).Value && (size(judge,1) == 1 && ~(judge(1,1) == j && judge(1,2) == i))
    h(judge(1,2),judge(1,1)).Value = 0;
    judge = [];
end
% 如果已经按了2个按钮
if size(judge,1) == 2
    % 坐标变换
    judge(:,1) = 12 - judge(:,1);
    judge(:,2) = judge(:,2) + 1;
    flag = 0;
    if judge(1,3) == judge(2,3)
        M(judge(1,1),judge(1,2)) = 0;
        M(judge(2,1),judge(2,2)) = 0;
        for k = 1:12
            %垂直判断
            if  sum(M(min([k,judge(1,1)]):max([k,judge(1,1)]),judge(1,2))) + ...
                sum(M(k,min([judge(1,2),judge(2,2)]):max([judge(1,2),judge(2,2)]))) + ...
                sum(M(min([k,judge(2,1)]):max([k,judge(2,1)]),judge(2,2))) == 0
                flag = 1;
                break;
            end
            %水平判断
            if  sum(M(judge(1,1),min([k,judge(1,2)]):max([k,judge(1,2)]))) + ...
                sum(M(min([judge(1,1),judge(2,1)]):max([judge(1,1),judge(2,1)]),k)) + ...
                sum(M(judge(2,1),min([k,judge(2,2)]):max([k,judge(2,2)]))) == 0
                flag = 1;
                break;
            end
        end
    end
    % 若不消除,Map恢复
    if flag == 0
        M(judge(1,1),judge(1,2)) = 1;
        M(judge(2,1),judge(2,2)) = 1;
    end
    % 坐标反变换
    judge(:,1) = 12 - judge(:,1);
    judge(:,2) = judge(:,2) - 1;
    % 若消除,隐藏按钮
    if flag == 1
        h(judge(1,2),judge(1,1)).Visible = 'off';
        h(judge(2,2),judge(2,1)).Visible = 'off';
    end
end
end

运行结果

Matlab入门3 GUI图形界面编程(连连看)_第1张图片  Matlab入门3 GUI图形界面编程(连连看)_第2张图片

Matlab入门3 GUI图形界面编程(连连看)_第3张图片  Matlab入门3 GUI图形界面编程(连连看)_第4张图片

 

总结

实验难度总体不大,有些细节需注意如按钮坐标系和Matlab矩阵坐标系不同需要转换,单个双击自消等小bug。Matlab默认可以显示点中多个按钮,但考虑到连连看本身是两两匹配的,所以修改成同时只能选中两个按钮。此外,写垂直和水平判断时需细心,比较容易出错。

你可能感兴趣的:(Matlab入门,matlab)