基于QT的嵌入式终端应用程序开发 ——黑白棋游戏

摘  要

现在人们的生活压力日益增大,需要劳逸结合才能获得更高的工作效率,工作之余的娱乐对每一个人来说都是必不可少的。黑白棋这种娱乐方式简单易学又具有深奥的技巧,非常富有趣味性和消遣性。在经过不断发展后,黑白棋已经成为棋盘娱乐的一个重要的组成部分。它能够增强思维能力、开发智力,是人们休闲娱乐的不错选择。然而近年来,手机不断更新换代,智能手机越来越多,手机游戏更是层出不穷,开发具有一定人工智能的黑白棋游戏,不仅可以解决人手不够或没有时间玩等客观因素,而且还能起到对黑白棋的广泛推广,使得越来越多的人喜欢上了黑白棋。

本文是根据黑白棋游戏的玩法,在Linux操作系统下,通过QT开发环境实现简单的黑白棋游戏功能,本文重点介绍了Linux操作系统、QT开发环境和整个系统的实现过程。经过测试,该系统能够满足一般用户需求,起到休闲娱乐的效果,具有一定的实用价值。

关键字:手机游戏;黑白棋;Linux;QT

ABSTRACT

Because of the increasing pressure on people's lives, the need to achieve higher working efficiency, combining exertion and rest is essential for everyone. Reversi this entertainment is easy to learn but also has a profound skill, very rich and interesting recreational. After continuous development, the Reversi has become an important component. It can enhance thinking skills, develop intelligence, and it is also a good choice for leisure and entertainment. However in recent years, constantly upgrading mobile phones, smart phones, more and more mobile games is endless, with some artificial intelligence development Reversi game, not only can solve the short of the manpower or do not have time to play other objective factors, but also play a Reversi widely on making more and more people interest in Reversi.

This article is based on Reversi game, under the Linux operating system, through the QT development environment to achieve a simple Reversi game features, this article focuses on the Linux operating system, QT development environment and overall system implementation process. After testing, the system is able to meet the general needs of users, play recreational effects, has some practical value.

Key words:mobile games;Reversi;Linux;QT


目  录

第一章  绪论

1.1 研究背景

1.2 研究意义

1.3 主要研究内容

1.4 嵌入式软件技术的发展现状与未来

第二章  Linux和开发工具QT

2.1 Linux简介

2.2 QT简介

2.3 QT信号与槽机制介绍

第三章  需求分析和系统设计

3.1 需求分析

3.1.1 了解黑白棋游戏玩法和胜负判断规则

3.1.2 本项目功能需求分析

3.1.3 游戏界面需求分析

3.2 系统设计

3.2.1 程序流程图

3.2.2 主要功能模块简介

第四章  系统实现和系统测试

4.1 系统实现

4.1.1 主界面实现

4.1.2 主要按钮功能实现

4.2 系统测试

结束语

  

参考文献

第一章  绪论

1.1研究背景

随着嵌入式产品的不断发展,往往要求嵌入式操作系统有图形和网络的功能。具有网络功能强大和成本低的Linux操作系统,近来得到了越来越多的应用。Linux操作系统能够支持大多数嵌入式系统上使用的芯片,包括Power PC和Strong ARM,MIPS等。在嵌入式Linux操作系统上定制一个功能完备的高性能、轻量级、可配置、可靠的GUI系统成为可行的解决方案。 

虽然目前市场上已经流行着众多优秀的GUI应用软件,但随着嵌入式技术的迅速发展,当新技术出现时,计算机的体系结构、指令系统和操作系统都可能发生相应的改变,这势必会导致一部分应用软件在新环境下无法正常运行。如果舍弃原有软件而重新开发,将会耗费大量的人力和资金,而且浪费了许多成熟的软件成果。 

而QT在源代码级上实现了跨平台特性,极大的支持了跨平台通用软件的开发。QT可以用同一个源程序在不同平台上编译链接,生成目标代码,并取得相同的运行效果,利用这种方法充分实现了程序的跨平台运行。

1.2研究意义

通过本次毕业设计的学习,我了解了QT是一种跨平台的开发工具,在window下开发的程序可以不用任何修改就能在Linux下运行,基本也能直接在手持设备上运行,这种基于跨平台的特性不仅解决了性能的问题,而且可以发挥各个平台的优势,充分利用每个平台自身的特点;并且可以在新环境下实现原有软件的功能和特点,减少开发费用,还可以改进原有软件的不足,增加新的需求,从而提高软件的质量,延长软件生命期。

在开发的过程中,使我能够有机会去学习和研究C++,了解它的各种特性,培养我的项目实践能力,熟悉前沿的Linux图形用户界面的开发,熟悉C++语言在Linux操作系统下的开发环境,以及巩固算法和数据结构等课程的学习成果,并且对算法和数据结构在程序设计中的地位有了深入理解。

随着人们对嵌入式技术和人工智能研究的深入,它们将会直接影响我们的生活,成为我们生活的不可缺少的一部分,帮助我们提高生活质量,减少人工成本,加快社会的发展和进步等等。由此可见,研究嵌入式技术和人工智能意义重大。

1.3主要研究内容

黑白棋游戏是一款非常经典的益智类游戏,其主要包含下棋、悔棋、跳棋、托管等等功能,游戏玩起来看似非常简单,但是要赢得胜利却不是一件容易的事情。

本文将黑白棋划分为两个大的模块进行研究,分别为:人人对战模块和人机对战模块。在人人对战的模块中,由两个游戏玩家进行对弈,任何一方的玩家都可以选择暂停游戏、跳棋、悔棋和托管等功能,不可以双方同时托管,当棋盘放满或者一方棋子全部被吃掉时,这时就是用到游戏判断的模块对游戏进行胜负判断,提示哪一方获胜。在人机对战中,玩家不可以托管,每当玩家落定棋子后,电脑将通过一定的算法选择下子位置,自行落子。

除此之外,本文还重点研究了对棋盘的扫描、悔棋、托管、电脑自动下棋和判断胜负是怎么实现的,在下文中我将以代码的形式进行介绍。

1.4嵌入式软件技术的发展现状与未来

在嵌入式技术的现状方面,以信息家电为代表的互联网时代嵌入式产品,不仅为嵌入式市场展现了美好前景,注入了新的生命;同时也对嵌入式系统技术,特别是软件技术提出新的挑战。这主要包括:支持日趋增长的功能密度、灵活的网络联接、轻便的移动应用和多媒体的信息处理,此外,当然还需对付更加激烈的市场竞争。

今天嵌入式系统带来的工业年产值已超过了1万亿美元,1997年来自美国嵌入式系统大会(Embedded System Conference)的报告指出,未来5年仅基于嵌入式计算机系统的全数字电视产品,就将在美国产生一个每年1500亿美元的新市场。美国汽车大王福特公司的高级经理也曾宣称,“福特出售的‘计算能力’已超过了IBM”,由此可以想见嵌入式计算机工业的广度和规模。在国内,“女锅计划”和“维纳斯计划”一度闹得沸沸扬扬,机顶盒、信息家电这两年更成了IT热点,而实际上这些都是在特定环境下嵌入式系统的一个特定应用。据调查,目前国际上已有两百多种嵌入式操作系统,而各种各样的开发工具和应用于嵌入式开发的仪器设备更加是不可胜数。由此可见,嵌入式技术发展的空间真是无比广大。

就嵌入式技术的未来而言,它的前景也是非常乐观的,家用电器将向网络化和数字化发展,微波炉、数字电话、电视机等都将嵌入微处理机并且通过家庭网络与Internet连接,构成家庭信息网络。将来,人们可以远程控制家里的电器设备,可以实现远程教育、远程医疗,还可以点播自己想看的娱乐电视节目。除此之外的改进还有很多,具体就不赘述了。


第二章  Linux和开发工具QT

2.1 Linux简介

简单地说,Linux是一套免费使用和自由传播的类Unix操作系统,它主要用于基于Intel x86系列CPU的计算机上。其目的是建立不受任何商品化软件的版权制约的、全世界都能自由使用的Unix兼容产品。

Linux最早由一位名叫Linus Torvalds的计算机爱好者开发,他主要是以设计一个代替Minix的操作系统为目的而进行的试验,这个操作系统可用于486、386或奔腾处理器的个人计算机上,具有Unix操作系统全部的功能。

Linux以它的灵活性和高效性著称。它能够在个人计算机上实现全部的Unix特性,具有多用户、多任务的能力。Linux可在GNU公共许可权限下免费获得,是一个符合POSIX标准的操作系统。Linux操作系统软件包不仅包括完整的Linux操作系统,而且还包括了高级语言编译器、文本编辑器等应用软件。它还包括带有多个窗口管理器的X-Windows图形用户界面,就如同我们使用Windows NT一样,允许我们使用菜单、窗口和图标对系统进行操作。

Linux受到广大计算机爱好者的喜爱,是因为:一是它属于自由软件,用户不用支付任何费用就可以获得它和它的源代码,并且可以根据自己的需要对它进行必要的修改和无约束地继续传播。另一个原因是,它具有Unix的全部功能,任何使用Unix操作系统或想要学习Unix操作系统的人都可以从Linux中获益。

下面我们来看下Linux的八大主要特性:

  1. 开放性:指系统遵循世界标准规范,特别是遵循开放系统互连(OSI)国际标准。
  2. 多用户:是指系统资源可以被不同用户使用,每个用户对自己的资源(例如:文件、设备)有特定的权限,互不影响。
  3. 多任务:它是指计算机同时执行多个程序,而且各个程序的运行互相独立。
  4. 良好的用户界面 :Linux向用户提供了两种界面:用户界面和系统调用。Linux还为用户提供了图形用户界面。它利用菜单、窗口、鼠标、滚动条等设施,给用户呈现一个直观、易操作、交互性强的友好的图形化界面。
  5. 设备独立性:是指操作系统把所有外部设备统一当作成文件来看待,只要安装它们的驱动程序,任何用户都可以象使用文件一样,操纵、使用这些设备,而不必知道它们的具体存在形式。Linux是具有设备独立性的操作系统,它的内核具有高度适应能力。
  6. 提供了丰富的网络功能:完善的内置网络是Linux一大特点。
  7. 可靠的安全系统:Linux采取了许多安全技术措施,包括对读、写控制、带保护的子系统、核心授权审计跟踪、等,这为网络多用户环境中的用户提供了必要的安全保障。
  8. 良好的可移植性:是指将操作系统从一个平台转移到另一个平台使它仍然能按其自身的方式运行的能力。Linux是一种可移植的操作系统,能够在从微型计算机到大型计算机的任何环境中和任何平台上运行。

2.2 QT简介

QT是一个跨平台的C++图形用户界面库,由挪威TrollTech公司出品,目前包括QT,基于Framebuffer的QT Embedded,快速开发工具QT Designer,国际化工具 QT Linguist等部分QT支持所有Unix系统,当然也包括Linux,还支持 WinNT/Win2k,Win95/98 平台。

QT是一个多平台的C++图形用户界面应用程序框架。它提供程序开发者建立图形用户界面需要的所用功能。QT是完全面向对象而且很容易扩展,并允许进行真正地组件编程。

从1996年的早些时候起,QT进入到商业领域,现在已经成为全世界范围内数千种成功的应用程序的基础。QT也是流行的Linux桌面环境KDE 的基础,KDE是所有主要的Linux发行版的一个标准组件。

基本上,QT同X Window上的Motif、Openwin、GTK等图形界面库和Windows 平台上的MFC、OWL、VCL、ATL是同类型的东西,但是QT具有下列优点:

(1)优良的跨平台特性:

QT支持下列操作系统: Microsoft Windows NT、Microsoft Windows 95/98、  Linux、Solaris、HP-UX、Digital UNIX (OSF/1、Tru64)、SunOS、Irix、FreeBSD, BSD/OS、SCO、AIX、OS390、QNX 等等。

(2)面向对象:

QT 具有良好的封装机制,这样使得QT的模块化程度非常高,可重用性较好,对于用户开发来说非常方便。除此之外,QT还提供了一种称为signals/slots的安全类型来替代 callback,这使得各个元件之间的协同工作变得十分简单。

(3)丰富的API:

QT 包括多达250个以上的C++类,还提供基于模板的collections、 serialization、file、I/O device、Directory management、date/time 类。甚至还包括正则表达式的处理功能。

(4)支持2D/3D图形渲染,支持OpenGL。

2.3 QT信号与槽机制介绍

信号和槽机制是 QT的核心机制,要精通 QT 编程就必须对信号和槽有所了解。信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。信号和槽是 QT 自行定义的一种通信机制,它独立于标准的 C/C++ 语言,因此要正确的处理信号和槽,必须借助一个称为 moc(Meta Object Compiler)的 QT 工具,该工具是一个 C++ 预处理程序,它为高层次的事件处理自动生成所需要的附加代码。

在图形用户界面编程中,我们经常希望一个窗口部件的一个变化被通知给另一个窗口部件。更一般地,我们希望任何一类的对象可以和其它对象进行通讯。例如,如果我们正在解析一个XML文件,当我们遇到一个新的标签时,我们也许希望通知列表视图我们正在用来表达XML文件的结构。如图2-1所示。

图2-1  关于一些信号和槽连接的摘要图

在QT中我们有一种可以替代回调的技术。我们使用信号和槽。当一个特定事件发生的时候,一个信号被发射。QT的窗口部件有很多预定义的信号,但是我们总是可以通过继承来加入我们自己的信号。槽就是一个可以被调用处理特定信号的函数。QT的窗口部件又很多预定义的槽,但是通常的习惯是你可以加入自己的槽,这样你就可以处理你所感兴趣的信号。

信号和槽机制是类型安全的机制:一个信号的签名必须与它的接收槽的签名相匹配。(实际上一个槽的签名可以比它接收的信号的签名少,因为它可以忽略额外的签名。)因为签名是一致的,编译器就可以帮助我们检测类型不匹配。信号和槽是宽松地联系在一起的:一个发射信号的类不用知道也不用注意哪个槽要接收这个信号。QT的信号和槽的机制可以保证如果你把一个信号和一个槽连接起来,槽会在正确的时间使用信号的参数而被调用。信号和槽可以使用任何数量、任何类型的参数。它们是完全类型安全的:不会再有回调核心转储(core dump)。

信号与槽机制是一个函数,原型如下:

QObject::connect( &a, SIGNAL(funtionA()), &b, SLOT(funtionB()) )

这一行在两个QT对象(直接或间接继承QObject对象的对象)中建立了一种单向的连接。每一个QT对象都有signals(发送消息)和slots(接收消息)。所有窗口部件都是QT对象。它们继承QWidget,而QWidget继承QObject。该函数意思是a部件发出 funtionA()消息,b部件执行funtionB()函数。

第三章  需求分析和系统设计

3.1需求分析

3.1.1了解黑白棋游戏玩法和胜负判断规则

  1. 下棋方法

黑白棋的棋盘是一个有8*8方格的棋盘。下棋时将棋下在空格中间,而不是像围棋一样下在交叉点上。开始时在棋盘正中有两白两黑四个棋子交叉放置,黑棋总是先下子。

把自己颜色的棋子放在棋盘的空格上,而当自己放下的棋子在横、竖、斜八个方向内有一个自己的棋子,则被夹在中间的全部翻转会成为自己的棋子。并且,只有在可以翻转棋子的地方才可以下子。

棋规:

(1).棋局初始时黑棋和白棋分别有棋子。

(2).黑方先行,双方交替下棋。

(3).一步合法的棋步包括:在一个空格新落下一个棋子,并且翻转对手一个或多个棋子。

(4).新落下的棋子与棋盘上已有的同色棋子间,对方被夹住的所有棋子都要翻转过来。可以是横着夹,竖着夹,或是斜着夹。夹住的位置上必须全部是对手的棋子,不能有空格。

(5).一步棋可以在数个方向上翻棋,任何被夹住的棋子都必须被翻转过来,棋手无权选择不去翻某个棋子。

(6).除非至少翻转了对手的一个棋子,否则就不能落子。如果一方没有合法棋步,也就是说不管他下到哪里,都不能至少翻转对手的一个棋子,那他这一轮只能弃权,而由他的对手继续落子直到他有合法棋步可下。

(7).如果一方至少有一步合法棋步可下,他就必须落子,不得弃权。

(8).棋局持续下去,直到棋盘填满或者双方都无合法棋步可下。

  1. 判断胜负条件

如果玩家在棋盘上没有地方可以下子,则该玩家对手可以连下。双方都没有棋子可以下时棋局结束,以棋子数目来计算胜负,棋子多的一方获胜。

在棋盘还没有下满时,如果一方的棋子已经被对方吃光,则棋局也结束。将对手棋子吃光的一方获胜。

翻转棋类似于棋盘游戏“奥赛罗 (Othello)”,是一种得分会戏剧性变化并且需要长时间思考的策略性游戏。

翻转棋的棋盘上有64个可以放置黑白棋子的方格(类似于国际象棋和跳棋)。游戏的目标是使棋盘上自己颜色的棋子数超过对手的棋子数。当游戏双方都不能再按规则落子时,游戏就结束了。通常,游戏结束时棋盘上会摆满了棋子或双方都无法在下棋时谁的棋子最多谁就是赢家。

3.1.2本项目功能需求分析

黑白棋游戏主要有如下功能需求:

1. 两人对弈,以轮流方式持黑子与白子。

2. 开辟新局者持黑子,加入者持白子, 之后以轮流方式将棋子置于棋盘格子中。若无地方可下子,则跳过一回,由对方下子。

3. 下子时,当下子的位置与离最近的同色旗子中, 若有其他棋子则中间的棋子变为与我方一样颜色。

4. 当下满64个棋子,棋子多者为胜。

5. 双方都无棋可走的其他局面,游戏结束,以子多者为胜。 

3.1.3游戏界面需求分析

通过试玩网上一些具有代表性的常见黑白棋程序的分析和对比,现在一个基于界面上的用户需求已经基本确立。该需求包含以下几点:

1. 以按钮的形式出现在主界面上的:

人人对战:实现人与人之间的对弈,黑棋先走,交叉走棋

人机对战:实现人与电脑之间的对弈,玩家先走,电脑自动走棋

开始:开始游戏,开启走棋倒计时功能

暂停:暂停游戏,倒计时的时间暂停

悔棋:每点击一次,即可悔棋一步,可以无限悔棋

托管:将走棋功能交给电脑,由电脑帮您选择位置并自动走棋

跳出:由于本方没有地方可以下棋,则将走棋的机会交换给对手

更换背景:实现背景的按需切换

重新开局:本局游戏结束,重新进行下一局游戏

退出:退出游戏

2. 能够直观显示在游戏界面上的:

网格线:规定下定棋子的位置

开局初始化的棋子:游戏初始化时,四个棋子交叉排列,成X形,组成一个正方形

倒计时剩余时间:显示走棋的剩余时间,时间用完后将下棋权利交给对方

黑方棋子数量:显示黑棋子的数量

白方棋子数量:显示白棋子的数量

3.2系统设计

3.2.1程序流程图

程序执行的流程图如下,该图详细描述了从游戏的加载到游戏结束的详细过程,同时也展现了各个模块之间的所属关系,之后的设计和系统的实现都是按照此图进行设计和规划。如图3-1所示。

图3-1  游戏执行流程图

3.2.2主要功能模块简介

本项目简单实现黑白棋功能,能够选择游戏模式,并且实现悔棋、托管、跳出等功能,界面简单明了,易于操作,下面为大家一一介绍各个模块的实现和功能。

  1. 绘图模块

该模块利用画图事件paintEvent(QPaintEvent *e),主要是画棋盘以及棋盘上黑白子的位置,每当点击鼠标后,就会调用show_chess()函数对棋盘进行一次重绘。

void ChessBoard::paintEvent(QPaintEvent *)

{

   bw = 314;                           //固定棋盘大小

   bh = 314;

   x = (int) (bw-10)/8;                    //从(5,5)开始画线

   y = (int) (bh-10)/8;

   QPainter p(this);                      //定义画笔

p.drawPixmap(0,0,bw,bh,QPixmap("../image/ii.jpg"));

   QPen pen;

   pen.setColor(QT::red);

   pen.setWidth(3);

   pen.setStyle(QT::SolidLine);             //风格:实线

   p.setPen(pen);

   for(int i=0;i<9;i++)                    //画出棋盘

   {

       p.drawLine(5,5+y*i,8*x,5+y*i);

       p.drawLine(5+x*i,5,5+x*i,8*y);

   }

show_chess();

}

show_chess()函数用于显示棋子在棋盘中的位置以及颜色,并记录棋盘上黑白子的数目。

void ChessBoard::show_chess()

{

   QPainter p(this);

   count_black = 0;

   count_white = 0;

   for(int i=0;i<8;i++)

   {

       for(int j=0;j<8;j++)

       {

           if(chess[i][j] == 0)

           {

   p.drawPixmap(5+i*x,5+j*y,x,y,QPixmap("../image/black.png"));

              count_black++;            //棋盘上黑子的数目

           }

           if(chess[i][j] == 1)

           {  

p.drawPixmap(5+i*x,5+j*y,x,y,QPixmap("../image/white.png"));

              count_white++;            //棋盘上白子的数目

           }

       }

   }

}

  1. 重新初始化棋盘模块

当点击重新开局按钮on_pushButton_start_again_clicked()时,将调用begin_chess()函数,对之前所保存的界面进行清除,恢复到游戏刚刚开始时的界面,重新选择游戏模式并进行游戏。

void ChessBoard::begin_chess()              //初始化棋盘

{

   for(a=0;a<8;a++)                       //给二维数组赋初值

   {

       for(b=0;b<8;b++)

       {

           chess[a][b] = 2;

       }

   }

   count_black = 0;                     //初始化

   count_white = 0;                     //初始化

   show_mid_fourchess();               //调用函数,打印出棋盘中间四格的棋子

}

函数show_mid_fourchess()用于显示游戏一开始时棋盘中间的四颗棋子,此函数在构造函数中被调用。

void ChessBoard::show_mid_fourchess()

{

   chess[3][3] = 0;

   chess[3][4] = 1;

   chess[4][3] = 1;

   chess[4][4] = 0;

   show_chess();                                   //调用函数

}

  1. 人人对战模块

函数judge_chess_ptop()为人人对战函数,基本上人人对战的操作都在这个函数中,包括吃子和悔棋功能,当点击人人对战时将执行以下代码。

void ChessBoard::judge_chess_ptop()                //人人对战

{

   if(chess[a][b] != 2)

       return;

   switch(loop)

   {

   case 0:

   {

       black_eat_num = judgeRule(a, b, 8, chess, Black);//调用吃子函数

       if(black_eat_num == 0)

       {

           chess[a][b] = Empty;

           loop = 0;

           break;

       }

       else

       {

           this->setCursor(QCursor(QPixmap("../image/swhite.png")));

           loop = 1;

           page++;                     //每下一个棋子page就加1

           voluation_three_array();        //调用函数

           emit control_clock();

           break;

       }

   }

   case 1:

   {

       white_eat_num = judgeRule(a, b, 8, chess, White) ; //调用吃子函数

       if(white_eat_num == 0)

       {

           chess[a][b] = Empty;

           loop = 1;

           break;

       }

       else

       {

           this->setCursor(QCursor(QPixmap("../image/sblack.png")));

           loop = 0;

           page++;

           voluation_three_array();            //调用给三维数组赋值函数

           emit control_clock();               //发送控制时钟信号

           break;

       }
     }

   }

}

  1. 人机对战模块

函数judge_chess_ptom()用于人机对战,人机对战所需的功能都在此函数中,当点击人机对战时将执行以下代码。

void ChessBoard::judge_chess_ptom()                 //人机对战

{

   if(chess[a][b] != 2)

       return;

   if(color_flag == 0)

   {

       if(loop == 0 )                              //黑棋,人下

       {  //调用吃子函数

           int black_eat_nnum = judgeRule(a, b, 8, chess, Black);

           if(black_eat_nnum == 0)

           {

               chess[a][b] = Empty;

               loop = 0;

           }

           else

           {

               page++;                        //page加1

               voluation_three_array();           //调用三维数组赋值函数

               emit control_clock();

               this->setCursor(QCursor(QPixmap("../image/swhite.png")));

               loop = 1;

           }

       }

   }

   if(color_flag == 1)

   {

       if(loop == 1 )                               //白棋,人下

       {  //调用吃子函数

           int white_eat_nnum = judgeRule(a, b, 8, chess, White);

           if(white_eat_nnum == 0)

           {

               chess[a][b] = Empty;

               loop = 1;

           }

           else

           {

               page++;                          //page加1

               voluation_three_array();             //调用三维数组赋值数

               emit control_clock();

               this->setCursor(QCursor(QPixmap("../image/sblack.png")));

               loop = 0;

           }

       }

   }

}

  1. 判断胜负模块

每当有棋子落在棋盘上的时候都需要对游戏进行胜负判断,本文通过调用函数get_chess_num()对棋盘上的棋子进行统计,并且做出胜负的判断,提示玩家游戏结束。

void MyGame::get_chess_num()       //显示lcdnumber,并判断棋局是否结束

{

   ui->lcdNumberBlack->display(w->count_black);

   ui->lcdNumberWhite->display(w->count_white);

   if(w->count_black + w->count_white == 64)           //棋盘满了,结束

   {

       if(w->count_black > w->count_white)             //黑方胜

       {

           int mes = QMessageBox::information(this,"Info","Game Over!\n黑 方胜!!!",QMessageBox::Ok,QMessageBox::Cancel);

           if(mes == QMessageBox::Ok)

           {

               this->close();

           }

       }

       if(w->count_black <= w->count_white)            //白方胜

       {

           int mes = QMessageBox::information(this,"Info","Game Over!\n白 方胜!!!",QMessageBox::Ok,QMessageBox::Cancel);

           if(mes == QMessageBox::Ok)

           {

               this->close();

           }

       }

   }//黑棋为零时结束,白棋胜

   if((w->count_black == 0)&&( w->count_white !=0) )   

   {

       int mes = QMessageBox::information(this,"Info","Game Over!\n白方  胜!!!",QMessageBox::Ok,QMessageBox::Cancel);

       if(mes == QMessageBox::Ok)                     //点击ok键退出

       {

           this->close();

       }

   }//白棋为零时结束,黑棋胜

   if((w->count_white == 0) && (w->count_black != 0))  

   {

       int mes = QMessageBox::information(this,"Info","Game Over!\n黑方 胜!!!",QMessageBox::Ok,QMessageBox::Cancel);

       if(mes == QMessageBox::Ok)                     //点击ok键退出

       {

           this->close();

       }

   }

}

  1. 悔棋模块

当点击悔棋按钮时,将调用on_pushButton_repentchess_clicked()函数,实现悔棋功能,此函数将棋盘恢复到上次落子前的棋盘。

void MyGame::on_pushButton_repentchess_clicked()        //悔棋

{

   w->flag=0;

   t=20;

   ui->lcdNumberClock->display(t);  

   if(w->loop == 0)

   {

       w->loop = 1;

       w->setCursor(QCursor(QPixmap("../image/swhite.png")));

   }

   else if(w->loop == 1)

   {

       w->loop = 0;

       w->setCursor(QCursor(QPixmap("../image/sblack.png")));

   }

   page--; int i, j;                                     //人人对战,page-1  

   for(i = 0; i < 8; i++)

   {

       for(j = 0; j < 8; j++)

       {

           w->chess[i][j] = w->chess_regret[page][i][j];      

}

   }

   if(page < 0)

   {

       page = 0;

       QMessageBox::warning(this,"warn",QObject::tr("Sorry!不能再退了"));    

   }

   this->w->update();

}

  1. 托管模块

点击托管按钮,对弈一方托管(只在人人对战中,人机对战中无意义)。

void MyGame::on_pushButton_deposit_clicked()        //托管

{

   if(w->loop == 1)                               //白棋托管

   {

       deposit_flag = 0;

       w->flag = 1;

       w->color_flag = 0;

   }

   else if(w->loop == 0)                        //黑棋托管

   {

       deposit_flag = 1;

       w->flag = 1;

       w->color_flag = 1;

   }

}

  1. 更换背景模块

通过更换背景按钮,可以对棋盘的背景图片进行切换,此按钮只有在游戏开始后才可以使用

void MyGame::on_pushButton_background_clicked()         //更换背景

{

   if(background_flag == 0)

   {

       background_name = (char *)"../image/1.jpg" ;

       background_flag = 1;

   }

   else if(background_flag == 1)

   {

       background_name = (char *)"../image/2.jpg" ;

       background_flag = 2;

   }

   else if(background_flag == 2)

   {

       background_name = (char *)"../image/3.jpg" ;

       background_flag = 0;

   }

}

第四章  系统实现和系统测试

4.1系统实现

4.1.1主界面实现

下图为游戏加载成功后的界面:如图4-1所示。

图4-1  游戏主界面

4.1.2主要按钮功能实现

本项目的主要功能是能够正常试玩黑白棋游戏,包括实现游戏模式(人人对战、人机对战)的选择、开始游戏、暂停游戏、悔棋、托管和暂停等功能,下面简单介绍点击对应按钮后实现的效果。如图4-2、4-3所示。

  1. 人人对战

点击人人对战后,人机对战按钮将不能使用,开始按钮恢复正常使用功能,点击开始后,游戏开始并启用倒计时,超时后切换对手,并且暂停、悔棋、托管、跳出、更换背景等按钮恢复使用功能。

图4-2  人人对战开始界面

图4-3  人人对战游戏界面

  1. 人机对战

点击人机对战后,人人对战按钮将不能使用,开始按钮恢复正常使用功能,点击开始后,游戏开始并启用倒计时,超时后切换对手,并且暂停、悔棋、托管、跳出、更换背景等按钮恢复使用功能。效果图与上图类似。

  1. 悔棋

点击悔棋按钮,棋盘回退到上一步,重新选择落子位置。

  1. 托管

点击托管按钮后,本方棋子将自行选择位置自动下棋。

  1. 跳出

点击跳出按钮后,切换为对手执子。

  1. 更换背景

点击更换背景后,游戏界面的背景将进行切换操作。

4.2系统测试

该部分主要编写功能测试,记录测试的过程和结果,并对测试结果进行分析总结,以便优化系统。如表4-1所示。

表4-1  系统测试结果表

序号

测试功能

输入及操作说明

期望结果

评价标准

1

暂停测试

点击暂停按钮

游戏时间暂停,点击开始后,游戏可以继续运行

测试结果与期望结果一致

2

悔棋测试

点击悔棋按钮

人人对战模式下,点击悔棋,可以实现单步悔棋

人机对战模式下,点击悔棋,将回收自己下的棋子和机器下的棋子

测试结果与期望结果一致

3

托管测试

点击托管按钮

一方点击托管后可实现本方下棋的自动化

测试结果与期望结果一致

4

跳出测试

点击跳出按钮

人人模式下,点击跳出后,换为另一放执棋

测试结果与期望结果一致

5

更换背景测试

点击更换背景按钮

点击更换背景后,窗体的背景进行切换

测试结果与期望结果一致

6

重新开局测试

点击重新开局按钮

点击重新开局后,进入模式选择界面

测试结果与期望结果一致

7

退出测试

点击退出按钮

点击退出,提示Are you sure to close?YES即退出,NO返回游戏

测试结果与期望结果一致

结束语

本程序是我的第一个嵌入式程序,通过我的不断的学习和探索,使得本程序实现了界面友好,并且能够运行于Windows和Linux两大系统,同时还实现了人人对战、人机对战、全局棋盘悔棋、跳棋、托管等功能,在上文中我简单的对绘制棋盘、判断行动力、选择位置落子进行了简单介绍。

虽然已近毕业设计尾声,但作为我的第一个程序它仅仅是一个开始,还需要不断的修改和完善,如果将本程序作为一个可发行版,我个人觉得还有以下几部分需要完善:

(1)加入背景音乐播放功能,使游戏玩起来让人更加愉悦,不至于过度单调。

(2)通过INTERNET实现不同客户端的人人对战。

(3)人机对战的算法优化,实现人机对战的不同难度的选择。

我的专业并未开设过与人工智能相关的课程,但由于我对此感兴趣,在论文选题时毅然选择了这个挑战非常大的关于人工智能的题目,由于我自学能力和时间有限,现在的黑白棋功能还处于初级阶段,但我会坚持不懈的努力,将黑白棋程序不断完善。

致  谢

时光飞逝,岁月如梭,回想到四年前接到的录取通知书,那份欣喜依然历历在目,转眼间大学四年的校园生活即将结束,在这4年的学习时间里,时间不算太长,但是这四年却赋予我人生浓墨重彩的一笔,思维的丰盈以及知识的储备,都让我感觉这四年学习生活的充实。

感谢曾经教过我的老师,感谢他们毫无保留的传道、授业、解惑,让我在学习的过程中充分享受到学习的愉悦和知识的力量。老师们的谆谆教导让我受益匪浅,借此论文答辩之际,要表示我最忠诚和崇高的感谢和敬意。我特别要感谢的是我的论文指导老师殷美琴老师,从论文的选题、定题、完成项目设计,一直到反复的修改和完善,花费了老师大量的时间和精力,并提出很多宝贵的意见和建议。殷美琴老师渊博的知识,严谨的治学态度,以及负责任的态度和真诚坦荡的处世之道,让我敬仰佩服。在此特别向我的导师殷美琴老师表示我最美好的祝福和最真挚的谢意。

其次我要感谢的是和我同窗四年的大学同学,他们让我对友情有了更深一层的认识,他们无私的给予了我学习和生活上的帮助,更加丰富了我的大学生活,这短短四年的时间已经成为了我这一生的宝贵财富,人生中的一道亮丽的风景线。

最后,我还要感谢下生我养我的父母,是他们提供给我这样一个很好的环境,让我健康愉快的成长。

感谢老师,感谢同学,感谢我的亲人朋友,因为有你们,我的人生才完整丰富,我将秉承各位的教诲,走向更美好的未来。

参考文献

[1]杜秀全.博弈算法在黑白棋中的应用[J].计算机技术与发展,2007.1.

[2]赖泳伶,张孝凡.黑白棋自我学习的改进策略[J],2004.6.

[3]尹立民.Visual C++6.0应用编程150例[M].北京电子工业出版,2008.

[4]王浩.Visual C++游戏开发经典案例详解[M].北京清华大学出版.

[5]蔡自兴,徐光祐.人工智能及其应用(第三版)[M].北京清华大学出版社,2003.9.

[6]霍亚飞编著.QT及QT Quick开发实战精解.北京航空航天大学出版社,2012.5.

[7]霍亚飞编著.QT Creator快速入门.北京航空航天大学出版社,2012.5.

[8]陈爽编著.Linux与QT程序设计.清华大学出版社,2011.12.

[9]蔡志明等编著.精通QT4编程(第2版).电子工业出版社,2011.2.

[10] 韩少云,奚海蛟,谌利编著.基于嵌入式Linux的QT图形程序实战开发.北京航空航天大 学出版社,2012.10.

[11] Mat Buckland.Ai Techniques For Game Programming[M].Premier Press,2002.

[12] George F.Luger Artificial Intelligence:Structures and Strategies for Complex Problem Solving Addison Wesley[M],2001.7.

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等天晴i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值