公司动态

C++实现五子棋AI对战(含评分算法 结尾附完整源码)

📅 2026/7/15 13:06:22
C++实现五子棋AI对战(含评分算法 结尾附完整源码)
1. 五子棋AI的核心设计思路五子棋AI的核心在于让计算机学会评估棋盘局势并做出最优决策。这就像教一个孩子下棋首先要让他明白什么是好棋什么是坏棋。我们采用的评分算法就是AI的棋感培养系统。在实际开发中我发现最有效的思路是将棋盘划分为多个方向进行评估。就像人类棋手会同时关注横向、纵向和斜向的棋子连接情况一样我们的AI也需要对四个主要方向进行分析横向水平纵向垂直主对角线左上到右下副对角线左下到右上每个空位的价值由两个因素决定进攻价值如果AI下在这里能形成什么棋型和防守价值如果对手下在这里会形成什么威胁。这种双重评估机制确保了AI既会积极进攻也不会忽视防守。2. 棋盘表示与基础结构在C中我们用一个二维数组来表示棋盘是最直观的选择。我推荐使用15×15的标准棋盘大小这也是国际比赛的标准规格。const int BOARD_SIZE 15; enum Piece { EMPTY, BLACK, WHITE }; // 棋子类型 Piece board[BOARD_SIZE][BOARD_SIZE]; // 棋盘数组初始化棋盘时我们需要将所有位置设为EMPTYvoid initBoard() { for (int i 0; i BOARD_SIZE; i) { for (int j 0; j BOARD_SIZE; j) { board[i][j] EMPTY; } } }为了方便调试和展示我还建议实现一个简单的控制台打印函数void printBoard() { cout ; for (int i 0; i BOARD_SIZE; i) { cout setw(2) i; } cout endl; for (int i 0; i BOARD_SIZE; i) { cout setw(2) i; for (int j 0; j BOARD_SIZE; j) { switch(board[i][j]) { case EMPTY: cout .; break; case BLACK: cout X; break; case WHITE: cout O; break; } } cout endl; } }3. 棋型识别与评分系统评分算法是AI的大脑我将其分为多个层级。在实际测试中这种分级评分系统比简单的线性评分效果要好得多。3.1 基本棋型定义首先我们需要定义各种棋型及其分值// 棋型评分进攻和防守都用这个评分 enum PatternScore { FIVE 100000, // 连五 LIVE_FOUR 10000, // 活四 DIE_FOUR 1000, // 死四 LIVE_THREE 1000, // 活三 DIE_THREE 100, // 死三 LIVE_TWO 100, // 活二 DIE_TWO 10, // 死二 LIVE_ONE 10, // 活一 DIE_ONE 1 // 死一 };3.2 方向分析函数为了评估一个位置的价值我们需要分析四个方向的棋型// 检查一个方向上的连续棋子 int checkLine(int x, int y, int dx, int dy, Piece player) { int count 0; // 正向检查 for (int i 1; i 4; i) { int nx x i * dx; int ny y i * dy; if (nx 0 || nx BOARD_SIZE || ny 0 || ny BOARD_SIZE || board[nx][ny] ! player) { break; } count; } // 反向检查 for (int i 1; i 4; i) { int nx x - i * dx; int ny y - i * dy; if (nx 0 || nx BOARD_SIZE || ny 0 || ny BOARD_SIZE || board[nx][ny] ! player) { break; } count; } return count; }3.3 综合评分函数结合四个方向的评估结果给出一个位置的总评分int evaluatePoint(int x, int y, Piece player) { if (board[x][y] ! EMPTY) return 0; // 已有棋子位置得分为0 int score 0; int directions[4][2] {{1,0}, {0,1}, {1,1}, {1,-1}}; for (auto dir : directions) { int dx dir[0], dy dir[1]; int maxCount 0; // 模拟下子 board[x][y] player; // 检查这个方向的连子数 int count 1 checkLine(x, y, dx, dy, player) checkLine(x, y, -dx, -dy, player); // 还原棋盘 board[x][y] EMPTY; // 根据连子数评分 if (count 5) { score FIVE; } else if (count 4) { // 需要进一步判断是活四还是死四 bool live isLiveFour(x, y, dx, dy, player); score live ? LIVE_FOUR : DIE_FOUR; } else if (count 3) { bool live isLiveThree(x, y, dx, dy, player); score live ? LIVE_THREE : DIE_THREE; } else if (count 2) { bool live isLiveTwo(x, y, dx, dy, player); score live ? LIVE_TWO : DIE_TWO; } else if (count 1) { bool live isLiveOne(x, y, dx, dy, player); score live ? LIVE_ONE : DIE_ONE; } } return score; }4. AI决策算法实现有了评分系统后AI的决策就变得直观了遍历所有空位选择综合评分最高的位置落子。4.1 最佳落子点搜索struct Move { int x, y; int score; }; Move findBestMove(Piece player) { Move bestMove {-1, -1, -1}; for (int i 0; i BOARD_SIZE; i) { for (int j 0; j BOARD_SIZE; j) { if (board[i][j] EMPTY) { // 进攻评分AI自己的棋型 int attackScore evaluatePoint(i, j, player); // 防守评分对手的棋型 int defendScore evaluatePoint(i, j, (player BLACK) ? WHITE : BLACK); // 综合评分防守权重可以适当调高 int totalScore attackScore defendScore * 1.2; if (totalScore bestMove.score) { bestMove {i, j, totalScore}; } } } } return bestMove; }4.2 胜负判断AI需要能够判断游戏是否结束这实际上比评分更简单bool checkWin(int x, int y, Piece player) { int directions[4][2] {{1,0}, {0,1}, {1,1}, {1,-1}}; for (auto dir : directions) { int dx dir[0], dy dir[1]; int count 1; // 当前位置已经有一个子 // 正向检查 for (int i 1; i 4; i) { int nx x i * dx; int ny y i * dy; if (nx 0 || nx BOARD_SIZE || ny 0 || ny BOARD_SIZE || board[nx][ny] ! player) { break; } count; } // 反向检查 for (int i 1; i 4; i) { int nx x - i * dx; int ny y - i * dy; if (nx 0 || nx BOARD_SIZE || ny 0 || ny BOARD_SIZE || board[nx][ny] ! player) { break; } count; } if (count 5) { return true; } } return false; }5. 完整游戏流程与源码将上述模块组合起来就形成了完整的游戏流程。下面给出主游戏循环的实现void playGame() { initBoard(); Piece currentPlayer BLACK; // 黑棋先行 bool gameOver false; while (!gameOver) { printBoard(); if (currentPlayer BLACK) { // 玩家回合 int x, y; cout 请输入落子坐标(x y): ; cin x y; if (x 0 || x BOARD_SIZE || y 0 || y BOARD_SIZE || board[x][y] ! EMPTY) { cout 无效落子请重新输入 endl; continue; } board[x][y] BLACK; if (checkWin(x, y, BLACK)) { printBoard(); cout 恭喜你赢了 endl; gameOver true; } } else { // AI回合 cout AI思考中... endl; Move bestMove findBestMove(WHITE); if (bestMove.x -1) { cout 平局 endl; gameOver true; continue; } board[bestMove.x][bestMove.y] WHITE; cout AI落子于: bestMove.x bestMove.y endl; if (checkWin(bestMove.x, bestMove.y, WHITE)) { printBoard(); cout AI赢了 endl; gameOver true; } } // 切换玩家 currentPlayer (currentPlayer BLACK) ? WHITE : BLACK; } }完整源码还包括一些辅助函数如isLiveFour()、isLiveThree()等棋型判断函数以及一些优化措施。由于篇幅限制这里不全部展示但核心思路已经完整呈现。6. 优化与改进方向在实际测试中我发现这个基础AI有几个可以改进的地方搜索深度优化当前只考虑了一步最优可以引入Minimax算法或Alpha-Beta剪枝来考虑多步策略模式库建立开局库和常见棋型模式库提高AI的战术水平并行计算将棋盘评估过程并行化提高搜索速度Zobrist哈希使用哈希表存储已评估位置避免重复计算一个简单的Minimax算法实现示例int minimax(int depth, bool isMaximizing, int alpha, int beta) { if (depth 0) { return evaluateBoard(); } if (isMaximizing) { int maxEval INT_MIN; for (auto move : generateMoves()) { makeMove(move); int eval minimax(depth - 1, false, alpha, beta); undoMove(move); maxEval max(maxEval, eval); alpha max(alpha, eval); if (beta alpha) break; } return maxEval; } else { int minEval INT_MAX; for (auto move : generateMoves()) { makeMove(move); int eval minimax(depth - 1, true, alpha, beta); undoMove(move); minEval min(minEval, eval); beta min(beta, eval); if (beta alpha) break; } return minEval; } }这个五子棋AI实现虽然基础但已经具备了相当的棋力。通过调整评分参数和优化搜索算法可以进一步提升其水平。最重要的是这个实现清晰地展示了游戏AI的基本原理状态评估和决策搜索。掌握了这个核心你就可以将其应用到更多类型的游戏AI开发中。