C++写黑白棋,要求实现6*6棋盘,玩家对战和人机对战两种
时间: 2024-02-03 19:12:16 浏览: 28
好的,下面是一个简单的实现,你可以根据需要进行修改和完善。
```
#include <iostream>
#include <vector>
// 定义棋盘大小
const int BOARD_SIZE = 6;
// 定义棋子类型
enum PieceType {
EMPTY, BLACK, WHITE
};
// 定义棋子位置
struct Position {
int row, col;
Position(int r = 0, int c = 0) : row(r), col(c) {}
};
// 定义棋盘类
class Board {
public:
Board() {
// 初始化棋盘
for (int i = 0; i < BOARD_SIZE; i++) {
std::vector<PieceType> row(BOARD_SIZE, EMPTY);
m_board.push_back(row);
}
// 设置初始棋子位置
m_board[2][2] = m_board[3][3] = WHITE;
m_board[2][3] = m_board[3][2] = BLACK;
}
// 打印棋盘
void print() const {
std::cout << " ";
for (int c = 0; c < BOARD_SIZE; c++) {
std::cout << c + 1 << " ";
}
std::cout << std::endl;
for (int r = 0; r < BOARD_SIZE; r++) {
std::cout << r + 1 << " ";
for (int c = 0; c < BOARD_SIZE; c++) {
PieceType p = m_board[r][c];
if (p == EMPTY) {
std::cout << ". ";
} else if (p == BLACK) {
std::cout << "X ";
} else if (p == WHITE) {
std::cout << "O ";
}
}
std::cout << std::endl;
}
}
// 获取棋子类型
PieceType getPiece(int row, int col) const {
return m_board[row][col];
}
// 设置棋子类型
void setPiece(int row, int col, PieceType type) {
m_board[row][col] = type;
}
// 判断落子是否合法
bool isValidMove(int row, int col, PieceType type) const {
if (m_board[row][col] != EMPTY) {
return false;
}
for (int dr = -1; dr <= 1; dr++) {
for (int dc = -1; dc <= 1; dc++) {
if (dr == 0 && dc == 0) {
continue;
}
if (isValidDirection(row, col, dr, dc, type)) {
return true;
}
}
}
return false;
}
// 落子
void makeMove(int row, int col, PieceType type) {
m_board[row][col] = type;
for (int dr = -1; dr <= 1; dr++) {
for (int dc = -1; dc <= 1; dc++) {
if (dr == 0 && dc == 0) {
continue;
}
if (isValidDirection(row, col, dr, dc, type)) {
flipDirection(row, col, dr, dc, type);
}
}
}
}
// 判断是否有合法落子点
bool hasValidMove(PieceType type) const {
for (int r = 0; r < BOARD_SIZE; r++) {
for (int c = 0; c < BOARD_SIZE; c++) {
if (isValidMove(r, c, type)) {
return true;
}
}
}
return false;
}
// 获取当前棋盘中黑白棋子数目
void getPieceCount(int& blackCount, int& whiteCount) const {
blackCount = whiteCount = 0;
for (int r = 0; r < BOARD_SIZE; r++) {
for (int c = 0; c < BOARD_SIZE; c++) {
PieceType p = m_board[r][c];
if (p == BLACK) {
blackCount++;
} else if (p == WHITE) {
whiteCount++;
}
}
}
}
private:
std::vector<std::vector<PieceType>> m_board;
// 判断某个方向是否可行
bool isValidDirection(int row, int col, int dr, int dc, PieceType type) const {
if (row + dr < 0 || row + dr >= BOARD_SIZE || col + dc < 0 || col + dc >= BOARD_SIZE) {
return false;
}
PieceType oppositeType = type == BLACK ? WHITE : BLACK;
if (m_board[row + dr][col + dc] != oppositeType) {
return false;
}
for (int r = row + 2 * dr, c = col + 2 * dc; r >= 0 && r < BOARD_SIZE && c >= 0 && c < BOARD_SIZE; r += dr, c += dc) {
if (m_board[r][c] == EMPTY) {
return false;
} else if (m_board[r][c] == type) {
return true;
}
}
return false;
}
// 翻转某个方向的棋子
void flipDirection(int row, int col, int dr, int dc, PieceType type) {
PieceType oppositeType = type == BLACK ? WHITE : BLACK;
for (int r = row + dr, c = col + dc; m_board[r][c] == oppositeType; r += dr, c += dc) {
m_board[r][c] = type;
}
}
};
// 定义玩家类
class Player {
public:
Player(PieceType t) : m_type(t) {}
// 获取棋子类型
PieceType getType() const {
return m_type;
}
// 落子
void makeMove(Board& board) const {
while (true) {
std::cout << "Player " << (m_type == BLACK ? "X" : "O") << ", enter row and column (e.g. 1 2): ";
int row, col;
std::cin >> row >> col;
if (row < 1 || row > BOARD_SIZE || col < 1 || col > BOARD_SIZE) {
std::cout << "Invalid input!" << std::endl;
continue;
}
row--;
col--;
if (board.isValidMove(row, col, m_type)) {
board.makeMove(row, col, m_type);
break;
} else {
std::cout << "Invalid move!" << std::endl;
}
}
}
private:
PieceType m_type;
};
// 定义AI类
class AI {
public:
AI(PieceType t) : m_type(t) {}
// 获取棋子类型
PieceType getType() const {
return m_type;
}
// 落子
void makeMove(Board& board) const {
std::cout << "AI is thinking..." << std::endl;
int bestRow = -1, bestCol = -1, maxCount = -1;
for (int r = 0; r < BOARD_SIZE; r++) {
for (int c = 0; c < BOARD_SIZE; c++) {
if (board.isValidMove(r, c, m_type)) {
Board tempBoard = board;
tempBoard.makeMove(r, c, m_type);
int blackCount, whiteCount;
tempBoard.getPieceCount(blackCount, whiteCount);
int count = m_type == BLACK ? blackCount : whiteCount;
if (count > maxCount) {
bestRow = r;
bestCol = c;
maxCount = count;
}
}
}
}
board.makeMove(bestRow, bestCol, m_type);
}
private:
PieceType m_type;
};
// 定义游戏类
class Game {
public:
void play() {
// 初始化
Board board;
Player player1(BLACK);
AI player2(WHITE);
// 游戏循环
int turn = 0;
while (true) {
// 打印棋盘
std::cout << std::endl << "Turn " << ++turn << ":" << std::endl;
board.print();
// 判断是否有合法落子点
if (!board.hasValidMove(player1.getType()) && !board.hasValidMove(player2.getType())) {
break;
}
// 玩家1落子
if (board.hasValidMove(player1.getType())) {
player1.makeMove(board);
} else {
std::cout << "Player X has no valid move!" << std::endl;
}
// 打印棋盘
std::cout << std::endl << "Turn " << ++turn << ":" << std::endl;
board.print();
// 判断是否有合法落子点
if (!board.hasValidMove(player1.getType()) && !board.hasValidMove(player2.getType())) {
break;
}
// 玩家2落子
if (board.hasValidMove(player2.getType())) {
player2.makeMove(board);
} else {
std::cout << "Player O has no valid move!" << std::endl;
}
}
// 结束游戏
std::cout << std::endl << "Game over!" << std::endl;
board.print();
int blackCount, whiteCount;
board.getPieceCount(blackCount, whiteCount);
if (blackCount > whiteCount) {
std::cout << "Player X wins!" << std::endl;
} else if (whiteCount > blackCount) {
std::cout << "Player O wins!" << std::endl;
} else {
std::cout << "Draw!" << std::endl;
}
}
};
int main() {
Game game;
game.play();
return 0;
}
```
这个实现中,我们定义了三个类:`Board`(棋盘类)、`Player`(玩家类)和`AI`(AI类),以及一个游戏类`Game`。`Board`类负责存储棋盘状态、落子、打印棋盘等操作;`Player`类负责玩家操作;`AI`类负责AI操作;`Game`类负责游戏循环和最终结果的判断。
在`Board`类中,我们使用一个二维数组来表示棋盘状态,其中`EMPTY`表示空位,`BLACK`表示黑棋,`WHITE`表示白棋。我们使用`print()`函数来打印棋盘,使用`getPiece()`和`setPiece()`函数来获取和设置某个位置的棋子类型,使用`isValidMove()`函数来判断某个位置是否可以落子,使用`makeMove()`函数来落子,使用`hasValidMove()`函数来判断是否有合法落子点,使用`getPieceCount()`函数来获取当前棋盘中黑白棋子数目。
在`Player`类和`AI`类中,我们都使用了`getType()`函数来获取棋子类型,然后使用`makeMove()`函数来落子。`Player`类中的`makeMove()`函数通过控制台输入来获取玩家下的行列坐标,然后判断是否合法,最后调用`Board`类中的`makeMove()`函数进行落子。`AI`类中的`makeMove()`函数则需要实现AI算法来计算最佳落子点,这里我们使用了一个简单的方法:对于所有合法落子点,分别在一个副本棋盘上进行落子,然后计算黑白棋子数目,选择黑白棋子数目最多的点进行落子。
在`Game`类中,我们使用一个循环来进行游戏,每次轮到玩家或AI落子时,先判断是否有合法落子点,如果有则调用`makeMove()`函数进行落子,否则输出提示信息。当游戏结束时,我们调用`getPieceCount()`函数来获取黑白棋子数目,然后根据数目判断胜负或平局。
以上是一个简单的黑白棋实现,你可以参考这个实现进行修改和完善,比如增加更复杂的AI算法、实现悔棋、保存棋谱等功能。