#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstdlib>
#include <ctime>
using namespace std;
// 棋子类型枚举
enum PieceType {
EMPTY,
RED_KING, RED_ADVISOR, RED_ELEPHANT, RED_HORSE, RED_CHARIOT, RED_CANNON, RED_PAWN,
BLACK_KING, BLACK_ADVISOR, BLACK_ELEPHANT, BLACK_HORSE, BLACK_CHARIOT, BLACK_CANNON, BLACK_PAWN
};
// 阵营枚举
enum Side {
RED, BLACK, NONE
};
// 难度等级枚举
enum Difficulty {
EASY, MEDIUM, HARD
};
// 棋子结构体
struct Piece {
PieceType type;
Side side;
Piece() : type(EMPTY), side(NONE) {}
Piece(PieceType t, Side s) : type(t), side(s) {}
};
// 移动结构体,用于AI生成走法
struct Move {
int fromX, fromY, toX, toY;
Move() : fromX(-1), fromY(-1), toX(-1), toY(-1) {}
Move(int fx, int fy, int tx, int ty) : fromX(fx), fromY(fy), toX(tx), toY(ty) {}
};
class ChineseChess {
private:
// 10行9列棋盘 board[0][0]是左上角(黑方车位置), board[9][8]是右下角(红方车位置)
// 坐标系:x为列(a-i -> 0-8), y为行(0-9)。y=0-4为黑方区域,y=5-9为红方区域
Piece board[10][9];
Side turn;
// AI相关配置
bool aiEnabled;
Side aiSide;
Difficulty aiDifficulty;
// 棋子基础价值表
const int pieceValue[17] = {
0, // EMPTY
10000, // RED_KING
10, // RED_ADVISOR
20, // RED_ELEPHANT
40, // RED_HORSE
90, // RED_CHARIOT
45, // RED_CANNON
10, // RED_PAWN
10000, // BLACK_KING
10, // BLACK_ADVISOR
20, // BLACK_ELEPHANT
40, // BLACK_HORSE
90, // BLACK_CHARIOT
45, // BLACK_CANNON
10 // BLACK_PAWN
};
// 位置加成表,提升AI走法合理性
const int posBonus[10][9] = {
{1, 1, 1, 1, 1, 1, 1, 1, 1},
{1, 2, 2, 3, 3, 3, 2, 2, 1},
{1, 2, 3, 4, 5, 4, 3, 2, 1},
{1, 2, 3, 5, 6, 5, 3, 2, 1},
{1, 2, 3, 5, 7, 5, 3, 2, 1},
{1, 2, 3, 5, 7, 5, 3, 2, 1},
{1, 2, 3, 5, 6, 5, 3, 2, 1},
{1, 2, 3, 4, 5, 4, 3, 2, 1},
{1, 2, 2, 3, 3, 3, 2, 2, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1}
};
// 记录最后一步
struct LastMove {
bool valid;
int fromX, fromY, toX, toY;
PieceType pieceType;
LastMove() : valid(false) {}
} lastMove;
public:
ChineseChess() : aiEnabled(false), aiSide(BLACK), aiDifficulty(MEDIUM) {
srand((unsigned int)time(NULL));
initBoard();
turn = RED; // 红方先手
lastMove.valid = false;
}
void initBoard() {
for(int y=0; y<10; y++)
for(int x=0; x<9; x++)
board[y][x] = Piece();
}
void printBoard() {
// 打印列标 a-i
cout << " a b c d e f g h i" << endl;
for (int y = 0; y < 10; y++) {
cout << y << " ";
for (int x = 0; x < 9; x++) {
Piece p = board[y][x];
if (p.type == EMPTY) {
// 楚河汉界显示
if (y == 4 || y == 5) {
if (x0) cout << "[、]";
else if (x8) cout << "[、]";
else cout << " · "; // 河界中间用点表示空
} else {
cout << "[、]";
}
} else {
string symbol = getPieceSymbol(p.type);
if (p.side == RED) {
cout << "{" << symbol << "}";
} else {
cout << "[" << symbol << "]";
}
}
}
cout << " " << y << endl;
}
// 打印列标 a-i
cout << " a b c d e f g h i" << endl;
}
string getPieceSymbol(PieceType t) {
switch(t) {
case RED_KING: return "帅";
case BLACK_KING: return "将";
case RED_ADVISOR: return "仕";
case BLACK_ADVISOR: return "士";
case RED_ELEPHANT: return "相";
case BLACK_ELEPHANT: return "象";
case RED_HORSE: return "马";
case BLACK_HORSE: return "马";
case RED_CHARIOT: return "车";
case BLACK_CHARIOT: return "车";
case RED_CANNON: return "炮";
case BLACK_CANNON: return "炮";
case RED_PAWN: return "兵";
case BLACK_PAWN: return "卒";
default: return " ";
}
}
// 解析输入,例如 "a0a2" 表示从 (0,0) 移动到 (0,2)
// 格式: [a-i][0-9][a-i][0-9]
bool parseInput(const string& moveStr, int& fromX, int& fromY, int& toX, int& toY) {
if (moveStr.length() != 4) return false;
}
bool isValidPos(int x, int y) {
return x >= 0 && x < 9 && y >= 0 && y < 10;
}
// 获取两点之间的棋子数量(不含端点),用于炮和将帅照面判断
int countPiecesBetween(int x1, int y1, int x2, int y2) {
int count = 0;
if (x1 == x2) { // 垂直方向
int minY = min(y1, y2);
int maxY = max(y1, y2);
for (int y = minY + 1; y < maxY; y++) {
if (board[y][x1].type != EMPTY) count++;
}
} else if (y1 == y2) { // 水平方向
int minX = min(x1, x2);
int maxX = max(x1, x2);
for (int x = minX + 1; x < maxX; x++) {
if (board[y1][x].type != EMPTY) count++;
}
} else {
return -1; // 不在同一直线
}
return count;
}
// 判断某一方是否被将军
bool isCheck(Side side) {
// 1. 找到该方的将/帅
int kingX = -1, kingY = -1;
PieceType kingType = (side == RED) ? RED_KING : BLACK_KING;
}
// 判断 (fx, fy) 的棋子是否能攻击到 (tx, ty)
bool canAttack(int fx, int fy, int tx, int ty) {
Piece p = board[fy][fx];
int dx = tx - fx;
int dy = ty - fy;
int absDx = stdabs(dx);
int absDy = stdabs(dy);
}
// 验证移动合法性
bool validateMove(int fx, int fy, int tx, int ty) {
Piece p = board[fy][fx];
if (p.type == EMPTY) return false;
if (p.side != turn) return false;
if (fx == tx && fy == ty) return false;
}
void makeMove(int fx, int fy, int tx, int ty) {
Piece p = board[fy][fx];
}
// 检查是否有合法移动
bool hasLegalMoves(Side side) {
for(int fy=0; fy<10; fy++) {
for(int fx=0; fx<9; fx++) {
if (board[fy][fx].side == side) {
for(int ty=0; ty<10; ty++) {
for(int tx=0; tx<9; tx++) {
if (validateMove(fx, fy, tx, ty)) {
return true;
}
}
}
}
}
}
return false;
}
// 获取某一方的所有合法走法
vector<Move> generateAllLegalMoves(Side side) {
vector<Move> moves;
Side originalTurn = turn;
turn = side;
}
// 评估当前棋盘局势,返回正值对红方有利,负值对黑方有利
int evaluateBoard() {
int score = 0;
for(int y=0; y<10; y++) {
for(int x=0; x<9; x++) {
Piece p = board[y][x];
if(p.type == EMPTY) continue;
}
// 带Alpha-Beta剪枝的Minimax算法
int minimax(int depth, int alpha, int beta, bool isMaximizing, Side maxSide) {
if(depth == 0) {
return evaluateBoard();
}
}
// AI核心走法函数
Move getAIMove() {
vector<Move> legalMoves = generateAllLegalMoves(aiSide);
if(legalMoves.empty()) return Move();
}
// 配置AI参数
void setAIEnabled(bool enabled) { aiEnabled = enabled; }
void setAISide(Side side) { aiSide = side; }
void setAIDifficulty(Difficulty diff) { aiDifficulty = diff; }
bool isAIEnabled() { return aiEnabled; }
Side getAISide() { return aiSide; }
Difficulty getAIDifficulty() { return aiDifficulty; }
Side getTurn() { return turn; }
};
int main() {
ChineseChess game;
string input;
int choice;
cout << "=== 带AI对弈的C++中国象棋 ===" << endl;
cout << "1. 本地双人模式 (关闭AI)" << endl;
cout << "2. 人机对战模式 (开启AI)" << endl;
cout << "请选择游戏模式: ";
cin >> choice;
if(choice == 2) {
game.setAIEnabled(true);
cout << "\n请选择AI执子阵营:" << endl;
cout << "1. AI执黑(红方先手,玩家先走)" << endl;
cout << "2. AI执红(AI先手,玩家执黑)" << endl;
cout << "请选择: ";
cin >> choice;
game.setAISide(choice == 1 ? BLACK : RED);
} else {
game.setAIEnabled(false);
cout << "\n本地双人模式已开启!" << endl;
}
cout << "\n红方先手。输入格式: xyXY (例如 a0a2 表示从a0移到a2)" << endl;
cout << "列: a-i, 行: 0-9. 红方在下(5-9), 黑方在上(0-4)." << endl;
cout << "退出请输入 'quit'" << endl;
while (true) {
game.printBoard();
}
return 0;
}