C++写黑白棋,要求实现绘制6*6棋盘,分玩家对战和人机对战两种模式
时间: 2024-02-03 14:12:34 浏览: 140
黑白棋 课程设计 + AI (Minimax)
好的,以下是一个简单的C++黑白棋的实现,代码注释中有详细的解释。
```cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
// 定义棋盘大小
const int BOARD_SIZE = 6;
// 定义棋子类型
enum PieceType { EMPTY, BLACK, WHITE };
// 定义玩家类型
enum PlayerType { HUMAN, AI };
// 定义玩家结构体
struct Player {
PieceType piece; // 玩家所执棋子的颜色
PlayerType type; // 玩家类型
};
// 定义棋盘类
class Board {
public:
Board() {
// 初始化棋盘
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
pieces[i][j] = EMPTY;
}
}
// 初始棋盘中央四个位置放置黑白棋子
pieces[2][2] = pieces[3][3] = WHITE;
pieces[2][3] = pieces[3][2] = BLACK;
}
// 绘制棋盘
void draw() {
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 (pieces[i][j] == EMPTY) {
cout << ". ";
} else if (pieces[i][j] == BLACK) {
cout << "X ";
} else {
cout << "O ";
}
}
cout << endl;
}
}
// 判断是否可以落子
bool canPlacePiece(int row, int col, PieceType piece) {
if (pieces[row][col] != EMPTY) {
return false;
}
// 八个方向判断是否有相邻的对手棋子
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) {
continue;
}
int r = row + i, c = col + j;
if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) {
continue;
}
if (pieces[r][c] != oppositePiece(piece)) {
continue;
}
while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE) {
r += i;
c += j;
if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) {
break;
}
if (pieces[r][c] == piece) {
return true;
}
if (pieces[r][c] == EMPTY) {
break;
}
}
}
}
return false;
}
// 落子
void placePiece(int row, int col, PieceType piece) {
pieces[row][col] = piece;
// 八个方向翻转对手棋子
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) {
continue;
}
int r = row + i, c = col + j;
if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) {
continue;
}
if (pieces[r][c] != oppositePiece(piece)) {
continue;
}
vector<pair<int, int>> toFlip;
while (r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE) {
toFlip.push_back(make_pair(r, c));
r += i;
c += j;
if (r < 0 || r >= BOARD_SIZE || c < 0 || c >= BOARD_SIZE) {
break;
}
if (pieces[r][c] == piece) {
for (auto p : toFlip) {
pieces[p.first][p.second] = piece;
}
break;
}
if (pieces[r][c] == EMPTY) {
break;
}
}
}
}
}
// 判断是否有空位
bool hasEmpty() {
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (pieces[i][j] == EMPTY) {
return true;
}
}
}
return false;
}
// 计算棋子数目
void countPieces(int& blackCount, int& whiteCount) {
blackCount = whiteCount = 0;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (pieces[i][j] == BLACK) {
blackCount++;
} else if (pieces[i][j] == WHITE) {
whiteCount++;
}
}
}
}
// 获取对手棋子类型
static PieceType oppositePiece(PieceType piece) {
if (piece == BLACK) {
return WHITE;
} else if (piece == WHITE) {
return BLACK;
} else {
return EMPTY;
}
}
// 获取当前棋盘状态
vector<vector<PieceType>> getPieces() const {
return pieces;
}
private:
PieceType pieces[BOARD_SIZE][BOARD_SIZE]; // 棋盘存储
};
// 定义人机对战类
class AIPlayer {
public:
AIPlayer(PieceType p) : piece(p) {}
// 获取最佳落子位置
pair<int, int> getBestMove(const Board& board) {
vector<pair<int, int>> moves = getValidMoves(board); // 获取所有合法落子位置
if (moves.empty()) {
return make_pair(-1, -1);
}
int maxScore = -1000;
pair<int, int> bestMove;
for (auto move : moves) {
Board tmpBoard = board;
tmpBoard.placePiece(move.first, move.second, piece);
int score = minMax(tmpBoard, 3, false); // 对每个落子位置进行估分
if (score > maxScore) {
maxScore = score;
bestMove = move;
}
}
return bestMove;
}
private:
PieceType piece; // AI所执棋子的颜色
// 获取所有合法落子位置
vector<pair<int, int>> getValidMoves(const Board& board) {
vector<pair<int, int>> moves;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board.canPlacePiece(i, j, piece)) {
moves.push_back(make_pair(i, j));
}
}
}
return moves;
}
// 极大极小搜索
int minMax(Board& board, int depth, bool isMaxPlayer) {
if (depth == 0 || !board.hasEmpty()) {
int blackCount, whiteCount;
board.countPieces(blackCount, whiteCount);
if (piece == BLACK) {
return blackCount - whiteCount; // 黑棋最大化分数
} else {
return whiteCount - blackCount; // 白棋最大化分数
}
}
if (isMaxPlayer) {
int maxScore = -1000;
vector<pair<int, int>> moves = getValidMoves(board);
for (auto move : moves) {
Board tmpBoard = board;
tmpBoard.placePiece(move.first, move.second, piece);
int score = minMax(tmpBoard, depth - 1, false);
maxScore = max(maxScore, score);
}
return maxScore;
} else {
int minScore = 1000;
PieceType opposite = Board::oppositePiece(piece);
vector<pair<int, int>> moves = getValidMoves(board);
for (auto move : moves) {
Board tmpBoard = board;
tmpBoard.placePiece(move.first, move.second, opposite);
int score = minMax(tmpBoard, depth - 1, true);
minScore = min(minScore, score);
}
return minScore;
}
}
};
// 定义黑白棋类
class Othello {
public:
Othello() {
// 初始化玩家
players[0].piece = BLACK;
players[1].piece = WHITE;
}
// 开始游戏
void play() {
// 选择游戏模式
int mode;
cout << "请选择游戏模式:1.玩家对战,2.人机对战" << endl;
cin >> mode;
if (mode == 2) {
players[1].type = AI;
aiPlayer = new AIPlayer(players[1].piece);
}
// 随机先手
int turn = rand() % 2;
while (true) {
cout << "---------------------" << endl;
board.draw();
int blackCount, whiteCount;
board.countPieces(blackCount, whiteCount);
cout << "当前黑棋子数目:" << blackCount << endl;
cout << "当前白棋子数目:" << whiteCount << endl;
if (!board.hasEmpty()) {
break;
}
PieceType piece = players[turn].piece;
cout << "玩家 " << (turn + 1) << " (" << (piece == BLACK ? "黑" : "白") << ") 的回合" << endl;
if (players[turn].type == HUMAN) {
if (!humanPlacePiece(piece)) {
cout << "无法落子,跳过此回合" << endl;
turn = 1 - turn;
continue;
}
} else {
cout << "AI正在思考..." << endl;
pair<int, int> bestMove = aiPlayer->getBestMove(board);
if (bestMove.first == -1) {
cout << "AI无法落子,跳过此回合" << endl;
turn = 1 - turn;
continue;
}
cout << "AI落在了 (" << bestMove.first << "," << bestMove.second << ")" << endl;
board.placePiece(bestMove.first, bestMove.second, piece);
}
turn = 1 - turn;
}
cout << "游戏结束!" << endl;
board.draw();
int blackCount, whiteCount;
board.countPieces(blackCount, whiteCount);
cout << "黑棋子数目:" << blackCount << endl;
cout << "白棋子数目:" << whiteCount << endl;
if (blackCount > whiteCount) {
cout << "黑方胜利!" << endl;
} else if (blackCount < whiteCount) {
cout << "白方胜利!" << endl;
} else {
cout << "平局!" << endl;
}
}
private:
Board board; // 棋盘
Player players[2]; // 玩家数组
AIPlayer* aiPlayer = nullptr; // AI玩家
// 玩家落子
bool humanPlacePiece(PieceType piece) {
vector<pair<int, int>> moves = getValidMoves(piece);
if (moves.empty()) {
return false;
}
cout << "可以落子的位置:";
for (auto move : moves) {
cout << "(" << move.first << "," << move.second << ") ";
}
cout << endl;
int row, col;
while (true) {
cout << "请输入落子位置的行列坐标(例如:2 3):" << endl;
cin >> row >> col;
if (find(moves.begin(), moves.end(), make_pair(row, col)) != moves.end()) {
board.placePiece(row, col, piece);
return true;
}
cout << "无效落子位置,请重新输入!" << endl;
}
}
// 获取所有合法落子位置
vector<pair<int, int>> getValidMoves(PieceType piece) {
vector<pair<int, int>> moves;
for (int i = 0; i < BOARD_SIZE; i++) {
for (int j = 0; j < BOARD_SIZE; j++) {
if (board.canPlacePiece(i, j, piece)) {
moves.push_back(make_pair(i, j));
}
}
}
return moves;
}
};
int main() {
Othello othello;
othello.play();
return 0;
}
```
这个黑白棋实现了一个简单的人机对战,AI玩家使用了极大极小搜索算法,最大搜索深度为3。你可以通过修改`minMax`函数的搜索深度来提高或降低AI玩家的难度。
阅读全文