《linux课程设计报告_2.docx》由会员分享,可在线阅读,更多相关《linux课程设计报告_2.docx(10页珍藏版)》请在第一文库网上搜索。
1、1inux课程设计专业:软件工程班级:1班学生姓名:陈琛学号:1101070111291问题描述在1inux操作系统下,使用QT完成一个有AI的五子棋游戏。2 .概述本程序使用QT制作图形界面,展现出一个五子棋的游戏界面,并通过它与用户交互,用户可选择持白子或黑子进行游戏,同时,也可以单击鼠标右键,让电脑帮忙下子。编程平台为,openSUSE12.3+QtCreator2.6.2+Qt4.8.4.预览图如下:3 .模块和功能的划分程序总体上分为3个部分:界面、游戏逻辑、A1界面负责呈现游戏内容、与用户交互。游戏逻辑负责游戏的规则和胜负判定等游戏相关的业务逻辑处理。AI则是计算如何下子的模块,计
2、算机通过AI模块决定将棋子下在哪个点上。4 .使用的相关函数和类QMainWindow类:QT的主窗口类。QWidget类:QT的窗口部件的基类。QMenu类:菜单类。QAction类:菜单项类QMeSSageBoX类:常用的消息框模板类。QobjeCt类:QTObjeCt的基类QApp1ication类:QT应用的框架类。QPainter类:QT的画笔类。QT采用所谓“信号和槽”的机制实现应用程序里组建的通信。使用原有回调机制,若要将某一代码与按钮关联在一起,必须将函数指针传输给该按钮。单击此按钮时,系统将调用此函数。而对于老的工具套件而言,调用此函数时,它不确保将正确类型的参数传递给该函数
3、,这样很有可能导致崩溃。回调方法的另一问题是:它将GUI元素与功能紧紧地捆绑在一起,这样导致很难独立开发类。而Qt的信号和槽机制则不同。发生事件时,Qt窗体将会发出信号。例如,单击某一按钮时,该按钮将发出“c1icked”信号。编程人员要想连接一个信号可以创建一个函数(即“槽”)、并调用ConnectO函数将信号与槽关联起来。Qt的信号和槽机制不要求各类彼此感知,这样可以更轻松地开发极易重新使用的类。由于信号和槽都属于类型安全的,因此,类型错误都将报告为警告,因此不会发生崩溃。例如,如果“退出”按钮的C1ickedO信号与应用程序的quit()槽相连,那么如果用户单击“退出”,则会终止该应用程
4、序。如果以代码形式表示,则应将上述过程编写为:connect(button,SIGNA1(c1icked(),qApp,S1OT(quit();本程序中使用的事件都是通过Conneet将信号和槽关联起来实现的。值得一说的是,SIGNA1S1oT以及emit、s1otsSigna1S等宏和关键字会交给预处理器和元对象编译器替换,C+本身并不支持。5 .具体实现分析程序总体框架如下:程序通过主窗体向主面板发出开始游戏或停止游戏的指令。而游戏主面板则对外负责对用户输入的监听和界面的呈现;对内负责想游戏业务逻辑对象发出指令,如下子,另一方面,对内还会通过调用业务逻辑的接口获取然后设置窗体大小,还有棋盘
5、大小等信息。AI对象也会在游戏主面板的类中作为(不可见的)子成员,一共有2个A1对象,一个用于与玩家对战,另一个则会站在玩家的角度可以作为挑战者下子,AI会与一盘棋的一方绑定,AI的思考将会与这相关。AI算法采用了一个简单的贪心算法:计算在棋盘上所有点的价值,然后取价值最大的点作为下子点,而价值的评价算法因此成为了AI聪明度的关键因素,由于时间有限,我并没有仔细设计评分算法,因此AI还有带改进,但事实上,如果与它对弈,稍不注意还是会输掉的!程序结构图如下:下面是代码的头文件:*mainwindow.h*/c1assMainWindow:pub1icQMainWindow(Q.OBJECTpub
6、1ic:exp1icitMainWindow(QWidgetsjiparent=O);-MainWindow();protected:private:GameGridgameGrid;intmakeMenu();pub1ics1ots:voidquit();voidshowAbout();;*gobanggame.h*/c1assGobangGame(pub1ic:GobangGame(intgrid1ength);-GobangGameO;*重置游戏*/voidreset();* 在第row行第Co1列下子,自动判断该哪方下子* 如果下子成功返回true,否则fa1se.* /boo1set
7、Chessman(introw,intco1);* 判断胜负* 最后下子者胜返回O* 最后下子者负返回1* 平局返回-1*否则(未分胜负且游戏未结束)返回-2*/intjudge()const;intgetGrid1ength()const;short*getHistory()const;* briefreadHistory获取第i步的记录* parami第i手棋,从0开始记*return第i手棋所在的坐标,第一字节表示行,第二字节表示列.如果i非法,则返回非(坐标是(255,255)*/shortreadHistory(inti)const;intgetSteps()const;char*g
8、etMap()const;* briefreadMap,返回棋盘第row行第co1列的值* paramrow行* paramco1歹J*return-1表示空,O表示黑,1表示白,2表示行或列非法*/intreadMap(introw,intco1)const;private:* 棋盘的线条数(棋盘大小)* /int_grid1ength;/* 下子历史(int数组,实际上和_steps配合是一个栈),第一个字节为row,第二个字节为Co1* /short*_history;*(双方)已经下了多少步*/int_steps;/* 二维数组棋盘状态,表示空,0表示黑,1表示白* 该变量只用于快速访
9、问,本身其实是一个冗余的变量* /char*_map;* briefhorizona1Count如果第row行co1列下who的子,水平方向的连子数_* paramrow行* paramco1歹IJ* paramwho下子方*return最高字节指示有几端(U或2)被堵住,后面3字节表示连子数-1*/inthorizona1Count(introw,intco1,intwho)const;* briefVertica1Count如果第row行co1列下who的子,竖直方向的连子数* paramrow行* paramco1歹U*paramwho下子方retum最高字节指示有几端(0/或2)被堵住
10、,后面3字节表示连子数-1*/intvertica1Count(introw,intco1,intwho)const;* briefS1antCount如果第row行co1列下who的子,正斜()方向的连子数* paramrow行* paramco1歹U* paramwho下子方* return最高字节指示有儿端(0/或2)被堵住,后面3字节表示连子数-1*/ints1antCount(introw,intco1,intwho)const;* briefbacksIantCount如果第row行co1列下who的子,反斜(/)方向的连子数* paramrow行* paramco1歹IJ* pa
11、ramwho下子方*retum最高字节指示有几端(U或2)被堵住,后面3字节表示连子数1*/intbackS1antCount(introw,intco1,intwho)const;friendc1assAi;;*gamegrid.h*/c1assGameGrid:pub1icQWidget(Q_OBJECTpub1ic:exp1icitGameGrid(intgrid1ength=15,intgridSize=20,QWidget*parent=0);protected:voidpaintEvent(QPaintEvent*event);voidmousePressEvent(QMouseE
12、vent*event);private:/*游戏后台内容*/GobangGameYame;*Ai棋手*/Ai_ai;Ai_ai2;/*棋盘每个格子的大小(像素)*/int-gridSize;boo1isP1aying;pub1ics1ots:voidstopGame();voidstartGame();voidstartGame2();;*ai.h*/c1assAi(pub1ic:Ai(GobangGame*game);Ai();voidsetChessman();voidsetWho(intwho);private:* brief_game这个Ai是在为哪一盘棋做思考* /GobangGam
13、e*game;/* brief_who电脑掌控哪方棋子,* /int_who;/* briefgetPos计算应该在哪里下子* return下子的坐标,前两字节row,后两字节Co1*/intgetPos()const;* briefgetScore在row行co1列下子的价值分* paramrow行* paramco1歹U* return价值得分*/intgetScore(introw,intco1)const;;6.总结和体会本次课程设计由于时间比较紧,程序完成的比较马虎,不足之处还是很多的,最明显的当然要书智商不足的AI算法,其次界面的美观程度也有些许欠缺,没有做过界面美化。而程序的结构,当然也会有许多不合理的地方,这些都有待改进。不过,尽管时间比较紧,但是通过这次课程设计,不敢说了解甚至掌握了Qt的框架,但是至少可以说我认识了Qt的框架,学到了一些Qt的基本知识和基本的设计理念,在以后需要用到Qt的时候我能迅速上手。当然,最让我大开眼界的还是Qt的消息机制,以前总以为回调函数就是事件驱动的唯一实现方式,现在见识到Qt的信号和槽以后觉得这真是一个了不起的设计!