帮我写一段反四子棋机器人的C++源代码
时间: 2024-02-05 12:13:54 浏览: 95
以下是一个简单的反四子棋机器人的C++源代码,它使用了一个简单的算法来选择最佳的下一步走法:
```c++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int BOARD_SIZE = 10;
const int WIN_NUM = 5;
enum class Player {
NONE,
PLAYER1,
PLAYER2
};
enum class Result {
NONE,
PLAYER1_WIN,
PLAYER2_WIN,
DRAW
};
struct Move {
int x, y;
int score;
};
class Board {
public:
Board() {
for (int i = 0; i < BOARD_SIZE; ++i) {
for (int j = 0; j < BOARD_SIZE; ++j) {
board[i][j] = Player::NONE;
}
}
}
bool is_valid_move(int x, int y) const {
return board[x][y] == Player::NONE;
}
void make_move(Player player, int x, int y) {
board[x][y] = player;
}
Result check_win() const {
for (int i = 0; i < BOARD_SIZE; ++i) {
for (int j = 0; j < BOARD_SIZE; ++j) {
if (board[i][j] == Player::NONE) {
continue;
}
if (check_horizontal(i, j) || check_vertical(i, j) ||
check_diagonal1(i, j) || check_diagonal2(i, j)) {
return board[i][j] == Player::PLAYER1 ? Result::PLAYER1_WIN : Result::PLAYER2_WIN;
}
}
}
if (is_full()) {
return Result::DRAW;
}
return Result::NONE;
}
vector<Move> get_valid_moves() const {
vector<Move> moves;
for (int i = 0; i < BOARD_SIZE; ++i) {
for (int j = 0; j < BOARD_SIZE; ++j) {
if (is_valid_move(i, j)) {
Move move = {i, j, 0};
moves.push_back(move);
}
}
}
return moves;
}
void print() const {
for (int i = 0; i < BOARD_SIZE; ++i) {
for (int j = 0; j < BOARD_SIZE; ++j) {
cout << (board[i][j] == Player::NONE ? '.' : (board[i][j] == Player::PLAYER1 ? 'O' : 'X')) << " ";
}
cout << endl;
}
}
private:
bool is_full() const {
for (int i = 0; i < BOARD_SIZE; ++i) {
for (int j = 0; j < BOARD_SIZE; ++j) {
if (board[i][j] == Player::NONE) {
return false;
}
}
}
return true;
}
bool check_horizontal(int x, int y) const {
if (y + WIN_NUM > BOARD_SIZE) {
return false;
}
for (int i = 0; i < WIN_NUM; ++i) {
if (board[x][y + i] != board[x][y]) {
return false;
}
}
return true;
}
bool check_vertical(int x, int y) const {
if (x + WIN_NUM > BOARD_SIZE) {
return false;
}
for (int i = 0; i < WIN_NUM; ++i) {
if (board[x + i][y] != board[x][y]) {
return false;
}
}
return true;
}
bool check_diagonal1(int x, int y) const {
if (x + WIN_NUM > BOARD_SIZE || y + WIN_NUM > BOARD_SIZE) {
return false;
}
for (int i = 0; i < WIN_NUM; ++i) {
if (board[x + i][y + i] != board[x][y]) {
return false;
}
}
return true;
}
bool check_diagonal2(int x, int y) const {
if (x + WIN_NUM > BOARD_SIZE || y - WIN_NUM + 1 < 0) {
return false;
}
for (int i = 0; i < WIN_NUM; ++i) {
if (board[x + i][y - i] != board[x][y]) {
return false;
}
}
return true;
}
private:
Player board[BOARD_SIZE][BOARD_SIZE];
};
class RandomPlayer {
public:
Move get_move(const Board& board) const {
vector<Move> moves = board.get_valid_moves();
return moves[rand() % moves.size()];
}
};
class MinMaxPlayer {
public:
MinMaxPlayer(int max_depth) : max_depth(max_depth) {}
Move get_move(const Board& board) const {
return min_max(board, Player::PLAYER2, 0).move;
}
private:
struct ScoredMove {
Move move;
int score;
};
ScoredMove min_max(const Board& board, Player player, int depth) const {
ScoredMove best_move = {{-1, -1, 0}, player == Player::PLAYER2 ? INT_MIN : INT_MAX};
if (depth == max_depth || board.check_win() != Result::NONE) {
best_move.score = evaluate(board, player);
return best_move;
}
vector<Move> moves = board.get_valid_moves();
for (const Move& move : moves) {
Board new_board = board;
new_board.make_move(player, move.x, move.y);
ScoredMove scored_move;
scored_move.move = move;
Result result = new_board.check_win();
if (result != Result::NONE) {
if (result == Result::PLAYER1_WIN) {
scored_move.score = player == Player::PLAYER1 ? INT_MAX : INT_MIN;
} else if (result == Result::PLAYER2_WIN) {
scored_move.score = player == Player::PLAYER2 ? INT_MAX : INT_MIN;
} else {
scored_move.score = 0;
}
} else {
ScoredMove child_move = min_max(new_board, player == Player::PLAYER1 ? Player::PLAYER2 : Player::PLAYER1, depth + 1);
scored_move.score = child_move.score;
}
if (player == Player::PLAYER2) {
if (scored_move.score > best_move.score) {
best_move = scored_move;
}
} else {
if (scored_move.score < best_move.score) {
best_move = scored_move;
}
}
}
return best_move;
}
int evaluate(const Board& board, Player player) const {
int score = 0;
for (int i = 0; i < BOARD_SIZE; ++i) {
for (int j = 0; j < BOARD_SIZE; ++j) {
if (board.is_valid_move(i, j)) {
continue;
}
Player p = board.check_horizontal(i, j) ? board.get(i, j) :
board.check_vertical(i, j) ? board.get(i, j) :
board.check_diagonal1(i, j) ? board.get(i, j) :
board.check_diagonal2(i, j) ? board.get(i, j) :
Player::NONE;
if (p == Player::PLAYER1) {
score += player == Player::PLAYER1 ? 1 : -1;
} else if (p == Player::PLAYER2) {
score += player == Player::PLAYER2 ? 1 : -1;
}
}
}
return score;
}
private:
int max_depth;
};
int main() {
Board board;
RandomPlayer player1;
MinMaxPlayer player2(3);
while (true) {
board.print();
Move move;
if (board.check_win() == Result::PLAYER1_WIN) {
cout << "Player 1 wins!" << endl;
break;
}
if (board.check_win() == Result::PLAYER2_WIN) {
cout << "Player 2 wins!" << endl;
break;
}
if (board.check_win() == Result::DRAW) {
cout << "Draw!" << endl;
break;
}
if (board.get_valid_moves().size() == 0) {
cout << "No valid moves!" << endl;
break;
}
move = player1.get_move(board);
board.make_move(Player::PLAYER1, move.x, move.y);
if (board.check_win() == Result::PLAYER1_WIN) {
cout << "Player 1 wins!" << endl;
break;
}
if (board.check_win() == Result::PLAYER2_WIN) {
cout << "Player 2 wins!" << endl;
break;
}
if (board.check_win() == Result::DRAW) {
cout << "Draw!" << endl;
break;
}
if (board.get_valid_moves().size() == 0) {
cout << "No valid moves!" << endl;
break;
}
move = player2.get_move(board);
board.make_move(Player::PLAYER2, move.x, move.y);
}
return 0;
}
```
这个代码实现了一个简单的反四子棋游戏,其中包含了随机玩家和MinMax玩家两种不同的玩家类型。MinMax玩家使用了一个简单的算法来选择最佳的下一步走法,它会考虑到当前的局面以及可能的未来走法,并尝试找到一个最佳的下一步走法来最大化自己的胜率。
阅读全文