【游戏】基于matlab国际象棋【含Matlab源码 498期】

一、简介

基于matlab国际象棋

二、源代码

function mychess()

%clear
%close all

global Grid_n Grid_w Grid_h Board BoardWhite chess_x chess_y Whowin

Grid_n=8;
Grid_w=60;
Grid_h=59;

x_start=-70;
y_start=100;

x_back=-70;
y_back=150;

x_exit=-70;
y_exit=200;

font_w=60;
font_h=20;

Board=zeros(Grid_n*Grid_h,Grid_n*Grid_w,3);
BoardWhite=255*ones(Grid_n*Grid_h,Grid_n*Grid_w,3);
nRowNum =Grid_n;
nColNum =Grid_n;


chess_name = ['r','n','b','q','k','p';'R','N','B','Q','K','P'];
chess_name_back = chess_name;

chess_type = [1 2 3 4 5 3 2 1 6 6 6 6 6 6 6 6;
              1 2 3 4 5 3 2 1 6 6 6 6 6 6 6 6];%各方16棋子在chess_name中的序号
chess_type_back =chess_type;
          
 exist_flag=[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1;
             1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1];%被杀掉则相应位置置0
 exist_flag_back=exist_flag;

KingBus_flag=[1;1];%1表示还未王车易位      
KingBus_flag_back=KingBus_flag;    

Whowin=0;
Whowin_back=0;

machine_turn=2;%默认计算机为黑棋

fig=zeros(2,16,Grid_h,Grid_w,3);
figwhite=255*ones(Grid_h,Grid_w,3);
figblack=128*ones(Grid_h,Grid_w,3);

% global variables
chess_x = -ones(2,16);%32个棋子的横坐标
chess_x_back=chess_x;
chess_y = -ones(2,16);%32个棋子的纵坐标
chess_y_back=chess_y;
pos_chess = zeros(nRowNum,nColNum);%棋盘矩阵
pos_chess_back=pos_chess;

cur_turn = 1;
cur_turn_back=cur_turn ; 
cur_cid = 0;
cur_cid_back=cur_cid;

PP_first_x=-1;
PP_first_x_back=PP_first_x;
PP_first_y=-1;%兵第一次跳了两格到了PP_first
PP_first_y_back=PP_first_y;

PP_flag=0;%0 清楚PP_first,1 不清除PP_first
PP_flag_back=PP_flag;

function Store()
chess_name_back = chess_name;
chess_type_back =chess_type;
exist_flag_back=exist_flag;
KingBus_flag_back=KingBus_flag;    
Whowin_back=Whowin;
chess_x_back=chess_x;
chess_y_back=chess_y;
pos_chess_back=pos_chess;
cur_turn_back=cur_turn ; 
cur_cid_back=cur_cid;
PP_first_x_back=PP_first_x;
PP_first_y_back=PP_first_y;
PP_flag_back=PP_flag;
end


function BackStep()
chess_name=chess_name_back ;
chess_type=chess_type_back;
exist_flag=exist_flag_back;
KingBus_flag=KingBus_flag_back;    
Whowin=Whowin_back;
chess_x=chess_x_back;
chess_y=chess_y_back;
pos_chess=pos_chess_back;
cur_turn=cur_turn_back; 
cur_cid=cur_cid_back;
PP_first_x=PP_first_x_back;
PP_first_y=PP_first_y_back;
PP_flag=PP_flag_back;
Init_Image();%更新图像库
end


figure(1)
set(1,'WindowButtonDownFcn',@OnWindowButtonDown);

 set(1,'name','白方先请');%设置标题
 InitializeChessPosition();
 Draw();
function Init_Image()
for i=1:2
    for j=1:16
        if i==1
filename=['images\basic\','120px-Chess_tile_',chess_name(1,chess_type(1,j)),'l','.png'];
%filename=['images\basic\','120px-Chess_tile_','q','l','.png'];

        else
% filename=['images\basic\','120px-Chess_tile_','k','l','.png'];

filename=['images\basic\','120px-Chess_tile_',chess_name(1,chess_type(2,j)),'d','.png'];
        end

fig(i,j,1:Grid_h,1:Grid_w,1:3)=imresize(imread(filename),[Grid_h,Grid_w]);%转换图像大小
    end
end


end


 function InitializeChessPosition()
        
    Whowin=0;
    cur_turn = 1;
    cur_cid = 0;
    
    chess_type = [1 2 3 4 5 3 2 1 6 6 6 6 6 6 6 6;
                 1 2 3 4 5 3 2 1 6 6 6 6 6 6 6 6];%各方16棋子在chess_name中的序号
          
    Init_Image();%更新图像库
    
    KingBus_flag=[1;1];%1表示还未王车易位   
    
    chess_x(:,1:8) = [1:8;1:8]; %车马象士帅 横坐标初始化
    chess_x(:,9:16) =[1:8;1:8]; %炮 炮横坐标初始化
    
    chess_y(:,1:8) = [ones(1,8);8*ones(1,8)];%纵坐标初始化
    chess_y(:,9:16) =[2*ones(1,8);7*ones(1,8)];%纵坐标初始化
    
    pos_chess(1,:) = [1:8];  %棋盘上的棋子 车马象士帅(将)士象马车 
    pos_chess(2,:) = [1:8]+8;
     
    pos_chess(3,:) = zeros(1,8);
    pos_chess(4,:) = zeros(1,8);
    pos_chess(5,:) = zeros(1,8);
    pos_chess(6,:) = zeros(1,8);
            
    pos_chess(nRowNum,:) =[1:8]+16;
    pos_chess(nRowNum-1,:) =[1:8]+8+16;
 
%     disp('棋盘初始化执行了')
%     pos_chess

    Store();%备份一下
    end

    %-------------------
    function OnWindowButtonDown(src,evnt)
        
    pt = get(gca,'CurrentPoint');
    x = round(pt(1,1));
    y = round(pt(1,2));
 %%%%%%%%%%%%%%%%%%%点击了左侧菜单
    if abs(y-y_start)<font_h/2 &&abs(x_start+font_w/2-x)<font_w/2
        disp('开始点击了')
         InitializeChessPosition();
         Draw();
        return
    end
    
    if abs(y-y_back)<font_h/2 &&abs(x_back+font_w/2-x)<font_w/2
        disp('悔棋点击了')
        BackStep();%执行了悔棋函数
        Draw();
        %%%%%%%%%%%%%%%%%%暂时还未考虑
        
        return
    end
    
    if abs(y-y_exit)<font_h/2 &&abs(x_exit+font_w/2-x)<font_w/2
        disp('退出点击了')
        close all
        return
    end
    
    
   x=round(0.5+x/Grid_w);
   y=round(0.5+y/Grid_h);
    
    if  x<1 || x>nColNum || y<1 || y>nRowNum 
        return
    end
    cc = pos_chess(y,x)%获取当前鼠标点击处的棋子序号1-32
   
    if cc~=0
        ct = ceil(cc/16);%取整 取大的
        cc = mod(cc,16);%取余
        if cc == 0
            cc = 16;
        end
    end
    

    if cur_cid==0  %还没有棋子被选中,则把鼠标点击处的棋子选中
        if cc~=0% chess clicked
            if ct==cur_turn
                cur_cid = cc
           %     set(hText(cur_turn,cur_cid),'BackgroundColor',[.3 .5 .1]);
            end
        end
    else% have current chess%点击的就是已经选中的棋子,没有变化
        if cc~=0% chess clicked
             if cc==cur_cid && ct==cur_turn% no change
                 return
             end
            if ct==cur_turn% change chess %选中了已方另一个棋子
         %       set(hText(cur_turn,cur_cid),'BackgroundColor','none');
                cur_cid = cc;
          %      set(hText(cur_turn,cur_cid),'BackgroundColor',[.3 .5 .1]);
            else %选中的是对方的一个棋子
                % kill
                 Store();%备份一下
                if CanMove(x,y,1)==1 %杀掉棋子
                    KillChess(ct,cc);
                 end
            end
        else% no chess clicked, go there%把当前棋子移动到点击的空位置
            if CanMove(x,y,0)==1
%                 disp('move之前')
%                 x
%                 y
                Store();%备份一下
                MoveChess(x,y);
              ChangeTurn();%轮到另一方了
            end
        end
    end
    
        Draw();%重新绘制所有界面
     
   CheckWin();%检测有没有谁赢了
      
     if cur_turn==machine_turn
         
     MachinePlay();
     Draw();
     
     CheckWin();%检测有没有谁赢了,并且有没有兵到达对方底线
     
     end
     
     
    end
  

    function flag=Jump(xfrom,yfrom,xto,yto) 
         
        flag=1;%默认没有挡道棋子
        %%%%%不能越子    
             if xto>xfrom 
                xdelta=1;
             else if xto==xfrom
                   xdelta=0;
                 else
                xdelta=-1;
                 end
             end
                
             if yto>yfrom 
                ydelta=1;
             else if yto==yfrom
                     ydelta=0;
                 else
                ydelta=-1;  
                 end
             end
       
           xtemp=xfrom;
           ytemp=yfrom;
             
             while(xtemp~=xto || ytemp~=yto)
                 if(xtemp~=xto)
                 xtemp=xtemp+xdelta;
                 end
                  if(ytemp~=yto)
                 ytemp=ytemp+ydelta;
                  end
%                       pos_chess
%                          ytemp
%                         xtemp
                        
                  if (xtemp~=xto || ytemp~=yto)%%%%最终到达的位置不用检验不然没法吃子
                 if pos_chess(ytemp,xtemp)~=0
                         
                        flag=0;
                        break;
                        
                 end
                        end
             end
    end

function CheckWin()%检测有没有谁赢了,并且有没有兵到达对方底线
          if Whowin==1
   msgbox(['白方获胜!'], '象棋', 'modal');
     else
     if Whowin==2
   msgbox(['黑方获胜!'], '象棋', 'modal');          
     end
     end
     
     if Whowin==0 % 棋局还在进行
    
       for i=1:8
           
           if pos_chess(1,i)>24 && chess_type(2,pos_chess(1,i)-16)==6 %黑兵在白方底线
              
               answer = inputdlg('输入数值: 后 4,象 3,马 2,车 1 . ','对兵进行升级',1,{'4'})
                             
               switch cell2mat(answer(1))
                   case '4'
                      % disp('后')
                     
                       chess_type(2,pos_chess(1,i)-16)=4;
                       
                   case '3'
                     %  disp('象')
                       
                        chess_type(2,pos_chess(1,i)-16)=3;
                       
                   case '2'
                     %  disp('马')
                        chess_type(2,pos_chess(1,i)-16)=2;
                   case '1'
                    %   disp('车')
                      chess_type(2,pos_chess(1,i)-16)=1;
               end
               
               Init_Image();%更新图像库
               Draw();
               break;
               
           else 
                if  8<pos_chess(8,i)&&pos_chess(8,i)<=16 && chess_type(1,pos_chess(8,i))==6 %白兵在黑方底线
              
               answer = inputdlg('输入数值: 后 4,象 3,马 2,车 1 . ','对兵进行升级',1,{'4'})
                             
               switch cell2mat(answer(1))
                   case '4'
                      % disp('后')                     
                       chess_type(1,pos_chess(8,i))=4;
                   case '3'
                     %  disp('象')
                        chess_type(1,pos_chess(8,i))=3;
                   case '2'
                     %  disp('马')
                        chess_type(1,pos_chess(8,i))=2;
                   case '1'
                    %   disp('车')
                      chess_type(1,pos_chess(8,i))=1;
               end
               
               Init_Image();%更新图像库
               Draw();
               break
                end
           end

三、运行结果

【游戏】基于matlab国际象棋【含Matlab源码 498期】

四、备注

版本:2014a
完整代码或代写加1564658423

上一篇:手把手教你ASP.NET Core:使用Entity Framework Core进行增删改查


下一篇:几行代码实现简单的网络象棋游戏,看看Java大牛是怎么做到的?