matlab 华容道 全功能

头像都是上网找的,如有侵权,请联系删除!


游戏名称:华容道

实现工具:matlab

实现功能:华容道基本功能+五种开局模式+重新开始+关于+步数显示;所有功能符合逻辑并通过自测。

难点:兵的对角移动判断

实现思路:武将和兵都为按键型控件,移动通过鼠标按键按下的位置判断,过程中生成一个5*4的矩阵,用于游戏逻辑判断。

完成日期:2018.06.27




function huarongdao  %主函数

global everyHandle wjposition mode step stepHandle %全局变量 everyHandle为控件的句柄值,wjposition是控件的位置元胞数组,mode为游戏模式,step为步数,stepHandle为步数按钮句柄值

windowHandle = figure('Name','华容道','NumberTitle','off','MenuBar','none',...
    'ToolBar','none','Position',[650 350 420 560],'WindowButtonDownFcn',...
    @emptyClick,'Resize','off');    %emptyClick函数为鼠标按键按下事件函数
axes(windowHandle,'Position',[0 0 0 0])  %创建坐标系,用来检测鼠标按下位置
axis off  %  不显示坐标轴

mode = '横刀立马①'; %初始化游戏模式为横刀立马①
step = 0;  %初始化步数为0

wjposition = {[110 310 200 200],[10 310 100 200],[310 310 100 200],...%  横刀立马①模式下武将的初始位置  顺序为: {'曹操','张飞','赵云','关羽','马超','黄忠','兵A','兵B','兵C','兵D'};
    [110 210 200 100],[10 110 100 200],[310 110 100 200],...
    [10 10 100 100],[110 110 100 100],[210 110 100 100],[310 10 100 100]};
wjphoto = {imread('曹操.jpg'),imread('张飞.jpg'),imread('赵云.jpg'),...    % 载入武将的图片数据
    imread('关羽.jpg'),imread('马超.jpg'),imread('黄忠.jpg'),...
    imread('兵A.jpg'),imread('兵B.jpg'),imread('兵C.jpg'),imread('兵D.jpg'),};

for ix = 1:10
    uicontrol('parent',windowHandle,'Style','pushbutton',...
        'Position',wjposition{ix},'FontSize',30,'Callback',@checked,'CData',wjphoto{ix})  % 生成游戏界面控件
end
everyHandle = flip(findall(gcf,'Style','pushbutton'));   %找出游戏将兵的句柄值,并赋予everyHandle

stepHandle = uicontrol('parent',windowHandle,'Style','pushbutton',...
    'Position',[10 515 100 45],'String','当前步数','Fontsize',10);    %创建游戏步数显示按钮

option = {'选择开局','重新开始','关于'};

for ix = 0:2
    uicontrol('parent',windowHandle,'Style','pushbutton',...         %创建菜单选项
        'Position',[ix*100+110 515 100 45],'String',option{ix+1},...
        'Fontsize',13,'Callback',@optionArray)
end


end

function optionArray(hObject,event)  %选项回调函数
global everyHandle wjposition mode step stepHandle
switch get(hObject,'String')
    case '选择开局'
        str2 = {'屯兵东进','兵分三路','齐头并进','横刀立马②','横刀立马①'};
        mode = figure('Name','请选择开局模式','ToolBar','none',...
            'MenuBar','none','NumberTitle','off',...
            'Position',[1100 500 300 300]);
        for ix = 1:5
            uicontrol('parent',mode,'Style','pushbutton',...
                'Position',[50,(ix-1)*57+15,200,50],...
                'String',str2{ix},'FontSize',20,'Callback',@modeCallback)
        end
        
    case '重新开始'
        wjposition = modeFun(mode);
        for ix = 1:10
            set(everyHandle(ix),'Position',wjposition{ix})
        end
        step=0;
        set(stepHandle,'String','当前步数')
        thining(wjposition)
        
    case '关于'
        about = figure('Name','关于','ToolBar','none',...
            'MenuBar','none','NumberTitle','off',...
            'Position',[750 500 400 400]);
        aboutA= uicontrol('parent',about,'Style','text','position',[0 0 380 390]);
        aboutB= uicontrol('parent',about,'Style','text','position',[20 20 350 270]);
        
        text2={ '★★华容道是古老的中国民间益智游戏,其变化多端、百玩不厌。',...
            '★★通过移动各个棋子,帮助曹操从初始位置移到棋盘最下方中部,从出口逃走。',...
            '★★不允许跨越棋子,还要设法用最少的步数把曹操移到出口。',...
            '★★曹操逃出华容道的最大障碍是关羽,关羽立马华容道,一夫当关,万夫莫开。',...
            '★★关羽与曹操当然是解开这一游戏的关键。',...
            '★★四个刘备军兵是最灵活的,也最容易对付,如何发挥他们的作用也要充分考虑周全。','',...
            '程序版本:1.0','完成时间:2018年6月27日'};
        text1={'诗云:','曹瞒兵败走华容,','正与关公狭路逢。','只为当初恩义重,','放开金锁走蛟龙。'};
        
        [textx1,~]=textwrap(aboutA,text1);
        [textx2,~]=textwrap(aboutB,text2);
        
        set(aboutA,'String',textx1,'FontSize',10,'HorizontalAlignment','center')
        set(aboutB,'String',textx2,'FontSize',10,'HorizontalAlignment','left')
end

end

function modeCallback(hObject,event)  % 模式选择回调函数 {'屯兵东进','兵分三路','齐头并进','横刀立马②','横刀立马①'};
global everyHandle wjposition mode step stepHandle
mode = get(hObject,'String') ; % 更新当前选择模式
wjposition = modeFun(mode);  %将模式初识位置赋予wjposition

for ix = 1:10
    set(everyHandle(ix),'Position',wjposition{ix})  % 将模式初始位置值更新到控件上
end

step=0;
set(stepHandle,'String','当前步数')   % 更新步数

thining(wjposition)  %将最新的位置更新到5*4的矩阵中

end

function wjposition = modeFun(mode)  %模式位置初始函数

switch mode   %顺序为 {'曹操','张飞','赵云','关羽','马超','黄忠','兵A','兵B','兵C','兵D'};
    case '横刀立马①'
        wjposition = {[110 310 200 200],[10 310 100 200],[310 310 100 200],...
            [110 210 200 100],[10 110 100 200],[310 110 100 200],...
            [10 10 100 100],[110 110 100 100],[210 110 100 100],[310 10 100 100]};
    case '横刀立马②'
        wjposition = {[110 310 200 200],[10 310 100 200],[310 310 100 200],...
            [110 210 200 100],[10 10 100 200],[310 10 100 200],...
            [10 210 100 100],[110 110 100 100],[210 110 100 100],[310 210 100 100]};
    case '齐头并进'
        wjposition = {[110 310 200 200],[10 310 100 200],[310 310 100 200],...
            [110 110 200 100],[10 10 100 200],[310 10 100 200],...
            [10 210 100 100],[110 210 100 100],[210 210 100 100],[310 210 100 100]};
    case '兵分三路'
        wjposition = {[110 310 200 200],[10 210 100 200],[310 210 100 200],...
            [110 210 200 100],[10 10 100 200],[310 10 100 200],...
            [10 410 100 100],[110 110 100 100],[210 110 100 100],[310 410 100 100]};
    case '屯兵东进'
        wjposition = {[10 310 200 200],[210 310 100 200],[310 310 100 200],...
            [10 210 200 100],[10 10 100 200],[110 10 100 200],...
            [210 210 100 100],[310 210 100 100],[210 110 100 100],[310 110 100 100]};
end

end

function checked(hObject,event)  %按钮回调函数,用来确定当前摁下的是哪一个按钮
global wjHandle everyHandle wj
wjHandle = hObject;
for ix =1:10
    if everyHandle(ix) == wjHandle
        wj = ix;
        break
    end
end
end

function emptyClick(~,event) %选定按钮后,鼠标点击空白处的事件函数
global wjHandle wjposition oldPosition
oldax = thining(wjposition);
oldPosition = get(wjHandle,'Position');

mouseXY = get(gca,'CurrentPoint');  %%★★★★★★返回鼠标按下的位置值★★★★★★
mouseXY = mouseXY(1,1:2)-10;

if (1 < mouseXY(1) & mouseXY(1) < 399) & (1 < mouseXY(2) & mouseXY(2) < 499)   %判断鼠标按下位置是否超出范围
    
    nx = get(wjHandle,'Position');
    
    if nx(3)==100 & nx(4)==100   %兵的移动判断
        wjarray = thining(wjposition);
        yy = (nx(1)-10)/100+1;
        xx = 5-(nx(2)-10)/100;
        if mouseXY(1)-nx(1)>100  & mouseXY(2)-nx(2) >100    %兵的对角移动,原位置为(-1,-1)角
            if wjarray(xx-1,yy)
                set(wjHandle,'Position',[nx(1)+100 nx(2) nx(3) nx(4)])  %右移
            elseif wjarray(xx,yy+1)
                set(wjHandle,'Position',[nx(1) nx(2)+100 nx(3) nx(4)])  %上移
            end
            
        elseif mouseXY(1)-nx(1)<0  & mouseXY(2)-nx(2) >100   %兵的对角移动,原位置为(-1,1)角
            if wjarray(xx,yy-1)
                set(wjHandle,'Position',[nx(1) nx(2)+100 nx(3) nx(4)])  %上移
            elseif wjarray(xx-1,yy)
                set(wjHandle,'Position',[nx(1)-100 nx(2) nx(3) nx(4)])  %左移
            end
            
        elseif mouseXY(1)-nx(1)<0  & mouseXY(2)-nx(2)<0     %兵的对角移动,原位置为(1,1)角
            if wjarray(xx,yy-1)
                set(wjHandle,'Position',[nx(1) nx(2)-100 nx(3) nx(4)])  %下移
            elseif wjarray(xx+1,yy)
                set(wjHandle,'Position',[nx(1)-100 nx(2) nx(3) nx(4)])  %左移
            end
        elseif mouseXY(1)-nx(1)>100  & mouseXY(2)-nx(2)<0     %兵的对角移动,原位置为(-1,1)角
            if wjarray(xx,yy+1)
                set(wjHandle,'Position',[nx(1) nx(2)-100 nx(3) nx(4)])  %下移
            elseif wjarray(xx+1,yy)
                set(wjHandle,'Position',[nx(1)+100 nx(2) nx(3) nx(4)])  %右移
            end
        elseif mouseXY(1)-nx(1)<0 & mouseXY(1)-nx(1)>-200 & mouseXY(2)-nx(2) >0 & mouseXY(2)-nx(2) <100  %向左
            set(wjHandle,'Position',[nx(1)-100 nx(2) nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >100 & mouseXY(1)-nx(1) <300 & mouseXY(2)-nx(2)>0 & mouseXY(2)-nx(2)<100   %向右
            set(wjHandle,'Position',[nx(1)+100 nx(2) nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >0 & mouseXY(1)-nx(1) <100 & mouseXY(2)-nx(2)>100 & mouseXY(2)-nx(2)<300    %向上
            set(wjHandle,'Position',[nx(1) nx(2)+100 nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >0 & mouseXY(1)-nx(1) <100 & mouseXY(2)-nx(2)<0 & mouseXY(2)-nx(2)>-200     %向下
            set(wjHandle,'Position',[nx(1) nx(2)-100 nx(3) nx(4)])
        end
        
    elseif nx(3)==100 & nx(4)==200   %张飞、赵云、马超、黄忠移动判断
        if mouseXY(1)-nx(1) >0 & mouseXY(1)-nx(1) <100 & mouseXY(2)-nx(2)>200 & mouseXY(2)-nx(2)<400     %向上
            set(wjHandle,'Position',[nx(1) nx(2)+100 nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >0 & mouseXY(1)-nx(1)<100 & mouseXY(2)-nx(2)<0 & mouseXY(2)-nx(2)>-200    %向下
            set(wjHandle,'Position',[nx(1) nx(2)-100 nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >-100 & mouseXY(1)-nx(1) <0 & mouseXY(2)-nx(2)>0 & mouseXY(2)-nx(2)<200     %向左  *
            set(wjHandle,'Position',[nx(1)-100 nx(2) nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >100 & mouseXY(1)-nx(1) <200 & mouseXY(2)-nx(2)>0 & mouseXY(2)-nx(2)<200      %向右   *
            set(wjHandle,'Position',[nx(1)+100 nx(2) nx(3) nx(4)])
        end
        
    elseif nx(3)==200 & nx(4)==100   %关羽移动判断
        if mouseXY(1)-nx(1) >0 & mouseXY(1)-nx(1) <200 & mouseXY(2)-nx(2)>100 & mouseXY(2)-nx(2)<200     %向上  *
            set(wjHandle,'Position',[nx(1) nx(2)+100 nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >0 & mouseXY(1)-nx(1)<200 & mouseXY(2)-nx(2)<0 & mouseXY(2)-nx(2)>-100    %向下  *
            set(wjHandle,'Position',[nx(1) nx(2)-100 nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >-200 & mouseXY(1)-nx(1) <0 & mouseXY(2)-nx(2)>0 & mouseXY(2)-nx(2)<100     %向左
            set(wjHandle,'Position',[nx(1)-100 nx(2) nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >200 & mouseXY(1)-nx(1) <400 & mouseXY(2)-nx(2)>0 & mouseXY(2)-nx(2)<100      %向右
            set(wjHandle,'Position',[nx(1)+100 nx(2) nx(3) nx(4)])
        end
        
    elseif nx(3)==200 & nx(4)==200   %曹操移动判断
        if mouseXY(1)-nx(1) >0 & mouseXY(1)-nx(1) <200 & mouseXY(2)-nx(2)>200 & mouseXY(2)-nx(2)<300     %向上  *
            set(wjHandle,'Position',[nx(1) nx(2)+100 nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >0 & mouseXY(1)-nx(1)<200 & mouseXY(2)-nx(2)<0 & mouseXY(2)-nx(2)>-100    %向下  *
            set(wjHandle,'Position',[nx(1) nx(2)-100 nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >-100 & mouseXY(1)-nx(1) <0 & mouseXY(2)-nx(2)>0 & mouseXY(2)-nx(2)<200     %向左  *
            set(wjHandle,'Position',[nx(1)-100 nx(2) nx(3) nx(4)])
        elseif mouseXY(1)-nx(1) >200 & mouseXY(1)-nx(1) <300 & mouseXY(2)-nx(2)>0 & mouseXY(2)-nx(2)<200      %向右   *
            set(wjHandle,'Position',[nx(1)+100 nx(2) nx(3) nx(4)])
        end
    end
end
newposition(oldPosition,oldax)
end

function newposition(oldPosition,oldax) %确定新位置是否符合要求,不符合则返回前状态
global wjposition wjHandle wj step stepHandle
wjposition(wj)={get(wjHandle,'Position')};
ax = thining(wjposition);
if sum(ax(:)==0) ~= 2
    set(wjHandle,'Position',oldPosition)
    wjposition(wj)={get(wjHandle,'Position')};
else
    if isequal(ax,oldax)
    else
        step=step+1;
        set(stepHandle,'String',num2str(step))
        temporary = get(wjHandle,'Position');
        if temporary(1,3:4) == [200 200]
            if temporary(1:1:2) == [110 10]
                gameover()
            end
        end
        
    end
end
end

function ax = thining(wjposition) %将图形界面转换成一个5*4的数组,用来判断移动是否符合游戏规则
ax = zeros(5,4);
for ix = 1:10
    switch ix
        case 1
            caocao = wjposition{ix};
            yy = (caocao(1)-10)/100+1;
            xx = (caocao(2)-10)/100+1;
            ax(5-xx:6-xx,yy:yy+1) = [1,1;1,1];
            
        case {2,3,5,6}
            zhangfei = wjposition{ix};
            yy = (zhangfei(1)-10)/100+1;
            xx = (zhangfei(2)-10)/100+1;
            ax(5-xx:6-xx,yy) = [1;1];
            
        case 4
            guanyu = wjposition{ix};
            yy = (guanyu(1)-10)/100+1;
            xx = (guanyu(2)-10)/100+1;
            ax(6-xx,yy:yy+1) = [1,1];
            
        case {7,8,9,10}
            guanyu = wjposition{ix};
            yy = (guanyu(1)-10)/100+1;
            xx = (guanyu(2)-10)/100+1;
            ax(6-xx,yy) = [1];
            
        otherwise
            errordlg('程序存在BUG!','错误')
    end
end
end

    function gameover()
        global step
       errordlg(strcat('恭喜你通过了游戏,一共用了_',num2str(step),'_步。'),'游戏结束')
    end

猜你喜欢

转载自blog.csdn.net/weixin_42205310/article/details/80836206