基于汇编语言实现的彩色黑白棋游戏

邱丑丑

发布日期: 2019-05-28 14:34:20 浏览量: 457
评分:
star star star star star star star star star star
*转载请注明来自write-bug.com

一、软件背景介绍

1.1 背景介绍

黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。它的游戏规则简单,因此上手很容易,但是它的变化又非常复杂。有一种说法是:只需要几分钟学会它,却需要一生的时间去精通它。

黑白棋是 19 世纪末英国人发明的。直到上个世纪 70 年代日本人长谷川五郎将其进行发展和推广,借用莎士比亚名剧奥赛罗(othello)为这个游戏重新命名(日语“オセロ”),也就是现在大家玩的黑白棋。为何借用莎士比亚名剧呢?是因为奥赛罗是莎士比亚一个名剧的男主角。他是一个黑人,妻子是白人,因受小人挑拨,怀疑妻子不忠一直情海翻波,最终亲手把妻子杀死。后来真相大白,奥赛罗懊悔不已,自杀而死。黑白棋就是借用这个黑人白人斗争的故事而命名。

1.2 黑白棋规则

每个“翻转棋”游戏开始时,棋盘上已经交叉放好了四颗棋子。其中两颗是黑棋,另两 颗是白棋,黑棋总是先走。

开局先将双方的棋子按图中一样的位置摆放,黑子先走,如图黄点所示下一步有四种走法。黑白棋的每一步都要翻转对方的棋子才能走。如图 1.2.1

黑子做端点,隔旁边的白子做水平、竖直、斜 45 度的端点放黑子,必须是直线,中间白子都翻转为黑子。如图 1.2.2

到白子走,走法和黑子一相同。白子做端点,隔旁边的黑子做水平、竖直、斜 45 度的端点放白字,必须是直线,中间黑子都翻转为白子。如图 1.2.3

最后看棋盘上放满棋子时,谁的棋子多来判定胜负。如果途中有对方棋子完全被翻转成另己方的颜色,则己方提前获胜。如图 1.2.4

1.3 程序概况

功能需求

本程序是建议的双人黑白棋对战游戏,项目要求是准许双人对战,而且游戏的参与者必须是操作黑棋和白棋的两位不同玩家,双方按照游戏规则进行对局比赛,在用户操作过程中,程序会计时和计数,分别计算用户下棋的时间和目前棋盘中黑白棋的数目。程序按照规则来实现棋子的“翻转”和不同颜色棋子的计数,当棋盘下满时,程序比较不同 棋子的数量来判断胜利者。

性能需求

程序满足用户随时重启战局,也满足随时退出游戏程序,且当棋盘下满时, 对胜负的检测也是实时的。

可靠性和可用需求

对于编程来说黑白棋最重要的两个编程点是黑白棋的“翻转”和 和黑白棋的计数,都可通过简单的编程算法解决,所以本程序在一定范围内时很可靠的,玩家不需要担心游戏运行有问题,由于用户在操作时需要共用一个光标,在操作上可能不方便。

出错处理需求

本程序设计严谨,在多次的测试中还未出现错误,若出现预期之外的错误玩家可以通过 esc 按键及时退出游戏。

操作方法

进入游戏后通过上下左右按键来操作光标的位置,选定合适位置后按下回车可以进行下棋,若该位置无法下棋,按下回车键并不会下棋,当用户下棋后,程序回来判断被包围的棋子,并将棋子“翻转”,同时开始重新计算棋盘中棋子数量,方便用户实时查看。

实用性

本程序严格按照黑白棋的规则,不会有犯规行为发生,同时相比实体黑白棋可以省去计数、“翻转”的过程,游戏有着很高的效率,用户只需要在自己想要的位置下棋 即可完成黑白棋的对战操作,是一个很便捷的程序。

二、核心算法思想

为了在汇编语言中实现黑白棋的基本操作,采用了大量的变成思路来实现黑白棋的双人对弈,经过算法展示出的程序界面如图 2.1 所示,主要包括一下主要步骤:

  • 设计棋盘,黑白棋的程序中,棋盘是程序图像的核心,为了更好的用汇编语言画出棋盘, 通过 lastmousex dw22 和 lastmousesey dw22 来设置棋盘的横纵坐标,展开 8*8 的棋盘

  • 设计棋子,棋盘设计完后应该定义出棋子,定义黑棋和白棋,这里通过定义不同的字符来区别黑棋和白棋,同时引入计数器,计数不同字符组的数量来识别棋子的数量,棋子的数量便是双方玩家的分数,打印输出再记分板上

  • 棋子的下棋步骤,通过 point proc near 来判断光标的位置,引入判断识别函数来判断识别用户的输入按键类别,来判断该位置是否可以下棋,不可以下棋的情况:

    • 该位置已经有棋
    • 在该位置下棋无法“翻转”棋子,如果是这两种情况外便可以下棋,识别后移动光标在棋盘中打印下棋点
  • 棋盘规则,黑白棋的基本规则就是“翻转”棋子,为了判断是否可以翻转棋子,引入了 循环识别函数,循环 64 次(棋盘中共 64 个下棋点),在循环体中要识别一条横、竖、斜线上的临近的棋子颜色和数量,进行颜色的翻转,在“翻转”前要保留 CPU 现场,确定该位置是否可以下棋,当判断识别函数读取到“enter”输入后进行颜色的替换,计数器重新计数读取棋盘中不同颜色棋子的数量并展示在记分板处

  • 记分的计算方法,引入栈和堆来计数黑白棋的数量,每次循环函数读取结束后,要清空栈和堆中的数据,重新进行计数,当黑棋数量加上白棋数量为 64 时,停止循环函数,开始比较黑棋和白棋的数量(分数),输出胜利方

  • 异常处理,引入错误的抛出,程序中引入同一种规则的多种不同算法,在程序运行中可能会出现预料之外的错误,这种错误大多出现在循环结束,所以在程序编写过程中,有多次操作采取的是保存 CPU 现场,当程序进行到崩溃时,抛出异常,返回到保存的 CPU 现场,采用其他算法进行下一步操作,防止程序发生崩溃

  • 交互界面的建立,在逻辑上黑白棋的设计已经构建完成,作为一款有好的软件,应该有着友好的交互界面,为此在汇编语言中引入像素模式,构画出 640*480 的像素模式,在通过对逐个像素点写像素构成黑白棋的图形界面,在图形界面中,逻辑的棋子的逻辑反馈要和图像点之间一一对应

  • 界面设计,期盼主界面建立完成后,将界面分成三块长方形区域,用来安放棋盘,进行到哪位玩家,玩家之间的比分

三、核心算法流程图

核心算法分为两部分,一部分为黑白棋的主函数流程如图 3.1 所示,另一部分为棋盘的绘制函数流程图如图 3.2 所示,其中图 3.3 将主程序的运行流程清晰的展现了出来。

四、开发中遇到的问题

这是第一次运用汇编语言开发程序,在开发过程中遇到了不少的问题,主要包括算法、汇编语言架构、汇编语言编程方面的问题。

4.1 算法问题

黑白棋与五子棋、围棋等棋类不同,黑白棋的棋子并不是任何位置都可以进行落子操作,落子位置必须可以进行“翻转”操作,所以在下棋前要先引入算法判定该位置是否可以落子,落子后开始识别被“翻转”区域的棋子,将棋子进行“翻转”,清空黑白棋子数 量,重新对黑白棋计数,简单的一个“翻转”过程需要:

  • 判断能否“翻转”

  • 落子后开始“翻转”

  • “翻转”结束后开始重新计数,在编程过程中要注意这三个算法的顺序

黑白棋的分类和下法,棋盘的核心是黑棋和白棋的对弈,在解决黑白棋的下棋过程中进行了多重算法的选择,最后找到了一个合理简单的方法,从程序表面来看,这是一个二维平面图,所以数据要用二维数组来表示,数组两个下标可以表示棋盘上的位置,数组元素的值代表棋路上的状态,共有三种情况,分别是 0 代表空格,1 代表白棋,2 代表黑棋, 这样程序的主要工作是接收棋手按键操作,棋手用 Up、Down、Left、Right 控制光标移 动,回车表示落子。如果无棋可走则显示停步信息。一旦接收到回车或者空格,说明落 子,先判断是否有效位置,也就是说已经有棋子的位置不能重叠落子,然后再判断位置能否吃掉对方棋子(根据黑白棋的游戏规则,只能将棋子落子能吃掉对方棋子的位置),如果条件满足则落在该位置,罗姿势执行这样几个步骤,先调用画棋子的函数,激情棋盘的相应位置画上棋子,在调用“翻转”函数,将对手的棋子变成自己颜色的棋子,然后根据吃 掉对手棋子的个数,给自己加上相应的分数和给对手减去相应的分数,再将数组中的相应元素赋值,标志位置已经落子,最后将落子的权限交给对手。

可视化界面的处理,在程序设计过程中,对界面的处理进行了深入的讨论,一种是采用符号化界面,另一种是采用像素化界面,前者设计需要输入各种符号,而且可视化效果很差,后者是一种我们从未接触过的全新算法,为了增强程序的体验效果,开始学习使用构建像素化可使化界面,为了解决逻辑棋子位置和可视化棋子位置,引入了映射函数,实现棋子位置的一一映射,使程序的可视化效果更强。

异常的处理,所有的程序都会发生意料之外的异常,为了提高程序的运行效率,减少错误的发生,要对程序进行合理的异常处理,经过编写实践发现,可能的错误发生在循环体结束后和循环体中算法的位置,“翻转”出现的可能并不是同一种形式,继续采用相同的循环可能会出现错误,在第一编写程序时出现了落子位置偏出棋盘的错误,所以多次保存CPU 现场,利用抛出异常返回之前的状态,抛出异常利用另一种算法继续进行循环体,多次异常则继续采用其他算法,在程序中引用了 4 中不同的算法,各有优势互补,实现程序稳定高效的运行。

4.2 汇编语言的架构问题

不了解程序存储器的作用和使用方法,后来查阅资料发现,在程序存储器中引入程序入口、中断入口、用户程序,要在编写过程中协调好这三者的关系。

不了解用户程序中的大致框架,后来查阅资料发现用户程序中分为,主程序、中断服务程序、用户子程序,在用户程序中要和程序存储器进行对接。

4.3 汇编语言问题

汇编语言是一种低级语言,简单的地址存储变换,在定义过程中有相同类别的定义方式,但是要多次重新定义,一个很简单的循环函数再汇编语言中要不断的重复定义,很多时候会按照固化思维写成 c++语言的表现形式。

编译器版本问题,在合作工程中,由于两人分工,用的并不是同一版本的 MASM 编译器,本来没有问题的程序会莫名报错,后发现是编译器版本的问题,统一了编译器版本和DosBox 版本来解决编译报错的问题。

汇编语言的编程习惯,在接触汇编预言时按照的时 c、c++语言的变成习惯,定义需要的头文件,构造不同的函数,定义主函数,完成程序,在编写过程中运用这种方式发现编写的汇编语言根本无法运行,后来了解到汇编语言分为:

  • 程序结构

  • 变量表示

  • 子程序这三个方面

五、心得体会

通过汇编语言的学习,我认为我不仅仅是学会了一门编程语言。从一开始对这门语言一窍不通,到后来用这个语言写下一个程序,我从中收获了很多。在学习语言的时候一定要记住动手,不要只说不做,这样会行成眼高手低,不管什么样的程序都要 亲手做过才能说会了,不要整天说我不会学不会,其实是你不想学。由于第一次写这样一个程序,我们遇到了许多困难,但我们没有灰心,而是耐心的研究,上网查找大量资料,向周边的人询问,最终解决了问题,这种成就感是无法用言语表达的,但它真的让我更加有动力向前进,最终完成了这个程序。在这个过程中,我发现其实语言并不难,难的只是一个问题的分析过程,只要我们把这个问题分析清楚了,用语言把这个过程翻译过来就行,所以有的小可爱在看一个问题的时候,千万不要直接上手写代码,一定要把过程分析清楚,这样就很容易就把这个代码写出来了。

进入大学后学习了三门高级语言,汇编语言是我学习的第一门低级语言,这门语言不像其他语言那样灵活,由于定位不同,汇编语言的编写思路和高级语言并不同不需要头文件,而且构造函数,引出主函数的过程和高级语言也有很大的区别,在学习这门语言是一定要纠正好自己的编程思路,让程序思路清晰。

由于汇编语言是直接与硬件衔接的,在编写过程中有很多的数据存写,有很多的重复编写过程,在编写过程中不仅要动手、动脑,更要动笔去记录数据目前的所在的寄存器,虽然方法有些落后,编写的过程有些困难,但编写完后的运行效率比高级语言高出好几倍。

在编写这个程序时参考了网上其他语言的编程算法,但是移植到汇编语言中发现不仅仅是移植的问题更有语言环境的适配,一个简单的循环函数,在汇编语言中用大量重复的代码来转换来表示,虽然过程枯燥,但是这也是一个学习的过程,在这个过程中,虽然发现了汇编语言的繁琐的缺点,但是汇编语言有着更快的运行速度,希望以后在学习其他编程算法,编程语言时能够很快的进入状态。

上传的附件 cloud_download 汇编语言黑白棋.docx ( 162.11kb, 1次下载 ) cloud_download 汇编源码.asm ( 29.87kb, 1次下载 )
error_outline 下载需要5点积分

发送私信

精品资源尽在此

45
文章数
0
评论数
最近文章
eject