AI井字棋 alpha-beta剪枝算法
2026-01-02 16:27:48
发布于:江苏
本作品仅为alpha-beta剪枝算法的应用示例,可玩性极低
注:需要raylib库,当然你也可以改成控制台版的
#include <raylib.h>
#include <vector>
std::vector <std::vector <int> > board(3, std::vector <int> (3, 0));
int tempSymbol = 0, mySymbol = 1, opSymbol = 2;
int inf = 0x7fffffff;
bool gameOver = false;
int gameResult = 0;
struct Move {
int score;
int x, y;
};
bool isWinning(std::vector <std::vector <int> > board, int symbol) {
for (int i = 0; i < 3; i++) {
if (board[i][0] == symbol && board[i][1] == symbol && board[i][2] == symbol) {
return true;
}
}
for (int i = 0; i < 3; i++) {
if (board[0][i] == symbol && board[1][i] == symbol && board[2][i] == symbol) {
return true;
}
}
if (board[0][0] == symbol && board[1][1] == symbol && board[2][2] == symbol) {
return true;
}
if (board[0][2] == symbol && board[1][1] == symbol && board[2][0] == symbol) {
return true;
}
return false;
}
bool isBoardFull(std::vector <std::vector <int> > board) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == tempSymbol) {
return false;
}
}
}
return true;
}
bool isGameOver(std::vector <std::vector <int> > board) {
return isWinning(board, mySymbol) || isWinning(board, opSymbol) || isBoardFull(board);
}
int evaluate(std::vector <std::vector <int> > board) {
if (isWinning(board, mySymbol)) {
return inf;
} else if (isWinning(board, opSymbol)) {
return -inf;
} else {
return 0;
}
}
Move alphaBeta(std::vector <std::vector <int> > board, int alpha, int beta, bool player) {
std::vector <std::pair <int, int> > emptyCells;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == tempSymbol) {
emptyCells.push_back(std::make_pair(i, j));
}
}
}
if (isGameOver(board) || emptyCells.size() == 0) {
int score = evaluate(board);
return {score, 0, 0};
}
Move bestMove;
if (player) {
bestMove.score = -inf;
for (int i = 0; i < emptyCells.size(); i++) {
int x = emptyCells[i].first, y = emptyCells[i].second;
board[x][y] = mySymbol;
Move move = alphaBeta(board, alpha, beta, false);
board[x][y] = tempSymbol;
move.x = x;
move.y = y;
if (move.score > bestMove.score) {
bestMove = move;
}
alpha = std::max(alpha, bestMove.score);
if (beta <= alpha) {
break;
}
}
} else {
bestMove.score = inf;
for (int i = 0; i < emptyCells.size(); i++) {
int x = emptyCells[i].first, y = emptyCells[i].second;
board[x][y] = opSymbol;
Move move = alphaBeta(board, alpha, beta, true);
board[x][y] = tempSymbol;
move.x = x;
move.y = y;
if (move.score < bestMove.score) {
bestMove = move;
}
beta = std::min(beta, bestMove.score);
if (beta <= alpha) {
break;
}
}
}
return bestMove;
}
int main() {
InitWindow(300, 300, "Tic-tac-toe AI");
SetTargetFPS(40);
while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(WHITE);
DrawLineEx({100, 0}, {100, 300}, 3, BLACK);
DrawLineEx({200, 0}, {200, 300}, 3, BLACK);
DrawLineEx({0, 100}, {300, 100}, 3, BLACK);
DrawLineEx({0, 200}, {300, 200}, 3, BLACK);
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (board[i][j] == mySymbol) {
DrawCircle(j * 100 + 50, i * 100 + 50, 40, BLACK);
DrawCircle(j * 100 + 50, i * 100 + 50, 37, WHITE);
} else if (board[i][j] == opSymbol) {
DrawLineEx({j * 100 + 20, i * 100 + 20}, {j * 100 + 80, i * 100 + 80}, 3, BLACK);
DrawLineEx({j * 100 + 80, i * 100 + 20}, {j * 100 + 20, i * 100 + 80}, 3, BLACK);
}
}
}
if (gameOver) {
const char* resultText = nullptr;
Color textColor = BLACK;
if (gameResult == 1) {
resultText = "You Win!";
textColor = GREEN;
} else if (gameResult == 2) {
resultText = "AI Win!";
textColor = RED;
} else {
resultText = "Draw!";
textColor = BLUE;
}
DrawText(resultText, 150 - MeasureText(resultText, 30) / 2, 140, 30, textColor);
}
EndDrawing();
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
if (!gameOver) {
int i = GetMouseY() / 100;
int j = GetMouseX() / 100;
if (board[i][j] == tempSymbol) {
board[i][j] = mySymbol;
if (isWinning(board, mySymbol)) {
gameOver = true;
gameResult = 1;
} else if (isBoardFull(board)) {
gameOver = true;
gameResult = 0;
} else {
Move aiMove = alphaBeta(board, -inf, inf, false);
board[aiMove.x][aiMove.y] = opSymbol;
if (isWinning(board, opSymbol)) {
gameOver = true;
gameResult = 2;
} else if (isBoardFull(board)) {
gameOver = true;
gameResult = 0;
}
}
}
}
}
}
CloseWindow();
return 0;
}
这里空空如也






有帮助,赞一个