1.
班内序号:
《C++语言程序设计》
课程设计
五子棋游戏
自动化学院
物联网工程
题
学
专
目
院
业
年级班别
学
号
学生姓名
吴灿桂
指导教师
2016 年 8 月 26 日
一、 课程设计目的
为使《C++语言程序设计》课程取得更好的教学效果而设置,是进一步培养学生综合应用 C++
的各种编程知识和技巧进行 Windows 应用程序编写的实际能力,包括:
(1)对 C++基本语法的熟练掌握;
(2)训练学生对一个实际应用系统进行综合分析、设计、编程及调试等的能力;
(3)培养学生自主学习和独立创新的精神。
使学生通过参加小型软件的开发过程,进一步掌握 C++语言的程序设计方法,使学生具有团队协作
精神,并培养学生的创新能力和创新意识。
二、 项目概述
五子棋游戏是一款历史悠久,对抗性强,技巧性高的棋类游戏,深受大众喜爱,富有趣味性和
消遣性。而且我对五子棋有着独特的爱好,希望自己也可以编写处一款实现人机对战的五子棋游戏,
借这次课设的机会,把想法变为现实。
程序类型说明:
这里设计和实现了一个简单的五子棋单机游戏,其主要应用 Qt creator 这个 IDE 开发环境和其
生成的 ui 界面文件进行 C++的可视化编程,使一个基于 Qt 的信号和槽机制以及 MainWindow 类和
Dialog 类这两个窗口类的五子棋游戏窗体应用程序,实现五子棋的基本功能,如双人对战,人机对
战,悔棋,重开,托管等功能,同时加入背景音乐,下棋音效等在下棋的过程中增添一些乐趣。
三、 功能介绍与系统实现
1
开 始 游 戏 后 显 示
的游戏开始图标
开始双人游戏按钮
开始人机对战按钮
退出游戏按钮
显示当前回合数
提示轮到的下棋方
悔棋按钮
重 新 开 始 游 戏 按
游戏主界面
玩 家 进 行 托 管 和
取消托管的按钮
显示托管状态,如无人
托管或人机对战则不显
2 功能与各模块对应的类
游戏开始时首先显示一个开始窗口并播放起始音乐,给玩家选择游戏模式,选择游戏模式后进
入游戏主窗口,在主窗口的左侧下棋,玩家开始下棋时背景音乐停止,给玩家以一个安静的环境一
决高下,在右侧上方由提示回合数和下棋方,使玩家在对决时了解棋上的情况,同时他们可以选择
悔棋功能,重新开始功能和退出功能,当一方玩家有事时,可以按下右下角的棋子图标,进行游戏
托管,由一方玩家与 AI 对弈,当托管的玩家回来时,重新按下图标可以实现取消托管,使双方愉悦
的进行对弈而不受其他事情打扰。
在这个程序中我主要设计编写了两个类,Dialog 类和 MainWindow 类,分别 public 继承于 Qt
的 QDialog 类和 QMainWindow 类这两个窗体类,实现可视话和窗体化并对所有信息进行封装隐藏,
只留出几个对外的接口,由我编写的 Dialog 类的成员变量和函数有:
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
bool getAI();
//构造函数,设置初始值
//析构函数
private slots:
//Dialog 的 3 个槽在按钮点击信号发送时促发
void
void
void
on_quitBtn_clicked()
on_BeginBtn_clicked();
on_AIButton_clicked();
private:
Ui::Dialog *ui;
bool AI;
由我编写的 MainWindow 类的 chengyuan 函数和变量有:
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void setofAI(bool);
void
paintEvent(QPaintEvent *);
//接受由 Dialog 传来的 AI 值应用于 mainwindow
//绘画图纸和棋子,这个事件只要是窗体部要被重
void mouseReleaseEvent(QMouseEvent *); //响应鼠标点击事件
绘了就会被调用或者在 update()时更新窗口
private slots:
//mainwindow 的 4 个槽,connected 各按钮的 click 事件
void on_huiqiButton_clicked();
void on_quitpushButton_clicked();
void on_againButton_clicked();
void on_qiehuanButton_clicked();
private:
int chess[15][15];
int xnew,ynew;
int xold,yold;
int player;
//定义一个 15*15 的数组对应棋盘的每个下棋点
//保存当前落子点的位置坐标
//保存上一步落子点的位置坐标
int timeofregret;
bool AI;
QString huihe;
QSound *movemusic;
bool isWin(int, int);
bool win90(int, int);
bool win0(int, int);
bool win135(int, int);
bool win45(int, int);
void regret(void);
void select(void);
void setAI(void);
int score0(int,int);
int score45(int,int);
int score90(int,int);
int score135(int,int);
3 流程图与系统实现
//以下为判断结果的函数
//悔棋函数
//以下为 AI 函数
Main 函 数 实 例 化 两 个 窗 体 对 象
MainWindow w 和 Dialog dlg;设置 Qt 可使
用中文,显示 dlg 窗口并播放背景音乐
dlg 按钮选择
人机对战,AI=true
双人对战,AI=false
显示开始图片后 show mainwindow
paintEvent 进
行检测, 画棋
mouseReleaseEvent 进行检测
退出
鼠标点
击落子
悔棋,调
用 regret()
重开,将基
础值重置
Ai 选取下棋点,
setAI(),select()
调 用 isWin(x,y) 检 测 当
前落子后是否有一方已
4 个 score 函数
计算去最佳点
4 个 win 函数判断五子
棋 4 个方向的五连子
系统实现与算法分析
在这个程序中,我采用面向对象的方法,利用自己编写的两个窗口类 dialog 和 mainwindow,首
先实例化这连个类分别为 dlg 和 w,首先显示 dlg,一个 dialog 对话框并播放背景音乐,然后给玩家选
择游戏模式或者退出程序,玩家选择好游戏模式后,把 dlg 的 AI 属性传递给 main window w,并用
w.show( )显示游戏主窗口,之后玩家就可以在棋盘上点击下棋,当鼠标点击时触发 mouseRelsaseEvent
函数,在这个函数中检测当前下棋次序,给与鼠标点击区间相对应的 chess 数组元素赋值 1 或 2,触
发下棋音效并调用 update( )函数;之后检测是否有 AI,如为 true,则调用 setAI( )函数计算出 AI 下
棋的最佳落子点并将相应的值赋给相应的 chess 元素,再调用 update( )函数。
当 update( )函数调用时或 w 的窗体画图需要更新时,系统自动调用 paintEvent(QPaintEvent *)函
数,绘制图纸并根据 chess[x][y]数组的每个元素的值在对应的点绘制棋子,值为 0 不绘制,1 绘制黑
子,2 绘制白子。
当点击 w 窗口上的悔棋按钮时,触发 on_huiqiButton_clicked(),调用 regre()函数,首先修改
chess[xnew][ynew]及上一次点击或者 AI 改变的数组元素的值,将棋修改为 0,在将 xnew 和 ynew
的值修改为上次的值,以便与其他地方同步,在调用 update ( )触发 paintEvent。
当点击重开按钮时,触发 on_againButton_clicked(),将 chess 数组,player 等设置为 0,调用 update()
达到重新开始游戏的状态。
当启用托管时及将 AI 设置为 true,在玩家下一步后电脑自动计算并下下一步棋。
AI 的实现:
在本程序中,AI 主要是对每个棋子可能落的地方进行评分计算,得出分数最高最有利与电脑的
位置,并落子,分数的计算分 4 个方向,水平,垂直,45°和 135°,分别在 score0(int,int),
score45(int,int) ,score90(int,int),score135(int,int)4 个函数中计算,在每个方向中进行 2 连子,3 连
子,4 连子和 5 连子的计算(连子及对应的 chess[ ][ ]值连续相同)并将分数返回给 select( )函数进行比
较。
四、测试
文件:
软件运行其余截图见上面软件整体结构图与模块划分介绍;
测试情况分析:
下图为程序运行时的 cpu,内存和磁盘占用,可见程序对电脑性能占用很少,性能较高。
五、小结与心得体会
课程设计是培养学生综合运用所学知识 ,发现,,提出,分析和解决实际问题,锻炼实践能力重
要环节,是对我们的实际工作能力的具体训练和考察过程。在当前程序开发技术是十分重要的,而
C++语言又是最常见,功能最强大的一种高级语言,因此做好 C++语言课程设计是十分必要的。
程序大概用了一个星期完成,从最开始的窗口显示到最后的基本完整的五子棋游戏,在这个游
戏编写的过程中,我体会到 C++语言的巨大的用处以及他的魅力,同时也提高了我的 C++编程能力
和创新能力。虽然我写的是一个五子棋小程序,但在这个过程中遇到许多问题,如一开始不熟悉 Qt
的 ui 环境而无从下手,但我没有放弃,在自学和同学的帮助下克服一个个困难并取得成功。
六、附录
用到的第三方控件或组件:
Qt 的 GUI 类库,Qt creater 组件。
程序的主要代码 :
dialog.h 文件
. . .
public:
bool getAI(void);
private slots:
void on_quitBtn_clicked();
void on_BeginBtn_clicked();
void on_AIButton_clicked();
private:
bool AI;
. . .
Mainwindow.h 文件
. . .
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void paintEvent(QPaintEvent *);
void mouseReleaseEvent(QMouseEvent *);
void setofAI(bool);
private slots:
. . .
private:
. . .
int chess[15][15];
int xnew,ynew;
int xold,yold;
int player;
int timeofregret;
bool AI;
QString huihe;
QSound *movemusic;
bool isWin(int, int);
bool win90(int, int);
bool win0(int, int);
bool win135(int, int);
bool win45(int, int);
void regret(void);
void select(void);
void setAI(void);
int score0(int,int);
int score45(int,int);
int score90(int,int);
int score135(int,int);
main.cpp 文件
#include
#include "mainwindow.h"
#include "dialog.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK")); //设置使用中文
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForTr((QTextCodec::codecForName("GBK")));
QPixmap pixmap("begingame.png");
QSplashScreen splash(pixmap);
MainWindow w;
Dialog dlg;
QSound backmusic("backmusic.wav");
backmusic.play();
if(dlg.exec()==QDialog::Accepted)
{
bool ai=dlg.getAI();
w.setofAI(ai);
splash.show();
Sleep(1000);
w.show();
splash.finish(&w);
return a.exec();
}
else
return 0;
}
dialog.cpp 文件
. . .
(构造函数内部)
setFixedSize(400,450);
setWindowTitle(tr("开始游戏"));
ui->BeginBtn->setDefault(true);
ui->guajianlabel->setPixmap(QPixmap("guajian.png"));
ui->tulabel->setPixmap(QPixmap("jian.png"));
ui->BeginBtn->setFlat(true);
ui->AIButton->setFlat(true);
ui->quitBtn->setFlat(true);
. . .
bool Dialog::getAI()
{
return AI;
}
void Dialog::on_quitBtn_clicked()
{
QDialog::reject();
}
void Dialog::on_BeginBtn_clicked()
{
AI=false;
QDialog::accept();
}
void Dialog::on_AIButton_clicked()
{
AI=true;
QDialog::accept();
}
Mainwindow.cpp 文件
. . .
(构造函数内部)
resize(840, 640);
setWindowTitle("五子棋");
ui->qihelabel->setPixmap(QPixmap("qihe.png"));