基于80x86汇编的五子棋游戏
一、游戏背景介绍
1.1 背景知识
当今,大有风靡全球之势的五子棋,就是起源于中国的黑白传统棋种之一。五子棋的发明,体现了中华民族对智慧的追求,是中华民族逻辑思维和形象思维双翼齐飞的智慧结晶。五子棋规则简明,对弈场地、用具简单易行。棋道变化无穷,与几千年的中国古代文明交融。现代竞技连珠五子棋使凝集着古代精华的棋理进一步得到传承,成为东西方文化交互在一起的璀璨明星。国粹五子棋堪称我国古老文化的瑰宝,是祖国宝贵文化遗产的一部分,五子棋的发明是中国为人类文明做出的贡献。
五子棋将科学、艺术、竞技、娱乐与教育五者融为一体。对弈五子棋,对自己可以启智静心,与别人可以进行和谐交流。不分智商高低,老少皆宜。现今已成为深受中国乃至世界广大民众所喜爱的一项智力体育项目,已逐渐发展成为国际性文化体育交流不可缺少的内容之一。
五子棋的下法是,对弈双方各执黑或白一色棋子,在棋盘上面,黑方先,白方后,交替落子于交叉点上。棋子落下后不能移动,没有吃子。黑方或白方哪一方先在棋盘的横、竖、斜方向的同一条直线上,由同色子连成五连为胜。五子棋的称谓多种多样,“连五子”、“五子连”、“五格”、“串珠”、“五目”、“五目碰”等。现代日本称五子棋为“连珠”(renju),由于把民间游戏的五子棋改良成竞技的努力主要来自日本,所以用“连珠”称谓五子棋流行于世界。国际上的一些组织或赛事,也多以连珠命名。如世界上大的五子棋民间组织称为“国际连珠联盟(RIF)”,世界上五子棋大正规的民间赛事称“世界连珠锦标赛”等。“连珠”这个词似乎比“五子棋”更有诗意,但五子棋界很多人,包括一些日本人在内均认为“连珠”的叫法似乎不如叫“五子棋”准确。
不同国家和地区还各有自己对五子棋的不同爱称,韩国人把五子棋称为“情侣棋”,意指五子棋能增加情感的交流,欧洲人称五子棋为“绅士棋”,喻棋手下五子棋的君子风度胜似绅士,美洲人取其贸易价值,可以边谈生意边下五子棋,称五子棋为“商业棋”。
1.2 基本功能
进入游戏后先选择游戏模式和棋子颜色,打印棋盘后玩家输入坐标后落子。玩家可以选择落子位置,系统判断玩家落子是否合理,是否胜利。待有一个玩家的棋子横向,纵向或斜向连成5子后胜利。
1.3 运行截图
二、核心算法思想
棋盘区域由许多等面积的小方块构成,这些区域状态只有有子棋或无棋子两种。将空间以静态二维数组实现,并预先定义其状态值。满为1,空为2,以此来完成游戏地图区域的空间分配。
游戏需要知道目前的状态,所以在程序中加入数码管显示程序,设置一个参数STATE,0到5不同的数字代表游戏不同的状态。
游戏开始后先选择游戏的模式,输入1代表单机模式,输入2代表双机模式,如果输入ESC则退出游戏。选择玩游戏模式1后,可以选择自己棋子的颜色,然后打印棋盘,屏幕提示输入自己的坐标,如果输入坐标不合法系统会报错并发出声音,如果你输入的坐标位置已经有棋子不为空系统也会报错,发出声音。如果输入的坐标正确并且此处没有棋子,则可以落子然后判断是否横向,纵向,斜上,斜下连成五子,连成五子则获胜游戏结束,没有连成五子则轮到电脑下;重复上述操作直到有一方连成五子后,游戏结束。选择玩游戏模式2后,直接打印棋盘,不能选择棋子颜色,玩家一为黑棋,玩家二为白棋,玩家一先落子。玩家一输入坐标后判断是否合法,坐标位置是否有棋子,是否连成五子,如果没有连成五子那轮到玩家二下,玩家二重复上述判断,直到有一玩家连成五子后游戏结束,屏幕显示有一个玩家已经胜利的信息。
本游戏界面简单,操作不复杂。进入游戏后界面背景为黑色,棋盘为灰白色,棋子上带着小笑脸,这些都可以调整。棋盘有15行,15列共225个棋盘落子点,符合标准棋盘的规格,可以让玩家有更多的战术和策略去实施。
游戏的声音控制由扬声器和播放音乐两个子程序控制。扬声器控制声音的发出,先保存cpu现场,设置一个计数器写入低8位计数值和高8位计数值,设置输出值的端口地址,然后设置PB0和PB1的端口地址以便以后判断,当PB0和PB1都为高电平时扬声器才能发声。播放音乐子程序控制音乐的信息和语调,将频率表和节拍时间分别赋给两个变量,以8253的2号计数器为核心。系统初始化时,2号计数器I作在“方波发生器”方式,初值为二进制数,,写入顺序为先低后高,CLK2为1.193182MHz,当计数初值为533H时,OUT2输出的方波大约为900Hz,经过简单的滤波之后,送至扬声器。改变1、4号计数器的计数初值就可以使扬声器发出不同频率的音响。 ROM BIOS 中有个BEEP子程序,这能根据BL中组出的时间计数值控制825定时器,产生持续时间为1个或几个0.5秒,频率为896HZ的声音,我们可以利用并修改BEEP,使其产生任一频率的声音。为此我们需要做两点修改,首先,BEEP程序只能产生896HZ的声音,我们的通用发声程序应能产生任一频率的声音。其次,BEEP产生声音的持续时间(音长)只能是0.5秒的倍数,我们希望声音的持续时间更易于调整,例如可以是10ms的倍数。
游戏中还有一个重要的子程序,中断子程序。中断服务程序,事先编好程序在程序问题时直接使用,中断程序时先保护被中断进程现场.为了在中断处理结束后能够使进程准确地返回到中断点,系统必须保存当前处理机程序状态字,分析中断原因,转去执行相应的中断处理程序.在多个中断请求同时发生时,处理优先级最高的中断源发出的中断请求. 恢复被中断进程的现场,CPU继续执行原来被中断的进程。如果输入坐标处中断,则清除刚保存的x y值并提示输入错误,重新输入无误后,会打印到棋盘上并清除刚才的错误提示信息的重新输入信息。
如果有人获胜或有人退出时,先把信息保存到寄存器,然后从指定的端口地址将信息发出,然后在屏幕中显示获胜或退出的信息。
三、核心算法流程图
进入程序后先进行屏幕初始化,之后显示调用显示边框函数,再显示棋盘。
检测按键状态,之后再度检测键盘状态。
棋子的制作:首先确定一个圆心,定义cx dx,确定棋子半径R,将棋子半径R赋值给cx dx,cx²+dx²-R²≤0则添加象素,否则dx减1,继续判断,直至dx为0,dx=R,cx依次减1,直至为0,如此作出的是四分之一圆,其余四分之三圆对称的方法作出。
五、开发中遇到的问题
5.1 如何让游戏知道目前是否有人获胜或有人退出等状态?
写一个数码管显示子程序,设置一个参数STATE,数码管根据STATE输出数字。数码管显示状态,0表示该我下,1表示等待对方下,2表示我赢了,3表示我退出,4表示对方赢了,5表示对方退出,不同的数字代表了不同的状态。数码管的数字不会显示在屏幕上,如有需要直接调用一次方便对目前状态的判断。
5.2 如何判断落子位置是否合法?
首先判断用户输入对的X坐标,如果用户输入的是字母若输入的值小于a或大于f都会报错,提示用户重新输入;如果用户输入的是数字,若输入的数字小于1或大于9报错,提示用户重新输入。报错以后会把刚输入的不合法数据清除。如果用户输入的X坐标合法则进行Y坐标的判断,Y坐标的判断数字判断与X坐标一样,但字母判断比较的是A和F。如果X和Y坐标都输入合法,将X和Y的坐标保存。将棋子右移15个字节然后与棋盘变量比较,若为1则表明此处已有棋子,输入的坐标就位置就不合法;若不为2且不等于1则表明此处没有棋子,则用户输入的坐标合法即可以在此处落子。
5.3 输入错误时怎么发出声音?
用了2个子程序分别是鸣响扬声器和播放音乐。先用播放音乐子程序,将频率表偏移地址送给SI,将将节拍时间表偏移地址送BP,然后将频率值送入DI寄存器并设置播放的时间,这是播放声音然后调用SOUND子程序发出声调,先保存CPU现场初始化8253控制寄存器,使其计数器产生方波信号将43H设为端口地址,设置一个被除数将1234DCH的值送入AX寄存器,其商为(AX)预置值。将AX先送入最低有效位再送入最高有效位,然后读取8225控制1寄存器端口B(61H)的原值并保存。开扬声器并接通扬声器,有扬声器直接控制发声,先写入低8位计数值再写入高8为计数值,从端口地址为41H的端口输出,当PB0,PB1同时为高电平时扬声器才能发声。发声中先初始化字符指针,字符指针左移一个字节到最左端,发声结束后用户可换行重新输入。
5.4 怎样判断是否获胜?
先判断黑子或白子在此处是否可以落子,如果不可以则报错提示用户不可以在此处落子重新输入坐标;如果可以落子则调用4个判断子程序来检测横向,纵向,斜上,斜下来判断是否获胜。横向判断,先比较横方向上是否还有10字节位置如果没有则横向不能连成5个,如果有则与CHESSBOARD[BX+1],CHESSBOARD[BX+2],CHESSBOARD[BX+3],CHESSBOARD[BX+4]比较,前三个不满足则不能连成5个,最后一个则可以连成5个,置OVER为1有结果返回。纵向判断,先比较纵向上是否还有10字节位置如果没有则纵向不能连成5个,如果有则分别与CHESSBOARD[BX+15],CHESSBOARD[BX+30],CHESSBOARD[BX+45],CHESSBOARD[BX+60]比较,前三个满足则不能连成5个,最后一个则可以连成5个,置OVER为1有结果返回。斜上判断,先比较斜上是否还有4字节位置和横向是否还有10个字节位置如果没有则斜上不能连成5个,如果有则与分别与CHESSBOARD[BX-14],CHESSBOARD[BX-28],CHESSBOARD[BX-42],CHESSBOARD[BX-56]比较,前三个不满足则不能连成5个,最后一个满足则可以连成5个,置OVER为1有结果返回。斜下判断,先比较纵向,横向分别还有10字节位置如果没有则不能连成5个,如果有则分别与CHESSBOARD[BX+16],CHESSBOARD[BX+32],CHESSBOARD[BX+48],CHESSBOARD[BX+64]比较前三个不满足则不能连成5个,最后一个满足则可以连成5个置OVER为1有结果返回。
六、心得体会
在本次编写五子棋汇编游戏中,我,通过大量查阅资料,请教老师和同学收获了很多知识的同时,还提高了实践能力。课程伊始,我便意识到汇编语言绝不是轻易能弄懂的。相较于曾经学过的c和c++语言,电脑等于在迁就人的思维方式,但汇编语言却是接近机器语言的一门语言,首先要搞清楚各种指令的用法和功能,了解了80X60指令系统和寻址方式,汇编语言学习不仅仅是学习其语法而更多的是学习计算机基本的体系结构。还有一点十分重要,跟所有的程序设计语言一样,要学好汇编语言,实验是必不可少的环节。我深有体会:书上的程序能看懂,基本原理也都都明白,但是亲手编写程序时却无从下手,甚至连第一句都不知道该怎么写。现在汇编语言的学习也告一段落了,在学习过程中遇到的难题都需要在其余时间逐步消化,进一步了解相关的游戏编程知识。
游戏的设计需要对设计对象有足够的分析了解,对编程语言熟悉掌握,并且依靠团体中的每一个人共同努力,相互协作,才能做的好;而且在程序的设计中需要的也不仅仅只是课本上的东西。拥有广泛的知识是程序设计成功的另一基础。这次的课程设计加深了我对汇编这门课程的了解:刚开始学习这门课程的时候,我认为汇编语言只比电脑执行的机器语言高一级,学习复杂功能有限,因此我也没有把这门语言学的很好。经过这次课程设计,我才明白汇编语言简洁精练,最快又最有效,并且能够充分利用计算机的硬件特性直接控制硬件。