1、武汉理工大学微机原理与接口技术课程设计四子棋游戏程序设计1设计任务及要求1.1设计任务设计一个四子棋游戏程序,棋盘为8X8(64格),先达到4子成一条线即结束游戏。 (该程序在DOS下运行)。1.2任务要求(1)画出棋盘界面。(2)定义键盘的功能,可以实现棋子左右移动及落子。(3)棋子不能悬空,落子后不能再移动。(4)人、人分别落子。(5)用不同的颜色区分各方的棋子。(6)撰写设计说明书及调试心得。2程序设计思路2.1 主程序及模块链接四子棋的程序中包含许多模块,其中有棋盘的绘制,棋子的绘制以及棋子坐标位置的计算,棋子胜负的算法等等,在主程序中需要将这些模块链接起来。程序主流程图:流程图开始
2、画棋盘控制游戏开始,并且玩家落子写棋子并计算棋子的位子判断棋盘中是否有横,竖,斜线上是否有四子练成直线。是结束继续落子,直到下完否程序运行界面图 图2-1 程序运行界面截图2.2棋盘的绘制本次课程设计要求是绘制8x8格的棋盘,在绘制过程中,需要调用dos 功能调用中的int 10h命令,利用该命令中的多项功能可以完成绘制棋盘中所需要的划线和填充颜色,从而绘制出8x8格棋盘! 开始划线划横线 画竖线完成格子颜色的填充 完成划线 绘制棋盘程序代码:ro rcolor,rrow,rcol,endcol ;调用划线的命令 local rline1 ; line horizon mov dx,rrow
3、mov cx,rcol rline1: mov al,rcolor ;调用int 10h 中的och功能 mov ah,0ch int 10h inc cx ;累加1的功能 cmp cx,endcol ;比较cx和endcol的大小 jl rline1 ;小于就再循环执行一次 endm段程序中, dx的值没有变化,不断的累加cx的值,不断的写像素,从而达到画横线的功能.cline macro color,crow,ccol,endrow ;画竖线 local cline1 ;line vertical mov dx,crow mov cx,ccol cline1: ;和上一段的程序相似 mov
4、 al,color mov ah,0ch int 10h inc dx cmp dx,endrow jl cline1 endmdx的值没有变化,不断的累加cx的值,不断的写像素,从而完成画横线的功能。mainfrm proc near ;主框架的设计 rline 1,65,1,640 ;画横线 rline 1,415,1,640 cline 1,65,480,415 ;画竖线 blockpos 9,64,640,1,1 ;for upbackground ;在整个的界面中有8个颜色区, 程序的功能就是在横向-纵向分别写像素,可以使的整块都有颜色. linechess proc near ;画
5、棋盘 mov dx,90 ;init row hline: mov cx,90 ;init column hdot: mov al,0fh ;set color;调用的int 10h 的0f功能,使的画出的线可以用颜色. mov al,0fh int 10h inc cx cmp cx,250 jle hdot ;小于或等于就跳转,重新执行 add dx,20 ;距离为20再画一条线 cmp dx,250 jle hline ;不断的画,一共9条 ;end of 15 hline mov cx,90 ;和上面的相似 vline: mov dx,90 vdot: mov al,0fh mov a
6、h,0ch int 10h inc dx cmp dx,250 jle vdot add cx,20 cmp cx,250 jle vline ;end of 15 vline ret linechess endp2.3绘制棋子绘制棋子模块的作用是根据鼠标返回的象素坐标写一级棋行表和界面对应的棋子,以准备进入二级棋行表进行判断。首先确定一个圆心,定义cx、dx,确定棋子半径R,将棋子半径R赋值给cx、dx,cx+dx-R0则添加象素,否则dx减1,继续判断,直至dx为0,dxR,cx依次减1,直至为0,如此作出的是1/4圆,其余3/4圆按对称的方法作出。程序流程图:开始在(X+Si,Y+Di)
7、 (XSi,Y+Di)(X+Si,YDi) (XSi,YDi) 这四点写象素DEC SiSi0?DEC Di Si=R结束(X+Si)*(X+Si)+(Y+Di)*(Y+Di)R*R 0 ? mov dx,y ; 0 in circle mov cx,x call writeb ;write pit in (x,y) add dx,di add cx,si call writeb ;write pit in (x+si,y+di) sub cx,si sub cx,si call writeb ;write pit in (x-si,y+di) mov dx,y mov cx,x sub dx
8、,di sub cx,si call writeb ;write pit in (x-si,y-di) add cx,si add cx,si call writeb ;write pit in (x+si,y-di) nextd: dec si cmp si,0 jl nextdb jmp loopy nextdb: dec di cmp di,0 jl exitdb jmp loopx exitdb: call mouseshow pop di pop si pop bp ret showbchess endp writeb proc near mov al,0 mov ah,0ch in
9、t 10h exitw: retwriteb endp2.4鼠标功能及界面信息的实现运用int 21h,int 10h,09h等 BIOS中断及功能调用,通过输出的字符串提示,使用户比较方便的运行程序。printwelcome proc near setcursor 1,20 ;设置光标位置 mov bx,offset m2 ;取m2的偏移地址给bx output: call delay1 ;调用delay1延时函数 mov al,bx cmp al,? ;循环比较,判断输出字符 je exit0 mov ah,02h mov dl,bx int 21h inc bx jmp output e
10、xit0: ret printwelcome endp光标,信息块及填充颜色块的宏定义和鼠标的功能调用。mouseinit proc near ;鼠标复位 mov ax,0 int 33h ret mouseinit endp mouseshow proc near ;显示鼠标光标 mov ax,1 int 33h ret mouseshow endpmouseshut proc near ;隐藏鼠标光标 mov ax,2 int 33h ret mouseshut endp mousestau proc near ;读鼠标光标 mov ax,3 ;return button status i
11、n bx int 33h ;horizion in cx ;vertical in dx ret mousestau endp mousepressed proc near ; 按鼠标光标 mov bx,0 ;check for left button mov ax,5 ;return statu in ax int 33h ;num in bx ;horizion in cx,vertical in dx ret mousepressed endp mouseliberty proc near ; 释放鼠标光标 mov bx,0 ;check for left mov ax,6 ;liber
12、ty mouse int 33h ret mouseliberty endp2.5胜负判断胜负判断的算法:该算法的作用主要是判断玩家的落子后是否构成胜负关系,以及给出胜负的具体一方,该算法主要是在一个长度为64的存储区段来表示一个8x8的数组,其中由一级棋行表传入的部分只占据在其中一个位置,周围一圈的位置的数据用来判断是否结束一行判断。程序流程图:开始 结束开始斜向方法与行测试,异同同上开始列测试,方法与行测试在个数据在地址距离游差别外其他一样转到下行的起始元素转到下个元素是否构成胜负开始行测试。数据移到BX 开始另一个斜方向的测试,异同同上一行是否测 完是否全部测完 程序源代码:datare
13、a segment qixingbiao1 dw 64 dup( ?) zancun dw ? mess1 db you win,0dh,0ah,$ mess2 db you loss ,0dh,0ah,&datarea endsprognam segmentmain proc farassume cs:prognam,ds:datareastart: push ds sub ax,ax push ax mov ax,datarea mov ds,ax;MIAN PART OF THE PROGNAM IS HERE mov cx,0 mov di,0 mov si,36yici: call
14、hcs ;开始行测试 add si,4 inc di sub di,7 ;判断是否所有行已测完 jbe yic1 mov cx,0 ;开始列测试 mov di,0 mov si,34yici1: call lcs add si,4 inc di sub di,7 ;判断是否所有行以测完 jbe yici1 mov cx,0 mov di,0 ; 开始撇测试 mov si,34yici2: call pcs add si,4 inc di sub di,7 ;判断是否所有行已测完 jbe yici2 mov cx,0 mov di,0 mov si,9yici3: call ncs ;开始捺测试
15、add si,4inc disub di,7 ;判断是否所有行已测完jbe yici3retmain endphcs proc nearhengceshi: mov bx,qixingbiao1si ;测试一个数据 mov ax,bx cmp x,6 jz exit1 ;如在二级棋行表的边界则退出 mov zancun,siheng: mov ax,qixingbiaosi ;是否有棋子 sub ax,8 jz exit mov ax,qixingbiao1si ;是否为同色棋子 sub ax,bx jnz next ;不是,转测反向 call bjlj ;是,累加CX判断 add si,2
16、;到右侧的数据继续判断 jmp hengnext: mov si,zancun ;恢复被判断棋子的位置 ub cx,1hengf: mov ax,qixingbiao1si ;测反方向, cmp ax,8 jz exit ;是否为有棋子 mov ax,qixingbiao1si sub ax,bx ;判断棋子是否同色 jnz exit ;不是 到下个元素判断 call bjlj ;是 继续累加判断 sub si,2 jmp hengf ;转左边继续判断exit: mov si,zancun ;恢复棋子在棋行表的位置 add si,2 mov cx,0 jmp hengceshi ;继续下个元素
17、的行测试exit1: rethcs endplcs proc nearlieceshi: mov bx,qixingbiao1si ;测试一个数据 mov ax,bx cmp bx,6 jz exit3 ;如在二级棋行表的边界则退出 mov zancun,silie: mov ax,qixingbiaosi ;是否有棋子 sub ax,8 jz exit mov ax,qixingbiao1si ;是否为同色棋子 sub ax,bx jnz next ;不是,转测反向 call bjlj ;是,累加CX判断 add si,16 ;到上方的数据继续判断 jmp lienext1: mov si,
18、zancun ;恢复被判断棋子的位置 sub cx,1lief: mov ax,qixingbiao1si ;测反方向 cmp ax,8 ;是否为有棋子 jz exi mov ax,qixingbiao1si ;判断棋子是否同色 sub ax,bx jnz exit2 ;不是 到下个元素判断 call bjlj sub si,16 jmp life ;转下方边继续判断 exi2t: mov si,zancun ;恢复棋子在棋行表的位置 add si,2 mov cx,0 jmp lieceshi ;继续下个元素的行测试exit3: retlcs endppcs proc nearpiecesh
19、i: mov bx,qixingbiao1si mov ax,bx cmp bx,6 jz exit4 ; 如在二级棋行表的边界则退出 mov zancun,si;pie: mov ax,qixingbiaosi ;是否有棋子 sub ax,8 jz exit5 mov ax,qixingbiao1si ;是否为同色棋子 sub ax,bx jnz next3 ;不是,转测反向 call bjlj ;是,累加CX判断 add si,30 ;到左上方的数据继续判断 jmp pienext3: mov si,zancun ;恢复被判断棋子的位置 sub cx,1pief: mov ax,qixin
20、gbiao1si ;测反方向 cmp ax,8 ;是否为有棋子 jz exit mov ax,qixingbiao1si ;判断棋子是否同色 sub ax,bx jnz exit5 ;不是 到下个元素判断 call bjlj ;是 继续累加判断 sub si,30jmp pief ;转右下方继续判断exit5: mov si,zancun ;恢复棋子在棋行表的位置 add si,2 mov cx,0 jmp piecesiexit1: rethcs endpncs proc nearnaceshi: mov bx,qixingbiao1si mov ax,bx cmp bx,6 jz exit
21、6 ;如在二级棋行表的边界则退出 mov zancun,sina: mov ax,qixingbiaosi ;是否有棋子 sub ax,8 jz exit7 mov ax,qixingbiao1si ;是否为同色棋子 sub ax,bx jnz next4 ;不是,转测反向 call bjlj ;是,累加CX判断 add si,14 ;到右上方的数据继续判断 jmp nanext4: mov si,zancun ;恢复被判断棋子的位置sub cx,1naf: mov ax,qixingbiao1si ;测反方向 cmp ax,8 ;是否为有棋子 jz exit mov ax,qixingbia
22、o1si ;判断棋子是否同色 sub ax,bx jnz exit7 ;不是 到下个元素判断 call bjlj ;是 继续累加判断 sub si,2jmp hengf ;转左下边继续判断 exit7: mov si,zancun ;恢复棋子在棋行表的位置 add si,2 mov cx,0 jmp hengceshi ;继续下个元素的行测试exit16: rethcs endpbjlj proc near inc cx ;累加 sub cx,5d ;是否四子连珠 jz mess ;给出信息 retmess: mov cx,qixingbiao1si ;白方胜 sub cx,7 jz winw
23、 mov dx,offset mess1 mov ah,09h int 21h retwinw: mov dx,offset mess2 ;黑方胜 mov ah,09h int 21h retbjlj endpprognam ends end start3程序设计小结 通过运用MF2KP软件对程序进行测试。对每一个程序模块进行单独的测试,从中找出问题,一次次的调试与验证。最后将所有测试完毕后的模块程序链接起来,再次进行测试和修改,得到完整的程序。当然,在设计过程中遇到一些不清楚的环节,比如棋盘绘制中需要调用的int 10h功能等,最后通过请教同学和查阅资料找到了答案。还有在绘制棋子的过程想过很
24、多方法绘制棋子,最后选择通过绘制圆的方法绘制出棋子。总之,在编写程序的过程中遇到很多问题,最后和小组成员一起通过不懈地努力很好的解决了问了,完成课程设计。4心得与体会这次课程设计使我使我认识到我在汇编语言学习上的很多严重不足,现在算法编制不简洁,程序冗长,出现即使是自己编写的也造成很难读懂的情况,对一些命令认识有很大的疏漏,对命令的含义和使用方法理解的不够深刻,造成编写的垃圾代码过多。通过这次的课程设计,对我的汇编语言的编程方法掌握时有很大帮助,我发现并解决了平常一些不明显但实际上却很严重的问题,我对模块化的编程方式也有了更深的理解,我想我会在以后的课程设计中克服这次课程设计所暴露的问题,不在烦类似的错误。软件的设计依靠团体中的每一个人共同努力,相互协作,才能做到最好。学习计算机专业需要广泛的知识,不能仅依靠课本的东西程序设计需要勤练习,多上机,多调试。参考文献【1】微机原理与接口技术 周佩玲 彭虎 电子工业出版社【2】汇编语言程序设计 沈美明 清华大学出版社【3】微型计算机原理与接口技术 吴秀清 中国科学技术大学出版社【4】微型计算机系统原理及应用 周明德 清华大学出版社【5】微型计算机技术及应用 戴梅萼 清华大学出版社22