您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 销售管理 > VB课程设计:拼图游戏
VisualBasic课程设计报告题目1:拼图游戏难度:***指导教师:姓名:学号:专业:班级:学院:日期:11.题目简介(1)本题目要求设计一个拼图游戏程序,要求如下:指定一幅完整的图片,将其分割成m*n个小图块,打乱后重新排列,其中有一个没有图片的“空当”如图————(2)使用鼠标单击与空当相邻的图块可以与其互换位置。(3)利用空当位置使原图恢复原来的顺序,并记下玩家的移动步数,游戏过程中可以查看参考图以方便顺利通过游戏。22、设计思路与总体方案本程序包含五个窗体模块,其中以窗体frmMain的作用最为主要,该模块负责加载选定的图片并按所选的行列数分割,进行随机排列并加载空当,实现鼠标点击时其中的图块时与相邻的空当进行替换,实现拼图完成这个结束动作。该模块中主要的变量有Rows,Cols,Arrange(),space,started,stepsshowrefFunctionisOK()其中,Rows,Cols,showref这三个为全局变量,分别表示行数,列数,以及是否显示参考图(因此showref为逻辑型变量)其余变量为模块级变量,started也为逻辑变量,负责显示游戏是否已开始,Arrange()数组表示联系图像控件与数组的关系,space显示空当的位置,steps来记录玩家所走的步数,FunctionisOK()用来检验拼图是否已经完成的函数,为逻辑性变量。除外,过程变量tt(0to2),b(0to2),s,r,c用来写入或读取排行榜中的记录。其中,还设有菜单栏,通过CommonDialog控件负责实现“打开图片”与“配置颜色”对话框,并同时还拥有打开frmRecod(排行榜窗体模块)的工能。主要代码(游戏初始时加载图片):DimiAsIntegerDimnAsIntegerCD.Filter=图片文件(*.JPG,*.BMP)|*.jpg;*.bmpCD.DialogTitle=打开图片CD.InitDir=App.Path&\picsCD.ShowOpen(显示指定图片对话框)IfCD.FileName=ThenExitSubIfstartedThenFori=1ToRows*Cols-1'(清除已有的控件数组元素)UnloadimgPT(i)NextimgPT(0).Picture=LoadPicture()IfshowrefThenfrmRef.Image1.Picture=LoadPicture()ElseMe.Picture=LoadPicture()EndIffrmDivide.Show1,Me'(显示指定行列对话框)PC.Picture=LoadPicture(CD.FileName)PC.Rows=RowsPC.Cols=Colsn=Rows*ColsimgPT(0).Width=320/Cols('窗体以像素为单位)3imgPT(0).Height=240/Rows窗体frmDivide载入图片后弹出此窗口,负责提示玩家进行图片行列数的选择,用以调节游戏等级,可分为3*3,3*4,4*3,4*4这四种模式。玩家通过两个VScroll控件调节TextBox中的行列数,通过Text1.Text=VScroll1.ValueText2.Text=VScroll2.ValuefrmMain.Rows=Text1.Text,frmMain.Cols=Text2.Text赋值语句来与frmMain模块进行数值传递。窗体frmRef通过窗体frmMain中的“显示参考图”按钮来显示玩家游戏时的所需的参考图,frmMain通过showref=NotshowrefIfshowrefThenLoadfrmReffrmRef.Image1.Picture=PC.PicturefrmRef.Top=Me.TopfrmRef.Left=Me.Left+Me.WidthfrmRef.ShowcmdShowRef.Caption=关闭参考图ElseUnloadfrmRefcmdShowRef.Caption=显示参考图来打开这个模块以显示参考图,通过对逻辑变量showref的非运算加载该模块,设置高度与宽度。窗体frmRecord用来显示玩家通过游戏后所处的名次,姓名,移动步数,难度(行数X列数),并且只有名次在大于系统默认前三名的状况下才能被录入排行榜,否则会弹出“完成,你未进入前三名!”的提醒框。代码如下:OpenApp.Path&\Record.txtForInputAs#1Forl=0To24Input#1,tt(l),b(l),r(l),c(l)(依次读入步数,姓名,行数,列数)NextClose#1Ifstt(2)Then(只有你的成绩大于系统内第三名时IF语句才会启动,进行信息录入)KillApp.Path&\Record.txtIfs=tt(1)Thentt(2)=s:b(2)=InputBox(请输入姓名:,输入框,无名侠):r(2)=Rows:c(2)=Cols:MsgBox完成,恭喜&b(2)&你成为第三名!,vbInformationIfstt(1)Ands=tt(0)Thentt(2)=tt(1):tt(1)=s:b(2)=b(1):b(1)=InputBox(请输入姓名:,输入框,无名侠):r(2)=r(1):r(1)=Rows:c(2)=c(1):c(1)=Cols:MsgBox完成,恭喜&b(1)&你成为第二名!,vbInformationIfstt(0)Thentt(2)=tt(1):tt(1)=tt(0):tt(0)=s:b(2)=b(1):b(1)=b(0):b(0)=InputBox(请输入姓名:,输入框,无名侠):r(2)=r(1):r(1)=r(0):r(0)=Rows:c(2)=c(1):c(1)=c(0):c(0)=Cols:MsgBox完成,恭喜&b(0)&你成为第一名!,vbInformation(通过以上的IF语句先比较出步数在系统默认下的的名次,再通过赋值语句进行排名,同时将姓名,行数,列数也进行赋值处理同步于步数的名次变化,优点是不需建立多维数组进行储存)OpenApp.Path&\Record.txtForOutputAs#1Forl=0To2Write#1,tt(l),b(l),r(l),c(l)NextClose#1ElseMsgBox完成,你未进入前三名!,vbInformationEndIf窗体frmHelp用以显示对本游戏的提示,用以解释游戏无法顺利进行的原因,详情请见(4、设计中尚存的不足分析)。主要代码:Image2(0).Picture=LoadPicture(App.Path&\Resource\ab.jpg)(加载图片)53、对重点(难点)问题的解决窗体模块frmMain为主要载体,也是该程序的难点所在,其中的PictureClip控件在我看来是最主要的,他负责管理打开的图片并将其分割为指定行列的小图块。CommonDialog控件负责实现“打开图片”与“配置颜色”对话框。Image控件数组用于显示图片,其中他的Stretch属性设计为True,可以使图片自动放大或缩小,方便玩家自由选择图片进行游戏。主窗体重点(难点1)——————————随机排列图片解决方案:利用j=Int(Rnd*n)产生的随机数(0~n-1)同时通过Arrange赋值给PC.GraphicCell,来传递给imgPT()进行图片的随机分布。例如:Arrange(3)=9imgPT(i).Picture=PC.GraphicCell(Arrange(3))因此,该随机排列图片过程的代码如下:PrivateSubRnd_Arrange()'DimiAsInteger,jAsIntegerDimnAsIntegern=Rows*ColsReDimArrange(0Ton-1)Fori=0Ton-1Arrange(i)=-1(用-1标记未赋值的元素)Nexti=0Doj=Int(Rnd*n)(产生0~n-1的随机数,并用Arrange赋值)IfArrange(j)=-1ThenArrange(j)=ii=i+1Ifi=nThenExitDoEndIfLoopFori=1Ton-1LoadimgPT(i)NextFori=0Ton-16IfArrange(i)n-1Then(将图块赋给控件数组元素)imgPT(i).Picture=PC.GraphicCell(Arrange(i))ElseimgPT(i).Picture=LoadPicture()space=I(将“打乱”前图片右下角的图块设为空)EndIfNextEndSub难点(2)——————————当你单击图片时判断是否与空当相邻并进行移动。解决方法:计算这两者分别所处的行列,利用IF语句进行判断,通过改变Image的Index值来改变所显示的图片,而非移动这个控件。该过程代码如下:c1=spaceModCols(计算空档的行列)r1=space\Colsc2=IndexModCols(计算点击的行列)r2=Index\ColsIfAbs(c1-c2)=1AndAbs(r1-r2)=0OrAbs(c1-c2)=0AndAbs(r1-r2)=1Then(判断是否相邻)n=Arrange(Index)Arrange(Index)=Arrange(space)Arrange(space)=nimgPT(space)=PC.GraphicCell(Arrange(space))imgPT(Index)=LoadPicture()(进行替换)难点(3)———————————————判定拼图结束IfisOK()ThenMsgBox恭喜,完成拼图!共用了&steps&步。'Fori=1ToRows*Cols-1imgPT(i).Enabled=False解决方法:上述代码表示游戏过程中可利用FunctionisOK()来检验玩家是否已经完成游戏,检验过程代码如下:DimiAsIntegerFori=0ToCols*Rows-1IfArrange(i)iThenExitForNextIfi=Cols*RowsThenisOK=True(isOK=True时,IF语句运行使得游戏结束)4、设计中尚存的不足分析本游戏中的图片排列顺序为随机排列,虽然代码简易,同时可以得到较为随7机的乱序图片外,50%的几率会出现下面这一个意想不到的问题————奇排列在偶数次移动后无法转化为偶排列。(拼图最后两块的位置颠倒且无法逆转)如a,b图所示,图中的a是3*3数字拼图标准的结果,则对于图b的状态是不可能变换成a的。证明起来需要用到高等代数里逆序数的概念,具体的说是用到了一个简单的定理。定义:在一个1,2,...,n的排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。逆序数为偶数的排列称为偶排列;逆序数为奇数的排列称为奇排列推论:数列进行偶数次相邻对换,数列的奇偶性不改变我们将空格看成数字9(数字9对应空位),按正常顺序看a图,9个数字排列是123456789,其逆序数是0,是偶排列;b图是123456879,逆序数是1,是奇排列。我们知道,我们能够移动空块相邻的块,这里的移动相当于一种特殊的对换(相邻对换),例如:对于b图,移动6就相当于9和6互换(9向上移动了),移动7就相当于9和7互换(9向左移动了)。现在假设从b图经过一系列的平移变到了a图,则空格块9必然移动(对换)了偶数次(向左一次必然要再向右一次回来,向上一次必然要向下再回来,最终才能够回到右下角的位置),根据上面的定理最终变成的排列必然是仍然是奇排列(和b相同),然而a图是偶排列,因而产生矛盾,因此b图不可能通过平移变成最终的a图。这种现象主要是由于在打乱图片顺序时是用随机法实现的,这种方法会带来50%无法通过游戏的概率,因此,此游戏需要设计一个板块三轮换的算法来进行有效
本文标题:VB课程设计:拼图游戏
链接地址:https://www.777doc.com/doc-6055904 .html