基于MATLAB的数字拼图游戏

1 运行效果 

3bcd7e968feb43faa42835bd048380a2.png

2 设计思路

将每一个按键设计成按钮,使用循环的方式生成按钮组,主要功能:

(1)随机打乱。防止产生死局。

(2)完成检测。

(3)计时显示。

3 程序代码

clear;close all;clc;

GUI();

function GUI()

    % 定义主界面
    Fig = figure('Position',[400,50,600,850],...% 界面位置、大小
        'NumberTitle','off',... % 关闭'figure 1'
        'Name','数字拼图游戏',...% 主界面命名
        'Units','normalized','MenuBar','none');% 相对位置、关闭工具栏
    
    % 定义网格区域(游戏界面)
    Pln = uipanel(Fig,'Position',[0.1,0.1,0.805,0.85]);
%     buttons = zeros(3,3);
    
    % 定义按钮
    count=1;
    for i=1:3
        for j=1:3
            buttons(count)=uicontrol(Pln,'Style', 'pushbutton',...
                'String', num2str(count),'FontSize',23,...
                'Position',[(j-1)*160,(3-i)*160,160,160]);
%             buttons(count).CData = imread("D:\photos\eason.jpg");
            count = count+1;
        end
    end
    buttons(9).String=[];

    buttons(9).CData=[];
    % 初始时间、初始计数值、开始标记
    MoveCount = 0;
    StartTime = 0; 

    % 定义每一个按钮的回调函数
    buttons(1).Callback = @MoveButton1;
    buttons(2).Callback = @MoveButton2;
    buttons(3).Callback = @MoveButton3;
    buttons(4).Callback = @MoveButton4;
    buttons(5).Callback = @MoveButton5;
    buttons(6).Callback = @MoveButton6;
    buttons(7).Callback = @MoveButton7;
    buttons(8).Callback = @MoveButton8;
    buttons(9).Callback = @MoveButton9;

    % 定义'游戏开始','重新开始'按钮
    StatButton = uicontrol(Pln,'Style','pushbutton','String','游戏开始','FontSize',16,...
        'Position',[80,600,160,60]);
    StatButton.Callback = @StartGame;
    ReStartButton = uicontrol(Pln,'Style','pushbutton','String','重新开始','FontSize',16,...
        'Position',[260,600,160,60]);
    ReStartButton.Callback = @RestartGame;
    % 定义计时、计数显示框
    TimeVal = uicontrol(Pln,'Style','edit','String','','Position',[90,500,140,50],'FontSize',16);
    NumbVal = uicontrol(Pln,'Style','edit','String','','Position',[250,500,140,50],'FontSize',16);
    uicontrol(Pln,'Style','text','String','时间:','Position',[120,550,80,40],'FontSize',16);
    uicontrol(Pln,'Style','text','String','移动步数:','Position',[270,550,100,40],'FontSize',16);
    % 创建定时器
    t = timer ('TimerFcn',{@TimeDisplay,TimeVal},'ExecutionMode','fixedRate','StartDelay',1);
    

    % 保存每一个按钮的初始位置 
    InitialPos=cell(1,9);
    for i=1:9
        InitialPos{i}=buttons(i).Position;
    end

    function StartGame(~,~)

        shuffbutton();
        TimeVal.String = '0 s';
        NumbVal.String = '';
        start(t);
        IsComplete();
    end

    % 每一个按钮的回调函数
    function MoveButton1(~,~)
        SwapPosition(buttons(1));
        IsComplete();
    end
    function MoveButton2(~,~)
        SwapPosition(buttons(2));
        IsComplete();
    end
    function MoveButton3(~,~)
        SwapPosition(buttons(3));
        IsComplete();
    end
    function MoveButton4(~,~)
        SwapPosition(buttons(4));
        IsComplete();
    end
    function MoveButton5(~,~)
        SwapPosition(buttons(5));
        IsComplete();
    end
    function MoveButton6(~,~)
        SwapPosition(buttons(6));
        IsComplete();
    end
    function MoveButton7(~,~)
        SwapPosition(buttons(7));
        IsComplete();
    end
    function MoveButton8(~,~)
        SwapPosition(buttons(8));
        IsComplete();
    end
    function MoveButton9(~,~)
        IsComplete();
    end


    % 打乱函数定义
    function shuffbutton(~,~)
        global EmptyButtonPos
        count=1;
        shuffpos = Stalemate();
        for i=shuffpos+1 % 解释 
            buttons(count).Position=cell2mat(InitialPos(i));
            count = count+1;
        end
        EmptyButtonPos = InitialPos(9);
    end


    % 判断是否完成
    function IsComplete(~,~)
        NewButtonPos = cell(1,9);
        for i=1:9
            NewButtonPos{i} = buttons(i).Position;
        end
        IsOrNo = isequal(NewButtonPos,InitialPos);
        NumbVal.String = num2str(MoveCount);
        % 游戏结束,计时结束
        if IsOrNo
            warndlg('恭喜你完成拼图!!!','数字拼图游戏');
            stop(t);
            TimeVal.String = [num2str(StartTime),'s'];
        end
    end
    
    function RestartGame(~,~)
        stop(t);
        shuffbutton();
        StartTime = 0;
        MoveCount = 0;
        TimeVal.String = '0 s';
        NumbVal.String = num2str(MoveCount);
        start(t);
    end
    % 交换位置
    function SwapPosition(butt)
        Pos = butt.Position;
        UpButton = Pos + [0 160 0 0];
        DownButton = Pos + [0 -160 0 0];
        LButton = Pos + [-160 0 0 0];
        Rbutton = Pos + [160 0 0 0];
        if UpButton==buttons(9).Position
            temp = Pos;
            butt.Position = buttons(9).Position;
            buttons(9).Position = temp;
            MoveCount = MoveCount + 1;
        end
        if DownButton==buttons(9).Position
            temp = Pos;
            butt.Position = buttons(9).Position;
            buttons(9).Position = temp;
            MoveCount = MoveCount + 1;
        end
        if LButton==buttons(9).Position
            temp = Pos;
            butt.Position = buttons(9).Position;
            buttons(9).Position = temp;
            MoveCount = MoveCount + 1;
        end
        if Rbutton==buttons(9).Position
            temp = Pos;
            butt.Position = buttons(9).Position;
            buttons(9).Position = temp;
            MoveCount = MoveCount + 1;
        end
    end
    
    function TimeDisplay(hObject,eventdata,x)
        StartTime = StartTime + 1;
        TimeVal.String = [num2str(StartTime),'s'];
    end

    % 存在死局,用此函数生成可以复原的序列
    function shuffpos = Stalemate()
        isok = 1;
        while isok
            shuffpos = abs(randperm(9)-9);
            yespos = [1:8,0];
            shuffCount = count_inversions(shuffpos);
            yesCount = count_inversions(yespos);
            if shuffCount == yesCount
                isok = 0;
            end
        end

        function inversions = count_inversions(state)
            n = length(state);
            inversions = 0;
            for i = 1:n-1
                for j = (i+1):n
                    if state(i) > state(j)
                        inversions = inversions + 1;
                    end
                end
            end
        end
    end
end

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值