目录
1. 项目目标
2. 效果演示
3. 创建项目
4. 项目框架设计
4.1 设计项目框架
4.2 根据设计框架创建类
5. 给类添加主要接口
5.1 设计棋盘类Chess的主要接口
5.2 设计AI类的主要接口
5.3 设计Man类的主要接口
5.4 设计ChessGame的主要接口
5.5 添加各个接口的具体实现
6. 实现游戏控制
6.1 添加数据成员
6.2 实现游戏控制啊
7. 创建游戏
8. 棋盘的“数据成员”设计
9. 使用棋盘类的“构造函数” 对棋盘进行构造
10. 棋盘的“初始化” - 正在更新
五子棋人机对战,已经有很版本。但是使用纯C++,严格按照C++面向对象思想开发的,却还是很少的,所以准备使用C++面向对象的思想,开发一个完整的五子棋人机对战,对于C++初学者,是很有帮助的哦!
本教程配套视频
1. 项目目标
- 掌握C++的核心技术
- 掌握C++开发项目的方法和流程
- 掌握AI算法的基础应用
2. 效果演示
开局头像,没有看错,就是我哈,棋魂附体 :-)
准备好 了吗?直接上代码!
3. 创建项目
使用VS2019+easyx图形库开发,也可以使用VS的其他版本。
参考:VS2019安装教程 easyx图形库入门教程
使用VS2019(或VS2022)创建一个新项目,选择空项目模板。
然后再导入图片素材res目录。因网盘链接不稳定,在评论中回复邮件地址,即发送完整素材。也可以使用自己的素材。
4. 项目框架设计
4.1 设计项目框架
使用C语言开发的初学者,往往直接就在main函数中写详细的过程。使用C++面向对象,就需要“脱胎换骨”,改变开发思路了!不写过程,直接写需要几个类!
这里,设计了4个类,分别表示棋手,AI, 棋盘,游戏控制。这应该是最符合现实情况的简单设计了,如果是做网络对战版,就还需要添加其它模块。
4.2 根据设计框架创建类
创建项目框架中描述的4个类。可以使用如下方式创建类:
填写类名,再单击确定即可。
按照这个方式,一共创建4个类:Man, AI, Chess, ChessGame. 创建完后,项目的目录结构如:
5. 给类添加主要接口
5.1 设计棋盘类Chess的主要接口
注意:在给类设计接口时,建议先只考虑对外暴露的“接口”,可以先不用考虑数据成员,对外(public)提供的接口(函数)才是最重要的。
Chess.h
typedef enum {
CHESS_WHITE = -1, // 白方
CHESS_BLACK = 1 // 黑方
} chess_kind_t;
struct ChessPos {
int row;
int col;
};
class Chess
{
public:
// 棋盘的初始化:加载棋盘的图片资源,初始化棋盘的相关数据
void init();
// 判断在指定坐标(x,y)位置,是否是有效点击
// 如果是有效点击,把有效点击的位置(行,列)保存在参数pos中
bool clickBoard(int x, int y, ChessPos* pos);
// 在棋盘的指定位置(pos), 落子(kind)
void chessDown(ChessPos* pos, chess_kind_t kind);
// 获取棋盘的大小(13线、15线、19线)
int getGradeSize();
// 获取指定位置是黑棋,还是白棋,还是空白
int getChessData(ChessPos* pos);
int getChessData(int row, int col);
// 判断棋局是否结束
bool checkOver();
};
5.2 设计AI类的主要接口
AI.h
#include "Chess.h"
class AI
{
public:
void init(Chess* chess);
void go();
};
5.3 设计Man类的主要接口
Man.h
#include "Chess.h"
class Man
{
public:
void init(Chess* chess);
void go();
};
5.4 设计ChessGame的主要接口
ChessGame.h
class ChessGame
{
public:
void play();
};
5.5 添加各个接口的具体实现
可以使用如下方式自动生成各接口的具体实现。先不用考虑各个接口的真正实现,直接使用空函数体代替。
6. 实现游戏控制
直接调用各个类定义的接口,实现游戏的主体控制。
6.1 添加数据成员
为了便于调用各个类的功能,在ChessGame中,添加3各数据成员,并再构造函数中初始化这三个数据成员。
#include "Man.h"
#include "AI.h"
#include "Chess.h"
class ChessGame
{
public:
ChessGame(Man*, AI*, Chess*);
void play();
private:
Man* man;
AI* ai;
Chess* chess;
};
ChessGame::ChessGame(Man* man, AI* ai, Chess* chess)
{
this->man = man;
this->ai = ai;
this->chess = chess;
ai->init(chess);
man->init(chess);
}
6.2 实现游戏控制啊
void ChessGame::play()
{
chess->init();
while (1) {
man->go();
if (chess->checkOver()) {
chess->init();;
continue;
}
ai->go();
if (chess->checkOver()) {
chess->init();
continue;
}
}
}
7. 创建游戏
在main函数中,创建游戏。
#include#include "ChessGame.h" int main(void) { Chess chess; Man man; AI ai; ChessGame game(&man, &ai, &chess); game.play(); return 0; }
8. 棋盘的“数据成员”设计
为棋盘类,添加private权限的“数据成员”。
private: // 棋盘尺寸 int gradeSize; float margin_x;//49; int margin_y;// 49; float chessSize; //棋子大小(棋盘方格大小) IMAGE chessBlackImg; IMAGE chessWhiteImg; // 存储当前游戏棋盘和棋子的情况,空白为0,黑子1,白子-1 vector> chessMap; // 标示下棋方, true:黑棋方 false: AI 白棋方(AI方) bool playerFlag;
再补充一下头文件。
#include#include using namespace std;
9. 使用棋盘类的“构造函数” 对棋盘进行构造
添加棋盘类的构造函数的定义以及实现。
Chess.h
Chess(int gradeSize, int marginX, int marginY, float chessSize);
Chess.cpp
Chess::Chess(int gradeSize, int marginX, int marginY, float chessSize)
{
this->gradeSize = gradeSize;
this->margin_x = marginX;
this->margin_y = marginY;
this->chessSize = chessSize;
playerFlag = CHESS_BLACK;
for (int i = 0; i < gradeSize; i++) {
vectorrow;
for (int j = 0; j < gradeSize; j++) {
row.push_back(0);
}
chessMap.push_back(row);
}
}
同时修改main函数的Chess对象的创建。、
//Chess chess; Chess chess(13, 44, 43, 67.4);
10. 棋盘的“初始化” - 正在更新
正在更新...



