编写五子棋AI可以使用极大极小算法(MinMax Algorithm)和Alpha-Beta剪枝(Alpha-Beta Pruning)来优化算法效率。以下是一个简单的示例代码:

#include <iostream>
#include <vector>
#include <climits>

const int SIZE = 15; // 棋盘大小

enum class Player {
    NONE,
    BLACK,
    WHITE
};

struct Move {
    int row;
    int col;
};

// 判断棋盘上某位置是否合法
bool isValidMove(int row, int col) {
    return row >= 0 && row < SIZE && col >= 0 && col < SIZE;
}

// 判断游戏是否结束
bool isGameOver(const std::vector<std::vector<Player>>& board, Player& winner) {
    int directions[4][2] = {{1, 0}, {0, 1}, {1, 1}, {-1, 1}}; // 四个方向:横、竖、斜、反斜

    for (int row = 0; row < SIZE; ++row) {
        for (int col = 0; col < SIZE; ++col) {
            if (board[row][col] == Player::NONE) {
                continue;
            }

            Player currPlayer = board[row][col];

            for (const auto& direction : directions) {
                int dx = direction[0];
                int dy = direction[1];
                int count = 1;

                for (int i = 1; i < 5; ++i) {
                    int newRow = row + dx * i;
                    int newCol = col + dy * i;

                    if (isValidMove(newRow, newCol) && board[newRow][newCol] == currPlayer) {
                        ++count;
                    } else {
                        break;
                    }
                }

                if (count == 5) {
                    winner = currPlayer;
                    return true;
                }
            }
        }
    }

    return false;
}

// 评估当前局面分数
int evaluate(const std::vector<std::vector<Player>>& board) {
    int score = 0;

    int directions[4][2] = {{1, 0}, {0, 1}, {1, 1}, {-1, 1}};

    for (int row = 0; row < SIZE; ++row) {
        for (int col = 0; col < SIZE; ++col) {
            if (board[row][col] == Player::NONE) {
                continue;
            }

            Player currPlayer = board[row][col];

            for (const auto& direction : directions) {
                int dx = direction[0];
                int dy = direction[1];
                int count = 1;
                int emptyCount = 0;

                for (int i = 1; i < 5; ++i) {
                    int newRow = row + dx * i;
                    int newCol = col + dy * i;

                    if (isValidMove(newRow, newCol) && board[newRow][newCol] == currPlayer) {
                        ++count;
                    } else if (isValidMove(newRow, newCol) && board[newRow][newCol] == Player::NONE) {
                        ++emptyCount;
                    } else {
                        break;
                    }
                }

                score += (count * count * count * count) * (currPlayer == Player::BLACK ? 1 : -1);
                score += (emptyCount * emptyCount * emptyCount * emptyCount) * (currPlayer == Player::BLACK ? 1 : -1);
            }
        }
    }

    return score;
}

// 极大极小算法
int minimax(std::vector<std::vector<Player>> board, int depth, bool isMaximizingPlayer) {
    Player winner = Player::NONE;
    if (isGameOver(board, winner)) {
        if (winner == Player::BLACK) {
            return INT_MAX;
        } else if (winner == Player::WHITE) {
            return INT_MIN;
        } else {
            return 0;
        }
    }

    if (depth == 0) {
        return evaluate(board);
    }

    if (isMaximizingPlayer) {
        int maxEval = INT_MIN;
        for (int row = 0; row < SIZE; ++row) {
            for (int col = 0; col < SIZE; ++col) {
                if (board[row][col] == Player::NONE) {
                    board[row][col] = Player::BLACK;
                    int eval = minimax(board, depth - 1, false);
                    board[row][col] = Player::NONE;
                    maxEval = std::max(maxEval, eval);
                }
            }
        }
        return maxEval;
    } else {
        int minEval = INT_MAX;
        for (int row = 0; row < SIZE; ++row) {
            for (int col = 0; col < SIZE; ++col) {
                if (board[row][col] == Player::NONE) {
                    board[row][col] = Player::WHITE;
                    int eval = minimax(board, depth - 1, true);
                    board[row][col] = Player::NONE;
                    minEval = std::min(minEval, eval);
                }
            }
        }
        return minEval;
    }
}

// Alpha-Beta剪枝
int alphabeta(std::vector<std::vector<Player>> board, int depth, int alpha, int beta, bool isMaximizingPlayer) {
    Player winner = Player::NONE;
    if (isGameOver(board, winner)) {
        if (winner == Player::BLACK) {
            return INT_MAX;
        } else if (winner == Player::WHITE) {
            return INT_MIN;
        } else {
            return 0;
        }
    }

    if (depth == 0) {
        return evaluate(board);
    }

    if (isMaximizingPlayer) {
        int maxEval = INT_MIN;
        for (int row = 0; row < SIZE; ++row) {
            for (int col = 0; col < SIZE; ++col) {
                if (board[row][col] == Player::NONE) {
                    board[row][col] = Player::BLACK;
                    int eval = alphabeta(board, depth - 1, alpha, beta, false);
                    board[row][col] = Player::NONE;
                    maxEval = std::max(maxEval, eval);
                    alpha = std::max(alpha, eval);
                    if (beta <= alpha) {
                        break;
                    }
                }
            }
        }
        return maxEval;
    } else {
        int minEval = INT_MAX;
        for (int row = 0; row < SIZE; ++row) {
            for (int col = 0; col < SIZE; ++col) {
                if (board[row][col] == Player::NONE) {
                    board[row][col] = Player::WHITE;
                    int eval = alphabeta(board, depth - 1, alpha, beta, true);
                    board[row][col] = Player::NONE;
                    minEval = std::min(minEval, eval);
                    beta = std::min(beta, eval);
                    if (beta <= alpha) {
                        break;
                    }
                }
            }
        }
        return minEval;
    }
}

// 获取AI的下一步落子位置
Move getNextMove(const std::vector<std::vector<Player>>& board, int depth, bool useAlphaBeta) {
    Move bestMove;
    int bestScore = INT_MIN;

    Player currPlayer = Player::BLACK; // AI执黑棋

    if (!useAlphaBeta) {
        for (int row = 0; row < SIZE; ++row) {
            for (int col = 0; col < SIZE; ++col) {
                if (board[row][col] == Player::NONE) {
                    std::vector<std::vector<Player>> newBoard = board;
                    newBoard[row][col] = currPlayer;
                    int score = minimax(newBoard, depth, false);
                    if (score > bestScore) {
                        bestScore = score;
                        bestMove.row = row;
                        bestMove.col = col;
                    }
                }
            }
        }
    } else {
        int alpha = INT_MIN;
        int beta = INT_MAX;

        for (int row = 0; row < SIZE; ++row) {
            for (int col = 0; col < SIZE; ++col) {
                if (board[row][col] == Player::NONE) {
                    std::vector<std::vector<Player>> newBoard = board;
                    newBoard[row][col] = currPlayer;
                    int score = alphabeta(newBoard, depth, alpha, beta, false);
                    if (score > bestScore) {
                        bestScore = score;
                        bestMove.row = row;
                        bestMove.col = col;
                    }
                    alpha = std::max(alpha, score);
                }
            }
        }
    }

    return bestMove;
}

int main() {
    std::vector<std::vector<Player>> board(SIZE, std::vector<Player>(SIZE, Player::NONE));

    // AI执黑棋,玩家执白棋
    Player currPlayer = Player::BLACK;
    Player winner = Player::NONE;

    while (!isGameOver(board, winner)) {
        // 玩家输入下一步落子位置
        int row, col;
        std::cin >> row >> col;
        if (isValidMove(row, col) && board[row][col] == Player::NONE) {
            board[row][col] = Player::WHITE;
        } else {
            std::cout << "Invalid move. Please try again." << std::endl;
            continue;
        }

        // AI计算下一步落子位置
        Move nextMove = getNextMove(board, 4, true);
        board[nextMove.row][nextMove.col] = Player::BLACK;

        // 打印棋盘
        for (int row = 0; row < SIZE; ++row) {
            for (int col = 0; col < SIZE; ++col) {
                switch (board[row][col]) {
                    case Player::NONE:
                        std::cout << ".";
                        break;
                    case Player::BLACK:
                        std::cout << "X";
                        break;
                    case Player::WHITE:
                        std::cout << "O";
                        break;
                }
            }
            std::cout << std::endl;
        }
    }

    if (winner == Player::BLACK) {
        std::cout << "AI wins!" << std::endl;
    } else if (winner == Player::WHITE) {
        std::cout << "Player wins!" << std::endl;
    } else {
        std::cout << "It's a draw!" << std::endl;
    }

    return 0;
}

这个示例代码实现了一个简单的五子棋AI,通过极大极小算法和Alpha-Beta剪枝来搜索最优解。其中,isValidMove函数用于判断落子位置是否合法,isGameOver函数用于判断游戏是否结束,evaluate函数用于评估当前局面分数,minimax函数用于执行极大极小算法,alphabeta函数用于执行Alpha-Beta剪枝,getNextMove函数用于获取AI的下一步落子位置。

main函数中,先由玩家输入下一步落子位置,然后AI计算下一步落子位置,并将落子位置打印到控制台。

需要注意的是,这只是一个简单的示例,实际的五子棋AI可能需要更复杂的算法和策略来提高性能和游戏水平

C++编写五子棋AI

原文地址: https://www.cveoy.top/t/topic/h6QJ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录