毕业论文

象棋棋谱管理系统的设计与实现

作者:论文空间  栏目:计算机论文     更新时间:2019-12-10 08:42   浏览

 
  摘要:本文介绍的中国象棋棋谱管理系统为易语言编写,软件布局参考了一些已经发布成品产品,易语言为一门使用面向对象的语言,且全中文编程,代码自动格式化,且方法名基本上都能见名知意,类库丰富[1],易于上手,因而适合于编写小型工具类型软件。
  系统的编写将用到之前所学课程中的一些理论,如自动机、共享访问控制等,对于全面理解面向对象并将所学的理论知识用于实践大有裨益。
  关键字象棋 棋谱 摆谱 演示 象棋棋谱管理系统
  内容提要
  本文将逐步大致介绍象棋棋谱管理系统的编写以及在其中遇到的问题;作为一款软件,通常都是大致分为 3 步:
  ①设计
  ②编码
  ③测试
  其中最关键的就是设计,它是一款软件的灵魂。
  设计时要均衡考虑功能的合理性以及实现难度,以及为之后可能存在的拓展作出预留空间。
  本系统主要涉及数据库、多线程、画板,3 方面组合起来就是本软件的基本骨架。
  第 1 章 分 析
  1.1 需求分析
  从字面意思来看,这个选题最终至少有 2 个要求:
  1. 存储象棋棋谱;
  2. 能管理象棋棋谱;
  结合着生活中的经验,如果仅仅是简单满足这两个要求并没多大意义,顶多算是 数据库课程的一个作业罢了,谈不上设计;另外,作为 1 款与象棋相关的软件,支持对弈算是天经地义的事情,再者,软件是给人使用的,棋谱也是给人使用的,仅仅能 存储和管理棋谱也没多大意义,棋谱的意义在于可以随时查看下棋过程以及尝试打谱, 或者自己新建棋谱对弈并存储起来;因而结合上述原因,最终设计出的软件必须满足 以下要求:
  1. 棋谱的管理(新建、删除、搜索)
  2. 对弈
  3. 棋谱演示
  4. 打谱
  作为一款软件,稳定性十分重要,故而棋谱数据的存储应当使用数据库,而不是自己简单设计出 1 种数据存储结构。
  结合个人经验,既要能便捷使用数据库,又能快速可视化开发,并且效率不能太差,易语言满足这个要求,首先 FoxPro、Visual Basic 都已经非常老旧,而且语法与主流编程语言有一定差异,故不考虑,C/C++支持可视化开发,但使用数据库却有点 麻烦,需要通过 ODBC 来连接数据库,这就要求客户机自身必须安装有一款数据库软件,并且还预先需要配置好连接,故而也不优先考虑,JAVA 的话则需要安装 JVM, 而且不支持可视化快速开发,也不优先考虑。
  易语言则既支持快速可视化开发,并且自带数据库(也支持通过 ODBC 连接第三方数据库),并且支持独立打包编译(将运行所需的库直接打包到可执行文件内部),故而客户机无需安装支持库即可直接运行,同时易语言的支持库也比较丰富,是 1 门面向对象的语言,语法与 C/C++类似,基本是 C/C++的中文翻译,使用起来难度不大,当然易语言也有自身的缺点,比如运行效率比不上 C/C++,并且不适合于开发大型项目,然而本项目也许在初学者眼中比较大,但在软件开发角度来看并不大,因此综合上述原因,使用易语言开发这款软件比较合适。
  1.2 可行性分析
  从技术角度来看,实现本软件的难度并不大,因为易语言对常用的 API 进行了高度封装,例如在 C/C++中想要将文本复制到剪贴板基本需要调用好几个函数才能做到, 而在易语言中调用 1 个方法就可以做到:逻辑型 置剪辑板文本(“此处表示被复制的 文本”),其他涉及到的 API 也都是经过高度封装的,使用方法都比较简单。
  从软件的功能上看,逻辑稍微复杂一点的地方也就是人机对弈和棋盘导入过程中的有效性校验。
  综合上述原因,使用易语言开发象棋棋谱管理系统可行。
  第 2 章 总体设计
  2.1 项目规划
  系统将分为以下模块:
  ①棋盘画面绘制
  ②双人对弈
  ③人机对弈
  ④棋谱管理
  ⑤棋谱演示
  ⑥摆谱
  ⑦棋盘导入
  ⑧多开检测
  ⑨皮肤更换
  2.2 系统功能
  根据上述的项目规划,系统的各项功能划分如下:
  3.3 数据库设计
  首先,每个棋谱都需要自己的名字,以及备注,另外还要保存棋局的对战情况, 然后得有棋谱的作者以及修改时间,便于在资源共享时确认棋谱的来源以及是什么时候的创建的,另外还需要有一个“备注”字段,以便出现不时之需,且在创建数据库时允许设置密码来保护数据安全。
  综合以上情况,设计出数据库结构如下:
  说明:文本型后的数字代表长度限制,每个中文字符长度为 2,英文字长度为 1, 备注型实际上是长度接近于无限的文本型,而文本型则有着长度限制,故而备注使用备注型而不是文本型
  其中最后一个字段存储棋谱的具体内容(仔细来说就是一堆字节数据),由于之后的功能需要能迅速查看棋谱的起始局势和结束局势,于是其中必须存储起始和结束时的棋盘,当然理论上只要存储了双方走法和起始或结束棋盘中的任意 1 个棋盘,很容易就推出第三者,但实际应用中,由于双方对弈步数可能比较多,点击查看时才临时进行推理显然不行,很容易招致软件卡顿,故而同时存储了起始和结束局势。
  3.4 软件流程设计
  首先,作为 1 款与象棋相关的软件,提供简单的对弈功能算是责无旁贷,并且对
  弈功能可以仅仅只是简单的对弈,而不保存,因此可以考虑在未打开数据库的情况下允许对弈,而摆谱打谱导入棋盘则不然,都会涉及到存储的问题,故而均设计成只允许在打开数据库之后才允许进行的
  3.5 主要功能模块设计
  3.5.1 主界面设计
  左侧放置游戏画板,供用户使用鼠标操作,右侧放置表格框和对应记录的详细信息,便于用户查看与复制(只读,不允许编辑),控制按钮对齐居中放在中间,软件在运行过程中将根据具体情形禁用或启用部分按钮指示当前哪些操作可用,具体布局如下:
  3.5.2 功能设计
  3.5.2.1 棋盘画面绘制
  首先,棋盘由 4 层构成,最底层的是背景,接着是棋盘网格,然后是棋子,最后是光标(提示用户移动的是哪些棋子,因为程序没有设计棋子移动的动画,而画板刷新的速度非常快);而画板实际上表现出来是只有 2 层的,当前景完全空白时(默认) 就会自动露出背景色,而在棋子的移动过程中必然会将部分棋盘网格覆盖掉,而在棋子移走后又需要恢复原始位置的棋盘网格,很自然会有个想法:每次移动时都全盘重新绘制一遍,理论上解决了棋盘方格的问题,实际上也是可以的,但是很容易就会发现一个问题,由于画板面积较大,并且需要绘制的内容比较多,频繁重新绘制会导致画板出现闪烁情况,且会非常耗费 CPU,而实际每次移动棋子虽然画板需要重新绘制,但绝大部分图像都没有发生变化,故而考虑使用另一个画板保存好棋盘网格,当棋子移动时,只局部进行重画,不但减少 CPU 的耗费,还能避免画板闪烁。
  其中黑色的方格极为绘制出的效果,后面的黄色背景以及“楚河汉界”的字样均为背景图案,可以很明显的观察到文字有模糊现象而方格则相当清晰,当然完全可以直接拿一副棋盘图片作为背景,这样就不需要绘制方格了,当然为了最终效果更清晰, 本程序没有使用这种方法,而是直接选择了直接用画板命令进行绘制。
  作为可见的棋子,它本质上来讲就是 1 张图片,当然在此之前先得对棋子进行编号,然后存储起来,棋盘有 10 行 9 列,由于会在整个软件的很多地方用到,故而本质上来说就是 1 个矩阵,10 行 9 列,如果该位置没有棋子则置为 0,若有棋子,则存储该棋子的编码(棋子编码:2 - 黑车,3 - 黑马,6 - 黑象,5 - 黑士,1 - 黑帅, 4 - 黑炮,7 - 黑兵,9 - 红车,10 - 红马,13 - 红象,12 - 红士,8 - 红将,11 - 红炮,14 - 红兵,字节型表示存储-128-127 的一个整数),当需要绘制棋子时首先按照棋子编号加载棋子图片(图片作为资源存在,运行后全部加载到内存,此处的加载表示拿到图片的地址便于直接使用,故而可以反复加载卸载),然后根据棋子在棋盘上的坐标计算出棋子的位置然后在绘制到棋盘画板上即可(支持局部覆盖修改画面)。
  由于绘制棋子的方法将在很多场合用到,故而需要先将对应位置的方格复制到草稿画板,然后再将棋子图片加到草稿画板上,最后再将绘制好的草稿直接复制到游戏画板上,从而达到绘制棋子的目的。之所以用到 1 个草稿画板也是为了提高画面的绘制效率,游戏画板面积大,而草稿画板则面积非常小(44x44),直接在游戏画板上进行图形合成固然可行,但由于棋子数量不少,最终仍然会影响画面的绘制效率。
  先不考虑光标的问题,棋子的移动本质上来说就是将起始点的棋子擦去,然后在目标位置绘制上棋子的过程,而棋盘方格已经保存到了备用画板中,故而只需要将备用画板的对应起始位置画面复制到游戏画板的对应位置即可擦去起始位置的棋子,然后再在目的位置绘制上棋子即可。
  然后是光标的问题,由于画板绘制速度较快而且是局部绘制,一旦棋子移动基本就是一闪的速度就完成了,如果不加入光标那么对弈的体验可想而知了,用户得花大量时间去寻找双方到底移动了哪个棋子,光标并不复杂,只需要将对应位置的画面(连同网格和棋子)一起复制到草稿画板然后向草稿画板上加入光标,再重新画回原位置即可(同样的问题,直接复制画面很简单,而合成画面则比较费事,因为涉及到透明度和部分颜色过滤的问题)棋谱的演示本质上来说就是从棋谱中取出起始棋盘信息,然后绘制出对应的棋子位置,再读出双方的走法,然后依据双方的走法定时移动对应棋子并修改对应的棋盘数据(目的是为了棋子绘制方法复用)直至步数最终走完即可,并且由于双方对弈步数不确定,为避免用户焦虑,演示时将在窗口最底端显示 1 个演示进度条。
  此处必须使用多线程,原因是一旦使用 UI 线程进行演示将会导致 UI 层不能及时响应用户的操作从而导致体验感极差(操作系统将提示用户是否强制关闭软件)。 演示方法:
  首先根据历史记录确定演示的轮数,也就是图片里的行数,然后根据走法(相当于数学中的向量,只不过同时记录了起始和终点)来轮流移动棋子
  3.5.2.2 棋谱管理
  首先利用通用对话框要求用户选择一个保存位置并设置数据库文件的名称,使用通用对话框可以保证最终要选择的文件可以顺利被创建,并且当用户选择了创建位置后将会提示用户设置数据库密码(可选)。
  首先通过通用对话框要求用户选择 1 个已有的数据库文件,通用对话框可以保证用户选择的数据库文件一定存在,然后使用易语言的内置方法直接打开数据库文件。
  当检测到数据库已经加密的情况下将要求输入密码,然后使用数据库的 API 函数从数据库中读出记录写到表格框中,当鼠标点击更改了表格框的选中项时就把对应的记录信息写入到文本编辑框中,其中文本编辑框均为只读,以供用户查看和复制。
  注意:为避免通过修改数据库破坏运行时数据,打开数据库后软件将一直独占锁定数据库文件,并禁止其他任何进程访问数据库文件。
  选中表格框中的 1 条有效记录,删除棋谱按钮将自动解除禁用,点击后将立即删除选中的棋谱,同时光标尝试移动到下一条记录,若当前删除的已经是最后一条记录则直接跳到最后一条记录,单条棋谱删除操作影响不大,故而不需要二次确认。
  调用数据库 API 删除即可清空当前数据库(已经打开),由于影响大,需要二次确认,确定后数据库中的记录将立即全部清空,且不可恢复。
  当在表格框中选择了一条有效记录时,载入初始棋盘按钮将自动解锁,点击后若当前棋盘可用则载入所棋谱的初始棋盘,否则将弹出错误信息以及错误原因。
  与载入初始棋盘类似,只不过绘制的棋盘有所不同,便于用户查看棋谱的结局。
  在“棋谱搜索”按钮左侧的编辑框键入需要搜索的内容然后点击棋谱搜索按钮 即可开始搜索棋谱,光标将会停在匹配成功的记录上,再次点击搜索按钮将继续向下 搜索,如果搜索条件或搜索内容发生改变,将自动从首记录开始搜索,同时在必要时 系统将会提示用户如何填写搜索条件,除创建时间字段以外的其他属性均为包含即可, 注意区分英文大小写。
  首先此功能也需要修改棋盘内容,故而此功能只能在对战结束并且没有演示或摆谱的状态下使用,进入此功能前需要提示用户是否需要保留当前棋盘内容,因为摆谱功能只提供了移动棋子和删除棋子的功能,而并没有提供新建棋子的功能,如果用户选择不保留棋盘内容则载入默认起手棋局,此时所有棋子均存在,就不存在新建棋子的需要了。
  当然由于残局可能已经分出胜负了,即 1 方老帅已经不存在了,此时则不能提供保留棋盘的功能了,必须强制清空然后重新初始化棋子。
  因此需要首先检测棋盘里的红黑双方的老帅是否俱在,都在的情况下才询问是否保留棋盘数据,否则直接清除棋盘数据。
  对战结束后(人机或者双人对弈均可)点击“保存棋谱”按钮(前提是已经打开了数据库),将会弹出保存棋谱窗口,填写“棋谱名称”、“作者”、“备注”然后单击确定即可,其中棋谱名称必须填写,且不能与已有的棋谱相同。
  3.5.2.3 对弈
  作为一款与象棋相关的软件,对弈功能必不可少。双人对弈
  上面已经实现了棋子的绘制和移动,对弈的过程则是用户点击游戏画板上的棋子, 触发画板点击消息,接收消息时会得到鼠标点击位置相对于画板左上角的坐标,由于 棋盘方格大小是固定的,棋盘网格点的位置也是固定的,因此可以轻松算得用户点击 的网格的位置从而轻松确定出用户选择的棋子,单方用户分为 2 步,第 1 步选择要移动的棋子,然后点击要到达的位置,当然在很正移动棋子前需要将移动的起始点和重 点传输给移动合法性检验方法,由于由起始位置可以直接确定要移动的棋子的类型, 故而只传输 2 个坐标即可,如果移动不合法则提示用户,若合法则移动棋子并修改棋
  盘数据;当然若第 2 次点击的棋子依然是己方的棋子,则应该视为更新起始位置(即将要移动的棋子),每次移动后都要判断对局是否结束(即红方和者蓝方的帅是否都存在),并在必要的时候结束对局并显示胜负信息
  人机对弈
  上面已经实现了双人对弈,人机对弈效果类似,红方走子与双人对弈中的红方走子完全一致,不同之处在于黑方的走子将需要电脑来负责移动,很自然的我在网上查找了一下有关于象棋人机对弈的软件,最后发现了一款简单的人机对弈软件适合于我的软件[3],很自然就把该软件的人机对弈函数引入了我的软件,由于方法涉及到的语句较多,不便于在此处张贴出源码,故而简单的说下思路:
  首先作为人机对弈,自然应该尽量倾向于战胜用户而不是随便乱走(比如随机选择一个棋子随机走动一下),故而随机选择1 个棋子然后随便走1 下的思想是不行的;
  很自然会有 1 个想法:列出所有可能的走法然后从里面选出 1 个最好的走法作为电脑的走法,那么怎么才能称得上是最好的做呢?根据经验,同一个棋子,比如小兵,在河道和在九宫格的小兵的价值肯定是不一样的,而且同一个位置不同的棋子价值也是不同的,故而引入几个概念:棋子的基本价值、灵活性、位置,比如车就比小兵更灵活,通常情况下车比小兵更重要,但并不绝对,故而再引入 1 个概念:棋子的价值,
  由棋子的基本价值、棋子的位置、棋子的灵活性综合运算得到 1 个值作为棋子当前的价值,当然老帅的基本价值必须是最高的,数据层面考虑,己方棋子的价值的总和(记为棋盘价值)越大,赢的可能性越大(仅仅是概率更大),由于棋子个数有限,棋子
  的走法也是有限的,故而可以列举出棋子的所有走法,然后模拟进行一下每个走法, 计算出这么走之后的棋盘的价值,选择使得棋盘价值最高的走法作为最佳走法;常言道“牛掰的棋手走一步看三步,垃圾的棋手走 1 步看 1 步”,故而可以考虑走法迭代的深度,将走法全部组合匹配起来,模拟进行之后再计算出棋盘价值,最后筛选出棋盘价值最高的走法,作为最佳走法;自然根据原理,需要用到递归,然后在众多组合中如何快速寻找到最佳走法呢?这里需要用到 1 个大名鼎鼎的搜索算法:Alpha-Beta 搜索算法,使用这个算法可以快速找出最佳走法,然后由计算机直接完成黑方的走子即可,当然考虑的步数越多,计算机的“棋力”一般来说也就越高,但是由于是通过递归算法实现的而且涉及到了棋子走法的组合,一旦组合的步数过大,产生的组合将会非常之多,而且递归层数太多会导致程序效率下降;并且本软件的主要目的是进行棋谱管理,人机对弈只是 1 个附属功能,并不要机器的“棋力”登峰造极,故而,限
  制考虑的步数在[1,4]之中,正好对应于 4 个难度:小白、入门、棋士、大师;实测发
  现小白和入门难度机器的反应都是秒速反应,而棋士难度则需要平均 4-6 秒才能做出反应,大师难度基本上是半天才走一步,故而在用户试图将难度设置为大师时提示用户可能会出现卡顿现象;通过点击“人机切换”按钮可在人机对弈与双人对弈之间切换(为保证对局公平,只允许在红方落子前进行切换)
  投降
  某些情况下用户可能需要快速结束对战,故而需要 1 个“投降”功能,对战状态下点击投降按钮时将首先要求用户确认投降操作,用户执意投降则判定最终输赢。
  由于摆谱功能的短板,无法新建棋子,故而需要一种快速导入棋盘数据的方法, 用户只需要构建 1 个含有 90 个整数的文本文件(程序只需要从开头读到 90 个整数就
  会停止读取),可以视为 10 行 9 列的数字棋盘,每个位置的数字都代表着 1 个棋子,直接导入即可。由于易语言对直接从文件中中读取数字文本并校验不是太方便,故而此部分使用 C 语言实现,使用动态运行库技术来取长补短,由 C 语言编码的动态库对棋盘文件进行检查(如部分棋子数量异常或者处于不可达位置或者文件内容异常) 然后生成格式化文件,并将检查结果反馈给主程序,主程序根据反馈的结果进行相应的操作:导入棋盘或者报告详细错误信息,并且迅速删除格式化输入文件。
  另外由于此功能会修改棋盘,故而需要检测棋盘的使用情况,当棋盘已被其他功能占用时将提示用户当前不能导入棋盘并说明对应的理由。
  点击按钮后将自动弹出棋盘文件的示例,按 ESC 键关闭示例窗口将开始导入。棋盘导入成功后将默认为双人对弈状态。
  3.5.3 其他功能
  作为一款软件,在满足基本要求的情况下总会有点额外的小点缀,当然本软件也不例外。
  点击皮肤列表组合框选择想要切换到的皮肤,程序将会弹出确认更换皮肤确认框, 点击确定后即可切换到该皮肤(注意:由于皮肤模块的缺陷,更换皮肤后将无法恢复 默认无皮肤状态)。
  此功能需要通过系统 API 实现,通过调用系统运行库 Kernel32.dll 中的有关创建内核互斥体的办法来实现检测。具体原理为,创建内核互斥体时需要传入 1 个字符串, 当没有其他程序通过这个字符串创建过并保持该内核对象(为进程所拥有,当进程退出时即使程序自身不释放所创建的内核互斥体,操作系统也会自动进行释放)时创建才能成功,故而同一个软件使用固定的字符串创建内核互斥体对象时,第 2 个甚至更多个打开的实例在创建内核互斥体对象时一定会失败,故而实现了多开检测。
  关于
  点击后将会弹出作者相关信息,当鼠标停留在关于窗口上时将会呈现禁止点击图标,单击鼠标左键即可关闭此窗口,在关闭此窗口前,不能对主窗口进行任何操作。
  总结
  作为信息与计算科学专业的一名学生,学校安排了一系列与软件开发相关的课程, 自然我们也学习了大量与软件开发有关的理论知识和实践知识,然而平常由于学习任 务繁忙,很难讲所学的实际应用出来,借助于毕业设计这个契机,可以一展所学,将学到的东西尽可能用出来,“纸上得来终觉浅,绝知此事要躬行”,能够使用使用所学 的知识才是真正的学成了自己的知识,在此次设计实现中,我有了不少新的发现,同 时也刷新了自己的认知,切身的感知到了自身的不足之处,使得自身的前进方向更加明确,“路上春色正好,天上太阳正晴”,在之后的日子里不忘初心,努力前行。
咨询论文发表及论文撰写
论文空间专注于毕业论文硕士论文论文发表网站地图服务
Copyright © 2002-2019 论文空间 版权所有
联系手机:17343344559 微信:lunwenpass QQ:论文客服 论文客服