请用c++编写一个五子棋人机对战的小游戏并使电脑尽可能获胜
时间: 2023-06-13 17:09:05 浏览: 143
好的,以下是一个简单的五子棋人机对战的小游戏,电脑使用的是基于极大极小值搜索的算法,尽可能获胜。
```c++
#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
using namespace std;
const int BOARD_SIZE = 15;
const int MAX_DEPTH = 5;
const int INF = 1e9;
struct Point {
int x, y;
Point(int x = 0, int y = 0) :x(x), y(y) {}
};
class Board {
public:
int board[BOARD_SIZE][BOARD_SIZE] = { 0 };
bool is_gameover = false;
void print_board() {
cout << " ";
for (int i = 0; i < BOARD_SIZE; i++) {
cout << i << " ";
}
cout << endl;
for (int i = 0; i < BOARD_SIZE; i++) {
cout << i << " ";
for (int j = 0; j < BOARD_SIZE; j++) {
if (board[i][j] == 0) cout << "+ ";
else if (board[i][j] == 1) cout << "O ";
else cout << "X ";
}
cout << endl;
}
}
bool check_win(int player) {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board[i][j] == player) {
if (check_row(i, j, player)) return true;
if (check_col(i, j, player)) return true;
if (check_diag(i, j, player)) return true;
}
}
}
return false;
}
bool check_row(int x, int y, int player) {
int count = 1;
for (int i = y + 1; i < BOARD_SIZE && board[x][i] == player && count < 5; i++, count++);
for (int i = y - 1; i >= 0 && board[x][i] == player && count < 5; i--, count++);
return count >= 5;
}
bool check_col(int x, int y, int player) {
int count = 1;
for (int i = x + 1; i < BOARD_SIZE && board[i][y] == player && count < 5; i++, count++);
for (int i = x - 1; i >= 0 && board[i][y] == player && count < 5; i--, count++);
return count >= 5;
}
bool check_diag(int x, int y, int player) {
int count = 1;
for (int i = x + 1, j = y + 1; i < BOARD_SIZE && j < BOARD_SIZE && board[i][j] == player && count < 5; i++, j++, count++);
for (int i = x - 1, j = y - 1; i >= 0 && j >= 0 && board[i][j] == player && count < 5; i--, j--, count++);
if (count >= 5) return true;
count = 1;
for (int i = x + 1, j = y - 1; i < BOARD_SIZE && j >= 0 && board[i][j] == player && count < 5; i++, j--, count++);
for (int i = x - 1, j = y + 1; i >= 0 && j < BOARD_SIZE && board[i][j] == player && count < 5; i--, j++, count++);
return count >= 5;
}
bool check_full() {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board[i][j] == 0) return false;
}
}
return true;
}
vector<Point> get_legal_moves() {
vector<Point> moves;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board[i][j] == 0) moves.push_back(Point(i, j));
}
}
return moves;
}
void make_move(const Point& move, int player) {
board[move.x][move.y] = player;
is_gameover = check_win(player) || check_full();
}
void undo_move(const Point& move) {
board[move.x][move.y] = 0;
is_gameover = false;
}
int evaluate() {
int score = 0;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board[i][j] == 1) score += 100;
else if (board[i][j] == 2) score -= 100;
}
}
return score;
}
};
class AI {
public:
Point get_move(Board& board) {
int alpha = -INF, beta = INF;
int max_score = -INF;
vector<Point> moves = board.get_legal_moves();
Point best_move;
for (const auto& move : moves) {
board.make_move(move, 1);
int score = min_value(board, alpha, beta, 1);
board.undo_move(move);
if (score > max_score) {
max_score = score;
best_move = move;
}
}
return best_move;
}
int max_value(Board& board, int alpha, int beta, int depth) {
if (board.is_gameover || depth >= MAX_DEPTH) return board.evaluate();
int max_score = -INF;
vector<Point> moves = board.get_legal_moves();
for (const auto& move : moves) {
board.make_move(move, 1);
int score = min_value(board, alpha, beta, depth + 1);
board.undo_move(move);
max_score = max(max_score, score);
alpha = max(alpha, score);
if (max_score >= beta) return max_score;
}
return max_score;
}
int min_value(Board& board, int alpha, int beta, int depth) {
if (board.is_gameover || depth >= MAX_DEPTH) return board.evaluate();
int min_score = INF;
vector<Point> moves = board.get_legal_moves();
for (const auto& move : moves) {
board.make_move(move, 2);
int score = max_value(board, alpha, beta, depth + 1);
board.undo_move(move);
min_score = min(min_score, score);
beta = min(beta, score);
if (min_score <= alpha) return min_score;
}
return min_score;
}
};
int main() {
srand(time(NULL));
Board board;
AI ai;
while (!board.is_gameover) {
board.print_board();
cout << "Your move (x y): ";
int x, y;
cin >> x >> y;
board.make_move(Point(x, y), 2);
if (board.is_gameover) break;
Point ai_move = ai.get_move(board);
cout << "AI move: " << ai_move.x << " " << ai_move.y << endl;
board.make_move(ai_move, 1);
}
board.print_board();
if (board.check_win(2)) cout << "You win!" << endl;
else if (board.check_win(1)) cout << "AI win!" << endl;
else cout << "Tie!" << endl;
return 0;
}
```
在这个实现中,我们使用了一个 `Board` 类来维护当前棋盘状态,并实现了一些辅助函数来判断胜负和合法走法等。我们还实现了一个 `AI` 类,其中的 `get_move` 函数使用基于极大极小值搜索的算法来计算电脑的下一步棋。
在 `max_value` 和 `min_value` 函数中,我们分别模拟电脑和玩家的行动,然后递归计算下一步的得分。具体地,`max_value` 函数在当前状态下尝试所有可能的电脑走法,并取其中得分最高的一步作为当前状态的得分;`min_value` 函数则在当前状态下尝试所有可能的玩家走法,并取其中得分最低的一步作为当前状态的得分。这样,我们就可以通过不断的递归调用来搜索到一棵完整的博弈树,并从中挑选最优的走法。
在主函数中,我们不断地让玩家和电脑轮流落子,直到棋局结束。最后,我们根据胜负情况输出相应的结果。
阅读全文