现在的位置: 首页 > 编程语言 > 正文

MATLAB实现五子棋游戏(双人对战、可悔棋)

2020年02月14日 编程语言 ⁄ 共 13576字 ⁄ 字号 评论关闭

本文实例为大家分享了MATLAB实现五子棋游戏的具体代码,供大家参考,具体内容如下

程序介绍:

1、此游戏只可用于双人对战。

2、棋盘颜色、棋盘格数、棋子颜色等参数均可自由设置

3、鼠标点击非棋盘区域可悔棋。

一、游戏界面

二、主程序及函数

1、主程序

%Author:LeiZhen%Date:2018-03-12%此程序只下五子棋,并判断胜负关系clear all;clc%定义颜色Color_QiPanBack=[135,206,255];Color_ChessLine=[100,100,100];%获胜连子数Num_Victory=5;Dpixel=33;NumCell=14;%棋盘格的行或列数Wid_edge=18;[M_QiPan,xcol_ChessLine,yrow_ChessLine]=QiPan(NumCell,Dpixel,Wid_edge,Color_QiPanBack,Color_ChessLine);imshow(M_QiPan);set (gcf,'Position',[600,45,625,625]);set (gca,'Position',[0,0,1,1]);hold on,%棋半径radius_Chess=15;M_LuoZi=zeros(NumCell+1,NumCell+1,2);VictoryB=0;VictoryW=0;StateB=1;StateW=2;NumChess=0;for i=1:(NumCell+1)^2 [x_col_Chess, y_row_Chess]=ginput_pointer(1); %获得距离鼠标点击点最近的下棋点的坐标,并保证点击的下棋点在棋盘内 if x_col_Chess<max(xcol_ChessLine)+Dpixel/2&&x_col_Chess>min(xcol_ChessLine)-Dpixel/2&&y_row_Chess<max(yrow_ChessLine)+Dpixel/2&&y_row_Chess>min(yrow_ChessLine)-Dpixel/2 for x_i=xcol_ChessLine if abs(x_col_Chess-x_i)<Dpixel/2; x_col_Chess=x_i; end end for y_i=yrow_ChessLine if abs(y_row_Chess-y_i)<Dpixel/2; y_row_Chess=y_i; end end %点击悔棋区(棋盘外的区域)悔棋 else [x_col_LuoZi_old,y_row_LuoZi_old]=find(M_LuoZi(:,:,2)==max(max(M_LuoZi(:,:,2)))); x_col_Chess_old=(x_col_LuoZi_old-1)*Dpixel+Wid_edge+1; y_row_Chess_old=(y_row_LuoZi_old-1)*Dpixel+Wid_edge+1; if NumChess>=1 M_QiPan=Chess(M_QiPan,x_col_Chess_old,y_row_Chess_old,radius_Chess,3,Wid_edge,Dpixel,Color_QiPanBack,Color_ChessLine); imshow(M_QiPan); NumChess=NumChess-1; M_LuoZi(x_col_LuoZi_old,y_row_LuoZi_old,1)=0; M_LuoZi(x_col_LuoZi_old,y_row_LuoZi_old,2)=0; end continue; end %落子并防止重复在同一个下棋点落子 x_col_LuoZi=(x_col_Chess-Wid_edge-1)/Dpixel+1; y_row_LuoZi=(y_row_Chess-Wid_edge-1)/Dpixel+1; if M_LuoZi(x_col_LuoZi,y_row_LuoZi,1)==0 NumChess=NumChess+1; M_LuoZi(x_col_LuoZi,y_row_LuoZi,2)=NumChess; if mod(NumChess,2)==1 M_QiPan=Chess(M_QiPan,x_col_Chess,y_row_Chess,radius_Chess,1,Wid_edge,Dpixel,Color_QiPanBack,Color_ChessLine); imshow(M_QiPan); M_LuoZi(x_col_LuoZi,y_row_LuoZi,1)=StateB; %落子为黑棋 VictoryB=Victory_Judge(M_LuoZi,x_col_LuoZi,y_row_LuoZi,StateB); elseif mod(NumChess,2)==0 M_QiPan=Chess(M_QiPan,x_col_Chess,y_row_Chess,radius_Chess,2,Wid_edge,Dpixel,Color_QiPanBack,Color_ChessLine); imshow(M_QiPan); M_LuoZi(x_col_LuoZi,y_row_LuoZi,1)=StateW; %落子为白棋 VictoryW=Victory_Judge(M_LuoZi,x_col_LuoZi,y_row_LuoZi,StateW); end end %显示获胜信息 if VictoryB==1 %普通对话框 h=dialog('name','对局结束','position',[500 350 250 100]); uicontrol('parent',h,'style','text','string','黑棋获胜!','position',[35 35 200 50],'fontsize',30); uicontrol('parent',h,'style','pushbutton','position',[150 5 80 30],'fontsize',20,'string','确定','callback','delete(gcbf)'); break; elseif VictoryW==1 %普通对话框 h=dialog('name','对局结束','position',[500 350 250 100]); uicontrol('parent',h,'style','text','string','白棋获胜!','position',[35 35 200 50],'fontsize',30); uicontrol('parent',h,'style','pushbutton','position',[150 5 80 30],'fontsize',20,'string','确定','callback','delete(gcbf)'); break; endend

2、画棋盘函数

%Author:LeiZhen%Date:2018-03-12function [M_QiPan, xcol_ChessLine,yrow_ChessLine]=QiPan(NumCell, Dpixel, Wid_edge,Color_QiPanBack,Color_ChessLine)%此程序为画五子棋盘的程序%NumCell为棋盘格数%Dpixel为相邻棋盘线间的像素间隔%Wid_edge为棋盘边缘的像素宽度%Color_QiPanBack为棋盘背景颜色%Color_ChessLine为棋盘线的颜色%M_QiPan为棋盘矩阵%xcol_ChessLine为棋盘列线%yrow_ChessLine为棋盘行线NumSum=1+Dpixel*NumCell+Wid_edge*2;xcol_ChessLine=Wid_edge+1:Dpixel:NumSum-Wid_edge;%列yrow_ChessLine=Wid_edge+1:Dpixel:NumSum-Wid_edge;%行M_QiPan=uint8(ones(NumSum,NumSum,3));M_QiPan(:,:,1)=M_QiPan(:,:,1)*Color_QiPanBack(1);M_QiPan(:,:,2)=M_QiPan(:,:,2)*Color_QiPanBack(2);M_QiPan(:,:,3)=M_QiPan(:,:,3)*Color_QiPanBack(3);%画棋盘线for i=xcol_ChessLine M_QiPan(i,Wid_edge+1:NumSum-Wid_edge,:)=ones(NumSum-2*Wid_edge,1)*Color_ChessLine;endfor j=yrow_ChessLine M_QiPan(Wid_edge+1:NumSum-Wid_edge,j,:)=ones(NumSum-2*Wid_edge,1)*Color_ChessLine;end%画9个小圆点radius_Dot=5;P1=Wid_edge+1+Dpixel*3:Dpixel*(NumCell/2-3):Wid_edge+1+Dpixel*(NumCell-3);for ti=P1 for tj=P1 for Num=ti-radius_Dot:ti+radius_Dot; for j=tj-radius_Dot:tj+radius_Dot; if (Num-ti)^2+(j-tj)^2<radius_Dot^2 M_QiPan(Num,j,:)=Color_ChessLine; end end end endendend

3、下棋或悔棋函数

%Author:LeiZhen%Date:2018-03-12function M_QiPan=Chess(M_QiPan,x_col_Chess,y_row_Chess,radius_Chess,BorW,Wid_edge,Dpixel,Color_QiPanBack,Color_ChessLine)%此程序下棋或者悔棋%M_QiPan为棋盘矩阵%xcol_ChessLine为棋盘列线%yrow_ChessLine为棋盘行线%radius_Chess为棋的像素半径%BorW为下棋选择,1黑棋,2白棋,3悔棋%Wid_edge为棋盘矩阵中的棋盘边缘的像素宽度%Dpixel为棋盘矩阵中的相邻棋盘线间的像素间隔%Color_QiPanBack为棋盘背景颜色%Color_ChessLine为棋盘线的颜色Color_BChess=[54,54,54];Color_WChess=[255,240,245];[Wid,Hei,Deep]=size(M_QiPan);for i=x_col_Chess-radius_Chess:x_col_Chess+radius_Chess for j=y_row_Chess-radius_Chess:y_row_Chess+radius_Chess if (i-x_col_Chess)^2+(j-y_row_Chess)^2<=radius_Chess^2 if BorW==1%黑棋 M_QiPan(j,i,:)=Color_BChess; elseif BorW==2%白棋 M_QiPan(j,i,:)=Color_WChess; elseif BorW==3%悔棋 M_QiPan(j,i,:)=Color_QiPanBack; %对于不是棋盘边缘的棋子 if i==x_col_Chess||j==y_row_Chess M_QiPan(j,i,:)=Color_ChessLine; end %悔棋点是否为小圆点 if ((i-x_col_Chess)^2+(j-y_row_Chess)^2<5^2)&&... (x_col_Chess==Wid_edge+1+Dpixel*3||x_col_Chess==floor(Wid/2)+1||x_col_Chess==Wid-Wid_edge-Dpixel*3)&&... (y_row_Chess==Wid_edge+1+Dpixel*3||y_row_Chess==floor(Wid/2)+1||y_row_Chess==Wid-Wid_edge-Dpixel*3) M_QiPan(j,i,:)=Color_ChessLine; end %对于棋盘边缘的棋子 if x_col_Chess==Wid_edge+1&&i<x_col_Chess M_QiPan(j,i,:)=Color_QiPanBack; elseif x_col_Chess==Wid-Wid_edge&&i>x_col_Chess M_QiPan(j,i,:)=Color_QiPanBack; end if y_row_Chess==Wid_edge+1&&j<y_row_Chess M_QiPan(j,i,:)=Color_QiPanBack; elseif y_row_Chess==Wid-Wid_edge&&j>y_row_Chess M_QiPan(j,i,:)=Color_QiPanBack; end end end endendend

4、胜负判断函数

%Author:LeiZhen%Date:2018-03-12function Victory_flag=Victory_Judge(M_LuoZi,x_col_LuoZi,y_row_LuoZi,State)%对一方是否获胜的判断函数%M_LuoZi为下棋点的矩阵%x_col_LuoZi为下棋列数%y_row_LuoZi下棋行数%State为M_LuoZi矩阵某点的下棋状态,黑棋(1)或白棋(2)或无棋(0),以及每步棋的序号%NumCell为棋盘格数%Victory_flag为胜利标志NumCell=length(M_LuoZi)-1;Victory_flag=0;for i=1:NumCell-3 if M_LuoZi(i,y_row_LuoZi,1)==State&&M_LuoZi(i+1,y_row_LuoZi,1)==State&&M_LuoZi(i+2,y_row_LuoZi,1)==State&&M_LuoZi(i+3,y_row_LuoZi,1)==State&&M_LuoZi(i+4,y_row_LuoZi,1)==State Victory_flag=1; break; end if M_LuoZi(x_col_LuoZi,i,1)==State&&M_LuoZi(x_col_LuoZi,i+1,1)==State&&M_LuoZi(x_col_LuoZi,i+2,1)==State&&M_LuoZi(x_col_LuoZi,i+3,1)==State&&M_LuoZi(x_col_LuoZi,i+4,1)==State Victory_flag=1; break; end if abs(x_col_LuoZi-y_row_LuoZi)+i<=NumCell-3 if x_col_LuoZi>=y_row_LuoZi if M_LuoZi(abs(x_col_LuoZi-y_row_LuoZi)+i,i,1)==State&&M_LuoZi(abs(x_col_LuoZi-y_row_LuoZi)+i+1,i+1,1)==State&&M_LuoZi(abs(x_col_LuoZi-y_row_LuoZi)+i+2,i+2,1)==State&&M_LuoZi(abs(x_col_LuoZi-y_row_LuoZi)+i+3,i+3,1)==State&&M_LuoZi(abs(x_col_LuoZi-y_row_LuoZi)+i+4,i+4,1)==State Victory_flag=1; break; end elseif x_col_LuoZi<y_row_LuoZi if M_LuoZi(i,abs(x_col_LuoZi-y_row_LuoZi)+i,1)==State&&M_LuoZi(i+1,abs(x_col_LuoZi-y_row_LuoZi)+i+1,1)==State&&M_LuoZi(i+2,abs(x_col_LuoZi-y_row_LuoZi)+i+2,1)==State&&M_LuoZi(i+3,abs(x_col_LuoZi-y_row_LuoZi)+i+3,1)==State&&M_LuoZi(i+4,abs(x_col_LuoZi-y_row_LuoZi)+i+4,1)==State Victory_flag=1; break; end end end if y_row_LuoZi+x_col_LuoZi<=NumCell+2&&y_row_LuoZi+x_col_LuoZi-i>=5 if M_LuoZi(y_row_LuoZi+x_col_LuoZi-i,i,1)==State&&M_LuoZi(y_row_LuoZi+x_col_LuoZi-i-1,i+1,1)==State&&M_LuoZi(y_row_LuoZi+x_col_LuoZi-i-2,i+2,1)==State&&M_LuoZi(y_row_LuoZi+x_col_LuoZi-i-3,i+3,1)==State&&M_LuoZi(y_row_LuoZi+x_col_LuoZi-i-4,i+4,1)==State Victory_flag=1; break; end elseif y_row_LuoZi+x_col_LuoZi>NumCell+2&&y_row_LuoZi+x_col_LuoZi+i<=NumCell*2-1 offset=NumCell+2; if M_LuoZi(y_row_LuoZi+x_col_LuoZi-offset+i,offset-i,1)==State&&M_LuoZi(y_row_LuoZi+x_col_LuoZi-offset+i+1,offset-i-1,1)==State&&M_LuoZi(y_row_LuoZi+x_col_LuoZi-offset+i+2,offset-i-2,1)==State&&M_LuoZi(y_row_LuoZi+x_col_LuoZi-offset+i+3,offset-i-3,1)==State&&M_LuoZi(y_row_LuoZi+x_col_LuoZi-offset+i+4,offset-i-4,1)==State Victory_flag=1; break; end endendend

5、光标函数(由库函数改动而来)

%此函数为库函数的修改,仅将十字光标改为箭头光标,改动位置为第88行function [out1,out2,out3] = ginput_pointer(arg1)%GINPUT Graphical input from mouse.% [X,Y] = GINPUT(N) gets N points from the current axes and returns% the X- and Y-coordinates in length N vectors X and Y. The cursor% can be positioned using a mouse. Data points are entered by pressing% a mouse button or any key on the keyboard except carriage return,% which terminates the input before N points are entered.%% [X,Y] = GINPUT gathers an unlimited number of points until the% return key is pressed.%% [X,Y,BUTTON] = GINPUT(N) returns a third result, BUTTON, that% contains a vector of integers specifying which mouse button was% used (1,2,3 from left) or ASCII numbers if a key on the keyboard% was used.%% Examples:% [x,y] = ginput;%% [x,y] = ginput(5);%% [x, y, button] = ginput(1);%% See also GTEXT, WAITFORBUTTONPRESS. % Copyright 1984-2011 The MathWorks, Inc.% $Revision: 5.32.4.18 $ $Date: 2011/05/17 02:35:09 $ out1 = []; out2 = []; out3 = []; y = [];c = computer;if ~strcmp(c(1:2),'PC') tp = get(0,'TerminalProtocol');else tp = 'micro';end if ~strcmp(tp,'none') && ~strcmp(tp,'x') && ~strcmp(tp,'micro'), if nargout == 1, if nargin == 1, out1 = trmginput(arg1); else out1 = trmginput; end elseif nargout == 2 || nargout == 0, if nargin == 1, [out1,out2] = trmginput(arg1); else [out1,out2] = trmginput; end if nargout == 0 out1 = [ out1 out2 ]; end elseif nargout == 3, if nargin == 1, [out1,out2,out3] = trmginput(arg1); else [out1,out2,out3] = trmginput; end endelse fig = gcf; figure(gcf); if nargin == 0 how_many = -1; b = []; else how_many = arg1; b = []; if ischar(how_many) ... || size(how_many,1) ~= 1 || size(how_many,2) ~= 1 ... || ~(fix(how_many) == how_many) ... || how_many < 0 error(message('MATLAB:ginput:NeedPositiveInt')) end if how_many == 0 % If input argument is equal to zero points, % give a warning and return empty for the outputs. warning (message('MATLAB:ginput:InputArgumentZero')); end end % Setup the figure to disable interactive modes and activate pointers. initialState = setupFcn(fig); set(gcf, 'pointer', 'arrow'); % onCleanup object to restore everything to original state in event of % completion, closing of figure errors or ctrl+c. c = onCleanup(@() restoreFcn(initialState)); % We need to pump the event queue on unix % before calling WAITFORBUTTONPRESS drawnow char = 0; while how_many ~= 0 % Use no-side effect WAITFORBUTTONPRESS waserr = 0; try keydown = wfbp; catch %#ok<CTCH> waserr = 1; end if(waserr == 1) if(ishghandle(fig)) cleanup(c); error(message('MATLAB:ginput:Interrupted')); else cleanup(c); error(message('MATLAB:ginput:FigureDeletionPause')); end end % g467403 - ginput failed to discern clicks/keypresses on the figure it was % registered to operate on and any other open figures whose handle % visibility were set to off figchildren = allchild(0); if ~isempty(figchildren) ptr_fig = figchildren(1); else error(message('MATLAB:ginput:FigureUnavailable')); end % old code -> ptr_fig = get(0,'CurrentFigure'); Fails when the % clicked figure has handlevisibility set to callback if(ptr_fig == fig) if keydown char = get(fig, 'CurrentCharacter'); button = abs(get(fig, 'CurrentCharacter')); else button = get(fig, 'SelectionType'); if strcmp(button,'open') button = 1; elseif strcmp(button,'normal') button = 1; elseif strcmp(button,'extend') button = 2; elseif strcmp(button,'alt') button = 3; else error(message('MATLAB:ginput:InvalidSelection')) end end axes_handle = gca; drawnow; pt = get(axes_handle, 'CurrentPoint'); how_many = how_many - 1; if(char == 13) % & how_many ~= 0) % if the return key was pressed, char will == 13, % and that's our signal to break out of here whether % or not we have collected all the requested data % points. % If this was an early breakout, don't include % the <Return> key info in the return arrays. % We will no longer count it if it's the last input. break; end out1 = [out1;pt(1,1)]; %#ok<AGROW> y = [y;pt(1,2)]; %#ok<AGROW> b = [b;button]; %#ok<AGROW> end end % Cleanup and Restore cleanup(c); if nargout > 1 out2 = y; if nargout > 2 out3 = b; end else out1 = [out1 y]; end endend %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function key = wfbp%WFBP Replacement for WAITFORBUTTONPRESS that has no side effects. fig = gcf;current_char = []; %#ok<NASGU> % Now wait for that buttonpress, and check for error conditionswaserr = 0;try h=findall(fig,'Type','uimenu','Accelerator','C'); % Disabling ^C for edit menu so the only ^C is for set(h,'Accelerator',''); % interrupting the function. keydown = waitforbuttonpress; current_char = double(get(fig,'CurrentCharacter')); % Capturing the character. if~isempty(current_char) && (keydown == 1) % If the character was generated by the if(current_char == 3) % current keypress AND is ^C, set 'waserr'to 1 waserr = 1; % so that it errors out. end end set(h,'Accelerator','C'); % Set back the accelerator for edit menu.catch %#ok<CTCH> waserr = 1;enddrawnow;if(waserr == 1) set(h,'Accelerator','C'); % Set back the accelerator if it errored out. error(message('MATLAB:ginput:Interrupted'));endif nargout>0, key = keydown; end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%endfunction initialState = setupFcn(fig)% Store Figure Handle. initialState.figureHandle = fig; % Suspend figure functionsinitialState.uisuspendState = uisuspend(fig);% Disable Plottools ButtonsinitialState.toolbar = findobj(allchild(fig),'flat','Type','uitoolbar');if ~isempty(initialState.toolbar) initialState.ptButtons = [uigettool(initialState.toolbar,'Plottools.PlottoolsOff'), ... uigettool(initialState.toolbar,'Plottools.PlottoolsOn')]; initialState.ptState = get (initialState.ptButtons,'Enable'); set (initialState.ptButtons,'Enable','off');end% Setup FullCrosshair Pointer without warning. oldwarnstate = warning('off', 'MATLAB:hg:Figure:Pointer');set(fig,'Pointer','fullcrosshair');warning(oldwarnstate);% Adding this to enable automatic updating of currentpoint on the figure set(fig,'WindowButtonMotionFcn',@(o,e) dummy());% Get the initial Figure UnitsinitialState.fig_units = get(fig,'Units');endfunction restoreFcn(initialState)if ishghandle(initialState.figureHandle) % Figure Units set(initialState.figureHandle,'Units',initialState.fig_units); set(initialState.figureHandle,'WindowButtonMotionFcn',''); % Plottools Icons if ~isempty(initialState.toolbar) && ~isempty(initialState.ptButtons) set (initialState.ptButtons(1),'Enable',initialState.ptState{1}); set (initialState.ptButtons(2),'Enable',initialState.ptState{2}); end % UISUSPEND uirestore(initialState.uisuspendState);endendfunction dummy()% do nothing, this is there to update the GINPUT WindowButtonMotionFcn. endfunction cleanup(c)if isvalid(c) delete(c);endend

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

本文标题: MATLAB实现五子棋游戏(双人对战、可悔棋)

以上就上有关MATLAB实现五子棋游戏(双人对战、可悔棋)的相关介绍,要了解更多MATLAB,五子棋,游戏内容请登录学步园。

抱歉!评论已关闭.