用C++编写一个简单的六子棋ai代码
时间: 2024-05-13 15:15:09 浏览: 68
好的,下面是一个简单的六子棋 AI 的代码,使用了 Minimax 算法和 Alpha-Beta 剪枝:
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define BOARD_SIZE 6
#define MAX_DEPTH 5
// 定义棋盘和玩家
typedef enum {Empty, PlayerA, PlayerB} Cell;
typedef struct {
Cell board[BOARD_SIZE][BOARD_SIZE];
Cell player;
} Board;
// 初始化棋盘
void init_board(Board *board) {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
board->board[i][j] = Empty;
}
}
}
// 打印棋盘
void print_board(Board *board) {
printf(" ");
for (int i = 0; i < BOARD_SIZE; i++) {
printf("%d", i + 1);
}
printf("\n");
for (int i = 0; i < BOARD_SIZE; i++) {
printf("%d", i + 1);
for (int j = 0; j < BOARD_SIZE; j++) {
switch (board->board[i][j]) {
case Empty:
printf(".");
break;
case PlayerA:
printf("X");
break;
case PlayerB:
printf("O");
break;
}
}
printf("\n");
}
}
// 判断游戏是否结束
bool game_over(Board *board) {
// 检查每行
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j <= BOARD_SIZE - 6; j++) {
if (board->board[i][j] != Empty &&
board->board[i][j] == board->board[i][j+1] &&
board->board[i][j] == board->board[i][j+2] &&
board->board[i][j] == board->board[i][j+3] &&
board->board[i][j] == board->board[i][j+4] &&
board->board[i][j] == board->board[i][j+5]) {
return true;
}
}
}
// 检查每列
for (int i = 0; i <= BOARD_SIZE - 6; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board->board[i][j] != Empty &&
board->board[i][j] == board->board[i+1][j] &&
board->board[i][j] == board->board[i+2][j] &&
board->board[i][j] == board->board[i+3][j] &&
board->board[i][j] == board->board[i+4][j] &&
board->board[i][j] == board->board[i+5][j]) {
return true;
}
}
}
// 检查每条对角线
for (int i = 0; i <= BOARD_SIZE - 6; i++) {
for (int j = 0; j <= BOARD_SIZE - 6; j++) {
if (board->board[i][j] != Empty &&
board->board[i][j] == board->board[i+1][j+1] &&
board->board[i][j] == board->board[i+2][j+2] &&
board->board[i][j] == board->board[i+3][j+3] &&
board->board[i][j] == board->board[i+4][j+4] &&
board->board[i][j] == board->board[i+5][j+5]) {
return true;
}
}
}
// 检查每条反对角线
for (int i = 5; i < BOARD_SIZE; i++) {
for (int j = 0; j <= BOARD_SIZE - 6; j++) {
if (board->board[i][j] != Empty &&
board->board[i][j] == board->board[i-1][j+1] &&
board->board[i][j] == board->board[i-2][j+2] &&
board->board[i][j] == board->board[i-3][j+3] &&
board->board[i][j] == board->board[i-4][j+4] &&
board->board[i][j] == board->board[i-5][j+5]) {
return true;
}
}
}
// 检查是否平局
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board->board[i][j] == Empty) {
return false;
}
}
}
return true;
}
// 计算分数
int evaluate(Board *board) {
int score = 0;
// 检查每行
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j <= BOARD_SIZE - 6; j++) {
int countA = 0, countB = 0;
for (int k = 0; k < 6; k++) {
if (board->board[i][j+k] == PlayerA) {
countA++;
} else if (board->board[i][j+k] == PlayerB) {
countB++;
}
}
if (countA > 0 && countB == 0) {
score += 1 << countA;
} else if (countB > 0 && countA == 0) {
score -= 1 << countB;
}
}
}
// 检查每列
for (int i = 0; i <= BOARD_SIZE - 6; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
int countA = 0, countB = 0;
for (int k = 0; k < 6; k++) {
if (board->board[i+k][j] == PlayerA) {
countA++;
} else if (board->board[i+k][j] == PlayerB) {
countB++;
}
}
if (countA > 0 && countB == 0) {
score += 1 << countA;
} else if (countB > 0 && countA == 0) {
score -= 1 << countB;
}
}
}
// 检查每条对角线
for (int i = 0; i <= BOARD_SIZE - 6; i++) {
for (int j = 0; j <= BOARD_SIZE - 6; j++) {
int countA = 0, countB = 0;
for (int k = 0; k < 6; k++) {
if (board->board[i+k][j+k] == PlayerA) {
countA++;
} else if (board->board[i+k][j+k] == PlayerB) {
countB++;
}
}
if (countA > 0 && countB == 0) {
score += 1 << countA;
} else if (countB > 0 && countA == 0) {
score -= 1 << countB;
}
}
}
// 检查每条反对角线
for (int i = 5; i < BOARD_SIZE; i++) {
for (int j = 0; j <= BOARD_SIZE - 6; j++) {
int countA = 0, countB = 0;
for (int k = 0; k < 6; k++) {
if (board->board[i-k][j+k] == PlayerA) {
countA++;
} else if (board->board[i-k][j+k] == PlayerB) {
countB++;
}
}
if (countA > 0 && countB == 0) {
score += 1 << countA;
} else if (countB > 0 && countA == 0) {
score -= 1 << countB;
}
}
}
return score;
}
// 判断是否可以下棋
bool is_valid_move(Board *board, int row, int col) {
return board->board[row][col] == Empty;
}
// 执行下棋操作
void make_move(Board *board, int row, int col) {
board->board[row][col] = board->player;
}
// 撤销下棋操作
void unmake_move(Board *board, int row, int col) {
board->board[row][col] = Empty;
}
// Minimax算法
int minimax(Board *board, int depth, int alpha, int beta) {
// 判断是否到达最大深度或游戏结束
if (depth == MAX_DEPTH || game_over(board)) {
return evaluate(board);
}
// 玩家A是Max玩家,玩家B是Min玩家
if (board->player == PlayerA) {
int max_score = -1000000;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (is_valid_move(board, i, j)) {
make_move(board, i, j);
int score = minimax(board, depth+1, alpha, beta);
unmake_move(board, i, j);
if (score > max_score) {
max_score = score;
}
if (max_score > alpha) {
alpha = max_score;
}
if (beta <= alpha) {
return max_score;
}
}
}
}
return max_score;
} else {
int min_score = 1000000;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (is_valid_move(board, i, j)) {
make_move(board, i, j);
int score = minimax(board, depth+1, alpha, beta);
unmake_move(board, i, j);
if (score < min_score) {
min_score = score;
}
if (min_score < beta) {
beta = min_score;
}
if (beta <= alpha) {
return min_score;
}
}
}
}
return min_score;
}
}
// 计算最佳下棋位置
void get_best_move(Board *board, int *row, int *col) {
int max_score = -1000000;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (is_valid_move(board, i, j)) {
make_move(board, i, j);
int score = minimax(board, 0, -1000000, 1000000);
unmake_move(board, i, j);
if (score > max_score) {
max_score = score;
*row = i;
*col = j;
}
}
}
}
}
int main() {
Board board;
init_board(&board);
board.player = PlayerA;
while (!game_over(&board)) {
print_board(&board);
int row, col;
if (board.player == PlayerA) {
printf("Player A's turn\n");
get_best_move(&board, &row, &col);
printf("Player A puts at (%d,%d)\n", row+1, col+1);
} else {
printf("Player B's turn\n");
printf("Enter row and column: ");
scanf("%d %d", &row, &col);
row--;
col--;
}
if (is_valid_move(&board, row, col)) {
make_move(&board, row, col);
if (board.player == PlayerA) {
board.player = PlayerB;
} else {
board.player = PlayerA;
}
} else {
printf("Invalid move\n");
}
}
print_board(&board);
if (evaluate(&board) > 0) {
printf("Player A wins\n");
} else {
printf("Player B wins\n");
}
return 0;
}
```
这个 AI 程序使用了 Alpha-Beta 剪枝来加速 Minimax 算法,同时还对棋盘状态进行了评估,以便在搜索过程中选择最优的下棋位置。由于搜索深度受到了限制,因此 AI 的水平可能不是很高,但仍然可以与人类玩家对弈。
阅读全文