matlab 手把手教你制作五子棋小游戏
想把以前写过的小游戏出一款详细教程呀
这两天发现五子棋有个简单的写法
虽然说有点弊端但这个程序真的很简单呀
一共只有70多行
相信大家就算没有基础多查多看也能学会吧嗯哒
第一步:界面设置
axis equal%让横竖坐标比例相等
axis([-10,10,-10,10])%坐标轴范围设置为X,Y轴都是-10到10
set(gca,‘xtick’,[],‘ytick’,[],‘xcolor’,‘w’,‘ycolor’,‘w’)
%用xtick,ytick删除掉坐标轴刻度,并将坐标轴颜色设置为white
set(gca,‘color’,[0.8392,0.7216,0.3804])
%将背景的颜色设置为棕色,这里的三个数字表示的是红蓝绿的比例
hold on%保持界面不关闭
第二步:绘制棋盘
这里直接用散点图scatter和折线图plot 进行绘制,直接暴力取点绘制
x1=[-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,-3,-2,-2,-1,-1,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9];
y1=[-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9];
x2=[-9,9,9,-9,-9];y2=[9,9,-9,-9,9];x3=[-9.2,9.2,9.2,-9.2,-9.2];y3=[9.2,9.2,-9.2,-9.2,9.2];x4=[-6,-6,-6,0,0,0,6,6,6];y4=[6,0,-6,6,0,-6,6,0,-6];
plot(x1,y1,‘k’)
plot(y1,x1,‘k’)
plot(x2,y2,‘k’,‘LineWidth’,2)
plot(x3,y3,‘k’)
scatter(gca,x4,y4,30,‘k’,‘filled’)
第三步:基础设置
row=19;col=19;%棋盘矩阵大小为19x19这里的矩阵大小画图使用不到的但是后期运算可以用到;
win=0;%这是判断输赢的一个参数
control=1;%这是判断下子颜色的一个参数,1为黑子,0为白子
postion=[0 0];%这是那个红叉的坐标就是下棋位置,这里的下棋方法为上下左右加空格键下棋
black=[20,20];white=[-20,-20];%随便取两个棋子的初始坐标
black(1,:)=[];white(1,:)=[];%把那两个初始坐标删掉
%这里取初始坐标又删掉是为了使这两个点集是两列的空矩阵
plotblack=scatter(gca,black(:,1),black(:,2),150,‘k’,‘filled’);
plotwhite=scatter(gca,white(:,1),white(:,2),150,‘w’,‘filled’);
plotpostion=scatter(gca,postion(1,1),postion(1,2),150,‘rx’);
设置绘图的初始数据
第四步:按键设置
set(gcf, 'KeyPressFcn', @key) %设置有任何按键动作时,调用key这个函数
function key(~,event)%定义函数key,其中event是按键动作
switch event.Key%将按键动作转换
case 'uparrow'%上下左右这四个都是一样的这里只挑一个进行解释
%将按键 uparrow即上箭头,转化为将postion坐标上移
postion=postion+[0,1];
case 'downarrow'
postion=postion+[0,-1];
case 'leftarrow'
postion=postion+[-1,0];
case 'rightarrow'
postion=postion+[1,0];
case 'c'%将按键c转化为按下按键红叉回到画面最中央
postion=[0,0];
case 'space'%空格键
if sum(ismember([black(:,1:2);white(:,1:2)],postion(1,1:2),'rows'))==0
%这句话用来判断下棋的点上有没有棋子
%这里解释一下
%这个小程序里棋子的坐标储存方法是这样的
%例如black=[x1,y1;x2,y2]就是指在(x1,y1),(x2,y2)坐标上两个点是黑棋
%其他的白棋和红叉同理
%然后解释一下ismember就是判断前面的集合的项在后面的集合中存不存在
%因为我们每行代表一个点,我们这里加上‘rows'表示判断前面的点在后面存不存在
%用法ismember(A,B,'rows')
%当然也可以用效果差不多的intersect来判断
%这里用sum有一点使懒,算是一种小bug的写法,最好还是用isempty判断
if control==1,black=[black;postion];end%如果control=1那么在红叉位置下黑子
if control==0,white=[white;postion];end%同上
control=mod(control+1,2);%mod是求余函数呀这里就是求control+1除以2的余数
%这样的话control就能1 0 1 0 1 0 的周期性变化啦,也就是轮流下黑子白子
end
case 'backspace'
co=0;
if control==0&&~isempty(black),black(end,:)=[];co=1;end
if control==1&&~isempty(white),white(end,:)=[];co=1;end
if co==1,control=mod(control+1,2);end
end
wuziqigame()每次按完键后重新画一遍图,这里wuziqigame负责画图和显示输赢
end
第五步:不断重新绘制棋盘
function wuziqigame(~,~)
postion(postion>9)=-9;%如果红叉坐标太大即超出界面,我们将它坐标减小移回界面内
postion(postion<-9)=9;%和上面差不多
panding()%这是一个胜负判断程序,后面会讲
set(plotblack,'XData',black(:,1),'YData',black(:,2))%还好scatter有Data功能,即可以不用删除上一幅图更新新的图片,非常好用
set(plotwhite,'XData',white(:,1),'YData',white(:,2))
set(plotpostion,'XData',postion(1,1),'YData',postion(1,2))
if win==1%这个是一方赢事弹出窗口的程序,比较简单就不讲了
buttonName1=questdlg('black win. What do you mean to do?','black win','close','restart','close');
if isempty(buttonName1)
buttonName1='end'
end
if strcmp(buttonName1,'restart')
clf
wuziqi()
else if strcmp(buttonName1,'close'),
close
end
end
end
if win==-1
buttonName1=questdlg('white win. What do you mean to do?','white win','close','restart','close');
if isempty(buttonName1)
buttonName1='end'
end
if strcmp(buttonName1,'restart')
clf
wuziqi()
else if strcmp(buttonName1,'close')
close
end
end
end
end
第六步:判断输赢的核心算法
核心算法真的短的吓人呀
不过感觉可能不是很好理解
至少要能熟练地运用
这样写很简单还有一个写法就是相对于最后下的一步棋(因为形成的五子连珠必定是由于新棋子的加入,不然它在下新子之前就已经赢了)进行的链式搜索,可以以后再讲。
function panding(~,~)
mat=zeros(row+4,col+4);%创建一个比棋盘大四行四列的全零矩阵
x=3:(row+2);y=3:(col+2);%设置x,y是中间row行col列
qipan=zeros(row,col);%设置棋盘是row行col列的全零矩阵
blackpos=black(:,1)+10+(black(:,2)+10-1)*row;
whitepos=white(:,1)+10+(white(:,2)+10-1)*row;
%将双参数索引转化为单参数索引
%例如对19X19的矩阵来说它的第(1,2)个数,即第一行第二列对应其第20个数
%这里加上10是因为棋子的坐标是从-9开始的
qipan(blackpos)=1;%棋盘矩阵中黑子的位置设置数值为1
qipan(whitepos)=-1;%棋盘矩阵中黑子的位置设置数值为-1
mat(x,y)=qipan;%将棋盘矩阵放在比棋盘矩阵大两圈的矩阵的正中间
mat1=mat(x,y)+mat(x+1,y)+mat(x+2,y)+mat(x-1,y)+mat(x-2,y);
%每一个位置的数值和它左侧坐标,左左侧坐标,右侧坐标,右右侧坐标相加
mat2=mat(x,y)+mat(x,y+1)+mat(x,y+2)+mat(x,y-1)+mat(x,y-2);
%每一个位置的数值和它上侧坐标,上上侧坐标,下侧坐标,下下侧坐标相加
mat3=mat(x,y)+mat(x+1,y+1)+mat(x+2,y+2)+mat(x-1,y-1)+mat(x-2,y-2);%与前面类似
mat4=mat(x,y)+mat(x+1,y-1)+mat(x+2,y-2)+mat(x-1,y+1)+mat(x-2,y+2);
con=[mat1;mat2;mat3;mat4];con1=con==5;con2=con==-5;%判断mat1到mat4中有没有数值为5或者负五的点
if (sum(sum(con1)))~=0,win=1;end%如果有值为5的点黑色赢
if (sum(sum(con2)))~=0,win=-1;end%如果有值为-5的点白色赢
end
第七部:将各部分连接在一起
完整代码
这里因为代码太长会在手机上显示不全,所以分成了两个代码片
将其复制在同一个m文件就可以用啦
function wuziqi
axis equal
axis([-10,10,-10,10])
set(gca,'xtick',[],'ytick',[],'xcolor','w','ycolor','w')
set(gca,'color',[0.8392,0.7216,0.3804])
hold on
row=19;col=19;
x1=[-9,-9,-8,-8,-7,-7,-6,-6,-5,-5,-4,-4,-3,-3,-2,-2,-1,-1,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9];
y1=[-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9,9,-9,-9,9];
x2=[-9,9,9,-9,-9];y2=[9,9,-9,-9,9];x3=[-9.2,9.2,9.2,-9.2,-9.2];y3=[9.2,9.2,-9.2,-9.2,9.2];x4=[-6,-6,-6,0,0,0,6,6,6];y4=[6,0,-6,6,0,-6,6,0,-6];
plot(x1,y1,'k'),plot(y1,x1,'k'),plot(x2,y2,'k','LineWidth',2),plot(x3,y3,'k'),scatter(gca,x4,y4,30,'k','filled')
win=0;control=1;postion=[0 0];
black=[20,20];white=[-20,-20];
black(1,:)=[];white(1,:)=[];
plotblack=scatter(gca,black(:,1),black(:,2),150,'k','filled');
plotwhite=scatter(gca,white(:,1),white(:,2),150,'w','filled');
plotpostion=scatter(gca,postion(1,1),postion(1,2),150,'rx');
set(gcf, 'KeyPressFcn', @key)
function wuziqigame(~,~)
postion(postion>9)=-9;
postion(postion<-9)=9;
panding()
set(plotblack,'XData',black(:,1),'YData',black(:,2))
set(plotwhite,'XData',white(:,1),'YData',white(:,2))
set(plotpostion,'XData',postion(1,1),'YData',postion(1,2))
if win==1
buttonName1=questdlg('black win. What do you mean to do?','black win','close','restart','close');
if isempty(buttonName1),buttonName1='end';end
if strcmp(buttonName1,'restart'),clf;wuziqi();
else if strcmp(buttonName1,'close'),close;end
end
end
if win==-1
buttonName1=questdlg('white win. What do you mean to do?','white win','close','restart','close');
if isempty(buttonName1),buttonName1='end';end
if strcmp(buttonName1,'restart'),clf;wuziqi();
else if strcmp(buttonName1,'close'),close;end
end
end
end
function panding(~,~)
mat=zeros(row+4,col+4);
x=3:(row+2);y=3:(col+2);
qipan=zeros(row,col);
blackpos=black(:,1)+10+(black(:,2)+10-1)*row;
whitepos=white(:,1)+10+(white(:,2)+10-1)*row;
qipan(blackpos)=1;qipan(whitepos)=-1;mat(x,y)=qipan;
mat1=mat(x,y)+mat(x+1,y)+mat(x+2,y)+mat(x-1,y)+mat(x-2,y);
mat2=mat(x,y)+mat(x,y+1)+mat(x,y+2)+mat(x,y-1)+mat(x,y-2);
mat3=mat(x,y)+mat(x+1,y+1)+mat(x+2,y+2)+mat(x-1,y-1)+mat(x-2,y-2);
mat4=mat(x,y)+mat(x+1,y-1)+mat(x+2,y-2)+mat(x-1,y+1)+mat(x-2,y+2);
con=[mat1;mat2;mat3;mat4];con1=con==5;con2=con==-5;
if (sum(sum(con1)))~=0,win=1;end
if (sum(sum(con2)))~=0,win=-1;end
end
function key(~,event)
switch event.Key
case 'uparrow',postion=postion+[0,1];
case 'downarrow',postion=postion+[0,-1];
case 'leftarrow',postion=postion+[-1,0];
case 'rightarrow',postion=postion+[1,0];
case 'c',postion=[0,0];
case 'space'
if sum(ismember([black(:,1:2);white(:,1:2)],postion(1,1:2),'rows'))==0
if control==1,black=[black;postion];end
if control==0,white=[white;postion];end
control=mod(control+1,2);
end
case 'backspace'
co=0;
if control==0&&~isempty(black),black(end,:)=[];co=1;end
if control==1&&~isempty(white),white(end,:)=[];co=1;end
if co==1,control=mod(control+1,2);end
end
wuziqigame()
end
end
相关文章
- Matlab中num2cell函数使用
- Matlab中filter2函数用法
- Matlab中num2str函数使用
- matlab学习笔记8 基本绘图命令-基本绘图操作
- 【MATLAB教程案例98】基于混沌序列的图像加解密matlab仿真,并进行各类攻击测试
- 【MATLAB教程案例84】通过matlab实现数据的线性回归
- 【MATLAB教程案例67】基于Actor-Critic结构强化学习的车杆平衡控制系统matlab仿真
- 【MATLAB教程案例49】三维点云数据ICP配准算法的matlab仿真学习
- 【MATLAB教程案例47】基于双目相机拍摄图像的三维重建matlab仿真
- 【MATLAB教程案例41】语音信号的语谱图matlab仿真与应用分析
- 【MATLAB教程案例40】语音信号的共振峰频率倒谱法估计matlab仿真学习
- 【MATLAB教程案例38】语音信号的去噪方法matlab仿真学习——LMS自适应滤波,谱减法去噪滤波及维纳滤波等
- 【MATLAB教程案例37】语音信号的端点检测方法matlab仿真学习——ZCR过零法,双门限法
- 【MATLAB教程案例29】基于Baker映射和Logistic混沌序列的图像加解密matlab实现
- 【MATLAB教程案例11~20总结】优化类算法matlab仿真经验和技巧总结
- 【MATLAB教程案例16】基于GWO灰狼优化算法的函数极值计算matlab仿真及其他应用
- 【MATLAB教程案例12】基于GA遗传优化算法的函数极值计算matlab仿真及其他应用
- 基于matlab的低秩结构重构算法仿真实现,对比ALM,IT,APG,ADMM
- 基于Kinect深度图像采集和SLAM室内地图创建算法的matlab仿真
- 【三维手臂手指活动动态仿真】基于MATLAB+python三维手臂动态仿真
- matlab产生泊松分布
- COST231-WI模型信道仿真,源码仿真matlab编程源码
- MATLAB 数据分析方法(第2版)1.2 MATLAB基础概述
- MATLAB 数据分析方法(第2版)1.6 MATLAB通用操作实例
- 【Matlab】系统预定义变量——元胞数组与结构体
- 把一个文件中所有文件名或者文件路径读取到一个txt文件,然后在matlab中读取
- 如何使用MATLAB制作 “福寿图“ 以及 “百寿图“
- MATLAB | 我用MATLAB制作了一款伪3D第一视角迷宫小游戏
- matlab 手把手教你制作五子棋小游戏(二)
- matlab 手把手教你制作贪吃蛇小游戏