本文实例为大家分享了MATLAB实现五子棋游戏的具体代码,供大家参考,具体内容如下
程序介绍:
1、此游戏只可用于双人对战。
2、棋盘颜色、棋盘格数、棋子颜色等参数均可自由设置
3、鼠标点击非棋盘区域可悔棋。
一、游戏界面
二、主程序及函数
1、主程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
%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 ; end end |
2、画棋盘函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
%Author:LeiZhen %Date:2018-03-12 function [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; end for 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 end end end |
3、下棋或悔棋函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
%Author:LeiZhen %Date:2018-03-12 function 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 end end end |
4、胜负判断函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
%Author:LeiZhen %Date:2018-03-12 function 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 end end end |
5、光标函数(由库函数改动而来)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
%此函数为库函数的修改,仅将十字光标改为箭头光标,改动位置为第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 end else 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 end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 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 conditions waserr = 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; end drawnow; if (waserr == 1) set(h, 'Accelerator' , 'C' ); % Set back the accelerator if it errored out. error(message( 'MATLAB:ginput:Interrupted' )); end if nargout>0, key = keydown; end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% end function initialState = setupFcn(fig) % Store Figure Handle. initialState.figureHandle = fig; % Suspend figure functions initialState.uisuspendState = uisuspend(fig); % Disable Plottools Buttons initialState.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 Units initialState.fig_units = get(fig, 'Units' ); end function 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); end end function dummy() % do nothing, this is there to update the GINPUT WindowButtonMotionFcn. end function cleanup(c) if isvalid(c) delete (c); end end |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_25634581/article/details/79086244