- 五位数倒序组合判断质数
242
- @ 2025-10-25 20:34:52
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <limits>
#include <cmath>
#include <random>
#include <chrono>
#include <thread>
using namespace std;
// 棋子类型枚举
enum PieceType {
EMPTY = 0,
GENERAL, // 将/帅
ADVISOR, // 士/仕
ELEPHANT, // 象/相
HORSE, // 马/傌
CHARIOT, // 车/俥
CANNON, // 炮/砲
SOLDIER // 兵/卒
};
// 棋子颜色枚举
enum PieceColor {
NONE = 0,
RED,
BLACK
};
// 颜色代码定义
namespace Color {
const string RED = "\033[31m"; // 红色
const string WHITE = "\033[37m"; // 白色
const string RESET = "\033[0m"; // 重置颜色
}
// 棋子类
class Piece {
public:
PieceType type;
PieceColor color;
int x, y;
bool selected;
Piece(PieceType t = EMPTY, PieceColor c = NONE, int posX = 0, int posY = 0) {
type = t;
color = c;
x = posX;
y = posY;
selected = false;
}
// 获取棋子显示名称(带颜色)
string getName() const {
if (type == EMPTY) return " ";
string name;
switch(type) {
case GENERAL: name = (color == RED) ? "帅" : "将"; break;
case ADVISOR: name = (color == RED) ? "仕" : "士"; break;
case ELEPHANT: name = (color == RED) ? "相" : "象"; break;
case HORSE: name = (color == RED) ? "傌" : "马"; break;
case CHARIOT: name = (color == RED) ? "俥" : "车"; break;
case CANNON: name = (color == RED) ? "砲" : "炮"; break;
case SOLDIER: name = (color == RED) ? "兵" : "卒"; break;
default: name = " ";
}
// 根据棋子颜色添加颜色代码
if (color == RED) {
return Color::RED + name + Color::RESET;
} else if (color == BLACK) {
return Color::WHITE + name + Color::RESET;
}
return name;
}
// 复制构造函数
Piece(const Piece& other) {
type = other.type;
color = other.color;
x = other.x;
y = other.y;
selected = other.selected;
}
};
// 移动结构
struct Move {
int fromX, fromY, toX, toY;
int score;
Move(int fx, int fy, int tx, int ty) : fromX(fx), fromY(fy), toX(tx), toY(ty), score(0) {}
};
// 棋盘类
class ChessBoard {
private:
vector<vector<Piece>> board;
PieceColor currentPlayer;
bool gameOver;
string winner;
bool aiEnabled; // 是否启用AI
// 棋子基础价值
const int PIECE_VALUES[8] = {0, 10000, 200, 200, 400, 900, 450, 100};
// 棋子位置价值表(黑方视角)
const int SOLDIER_POSITION_VALUE[10][9] = {
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0},
{10, 0, 15, 0, 20, 0, 15, 0, 10},
{10, 0, 15, 0, 20, 0, 15, 0, 10},
{20, 0, 25, 0, 30, 0, 25, 0, 20},
{30, 0, 35, 0, 40, 0, 35, 0, 30},
{40, 0, 45, 0, 50, 0, 45, 0, 40},
{50, 0, 55, 0, 60, 0, 55, 0, 50},
{0, 0, 0, 0, 0, 0, 0, 0, 0}
};
public:
ChessBoard() {
// 初始化9x10的棋盘
board.resize(9, vector<Piece>(10));
initializeBoard();
currentPlayer = RED;
gameOver = false;
winner = "";
aiEnabled = false; // 默认不启用AI
}
// 复制构造函数
ChessBoard(const ChessBoard& other) {
board = other.board;
currentPlayer = other.currentPlayer;
gameOver = other.gameOver;
winner = other.winner;
aiEnabled = other.aiEnabled;
}
// 启用或禁用AI
void setAIEnabled(bool enabled) {
aiEnabled = enabled;
}
// 初始化棋盘
void initializeBoard() {
// 清空棋盘
for (int x = 0; x < 9; x++) {
for (int y = 0; y < 10; y++) {
board[x][y] = Piece(EMPTY, NONE, x, y);
}
}
// 布置红方棋子
board[0][9] = Piece(CHARIOT, RED, 0, 9);
board[1][9] = Piece(HORSE, RED, 1, 9);
board[2][9] = Piece(ELEPHANT, RED, 2, 9);
board[3][9] = Piece(ADVISOR, RED, 3, 9);
board[4][9] = Piece(GENERAL, RED, 4, 9);
board[5][9] = Piece(ADVISOR, RED, 5, 9);
board[6][9] = Piece(ELEPHANT, RED, 6, 9);
board[7][9] = Piece(HORSE, RED, 7, 9);
board[8][9] = Piece(CHARIOT, RED, 8, 9);
board[1][7] = Piece(CANNON, RED, 1, 7);
board[7][7] = Piece(CANNON, RED, 7, 7);
board[0][6] = Piece(SOLDIER, RED, 0, 6);
board[2][6] = Piece(SOLDIER, RED, 2, 6);
board[4][6] = Piece(SOLDIER, RED, 4, 6);
board[6][6] = Piece(SOLDIER, RED, 6, 6);
board[8][6] = Piece(SOLDIER, RED, 8, 6);
// 布置黑方棋子
board[0][0] = Piece(CHARIOT, BLACK, 0, 0);
board[1][0] = Piece(HORSE, BLACK, 1, 0);
board[2][0] = Piece(ELEPHANT, BLACK, 2, 0);
board[3][0] = Piece(ADVISOR, BLACK, 3, 0);
board[4][0] = Piece(GENERAL, BLACK, 4, 0);
board[5][0] = Piece(ADVISOR, BLACK, 5, 0);
board[6][0] = Piece(ELEPHANT, BLACK, 6, 0);
board[7][0] = Piece(HORSE, BLACK, 7, 0);
board[8][0] = Piece(CHARIOT, BLACK, 8, 0);
board[1][2] = Piece(CANNON, BLACK, 1, 2);
board[7][2] = Piece(CANNON, BLACK, 7, 2);
board[0][3] = Piece(SOLDIER, BLACK, 0, 3);
board[2][3] = Piece(SOLDIER, BLACK, 2, 3);
board[4][3] = Piece(SOLDIER, BLACK, 4, 3);
board[6][3] = Piece(SOLDIER, BLACK, 6, 3);
board[8][3] = Piece(SOLDIER, BLACK, 8, 3);
}
// 显示棋盘
void display() {
cout << "\n 0 1 2 3 4 5 6 7 8 " << endl;
cout << " ┌--┬--┬--┬--┬--┬--┬--┬--┬--┐" << endl;
for (int y = 0; y < 10; y++) {
cout << y << " │";
for (int x = 0; x < 9; x++) {
cout << board[x][y].getName();
if (x < 8) cout << "│";
}
cout << "│" << endl;
if (y < 9) {
if (y == 4) {
cout << " ├--┼--┼--┼--┼--┼--┼--┼--┼--┤" << endl;
} else {
cout << " ├--┼--┼--┼--┼--┼--┼--┼--┼--┤" << endl;
}
}
}
cout << " └--┴--┴--┴--┴--┴--┴--┴--┴--┘" << endl;
cout << "\n当前回合: " << (currentPlayer == RED ? Color::RED + "红方" + Color::RESET : "黑方") << endl;
if (aiEnabled && currentPlayer == BLACK) {
cout << "黑方由AI控制" << endl;
}
}
// 检查移动是否合法
bool isValidMove(int fromX, int fromY, int toX, int toY) {
// 检查坐标是否在棋盘内
if (fromX < 0 || fromX >= 9 || fromY < 0 || fromY >= 10 ||
toX < 0 || toX >= 9 || toY < 0 || toY >= 10) {
return false;
}
Piece fromPiece = board[fromX][fromY];
Piece toPiece = board[toX][toY];
// 检查是否选择己方棋子
if (fromPiece.color != currentPlayer) {
return false;
}
// 检查是否吃己方棋子
if (toPiece.color == currentPlayer) {
return false;
}
// 根据棋子类型检查移动规则
switch(fromPiece.type) {
case GENERAL:
return isValidGeneralMove(fromX, fromY, toX, toY);
case ADVISOR:
return isValidAdvisorMove(fromX, fromY, toX, toY);
case ELEPHANT:
return isValidElephantMove(fromX, fromY, toX, toY);
case HORSE:
return isValidHorseMove(fromX, fromY, toX, toY);
case CHARIOT:
return isValidChariotMove(fromX, fromY, toX, toY);
case CANNON:
return isValidCannonMove(fromX, fromY, toX, toY);
case SOLDIER:
return isValidSoldierMove(fromX, fromY, toX, toY);
default:
return false;
}
}
// 将/帅移动规则
bool isValidGeneralMove(int fromX, int fromY, int toX, int toY) {
// 将/帅只能在九宫格内移动
if (currentPlayer == RED) {
if (toX < 3 || toX > 5 || toY < 7 || toY > 9) return false;
} else {
if (toX < 3 || toX > 5 || toY < 0 || toY > 2) return false;
}
// 只能移动一步
if (abs(fromX - toX) + abs(fromY - toY) != 1) return false;
return true;
}
// 士/仕移动规则
bool isValidAdvisorMove(int fromX, int fromY, int toX, int toY) {
// 士/仕只能在九宫格内斜线移动
if (currentPlayer == RED) {
if (toX < 3 || toX > 5 || toY < 7 || toY > 9) return false;
} else {
if (toX < 3 || toX > 5 || toY < 0 || toY > 2) return false;
}
// 只能斜线移动一步
if (abs(fromX - toX) != 1 || abs(fromY - toY) != 1) return false;
return true;
}
// 象/相移动规则
bool isValidElephantMove(int fromX, int fromY, int toX, int toY) {
// 象不能过河
if (currentPlayer == RED && toY < 5) return false;
if (currentPlayer == BLACK && toY > 4) return false;
// 象走田字
if (abs(fromX - toX) != 2 || abs(fromY - toY) != 2) return false;
// 检查象眼是否被塞
int eyeX = (fromX + toX) / 2;
int eyeY = (fromY + toY) / 2;
if (board[eyeX][eyeY].type != EMPTY) return false;
return true;
}
// 马/傌移动规则
bool isValidHorseMove(int fromX, int fromY, int toX, int toY) {
// 马走日字
int dx = abs(fromX - toX);
int dy = abs(fromY - toY);
if (!((dx == 1 && dy == 2) || (dx == 2 && dy == 1))) return false;
// 检查马腿是否被绊
if (dx == 2) {
int legX = (fromX + toX) / 2;
if (board[legX][fromY].type != EMPTY) return false;
} else {
int legY = (fromY + toY) / 2;
if (board[fromX][legY].type != EMPTY) return false;
}
return true;
}
// 车/俥移动规则
bool isValidChariotMove(int fromX, int fromY, int toX, int toY) {
// 车只能直线移动
if (fromX != toX && fromY != toY) return false;
// 检查路径上是否有其他棋子
if (fromX == toX) {
int startY = min(fromY, toY);
int endY = max(fromY, toY);
for (int y = startY + 1; y < endY; y++) {
if (board[fromX][y].type != EMPTY) return false;
}
} else {
int startX = min(fromX, toX);
int endX = max(fromX, toX);
for (int x = startX + 1; x < endX; x++) {
if (board[x][fromY].type != EMPTY) return false;
}
}
return true;
}
// 炮/砲移动规则
bool isValidCannonMove(int fromX, int fromY, int toX, int toY) {
// 炮只能直线移动
if (fromX != toX && fromY != toY) return false;
int pieceCount = 0;
// 计算路径上的棋子数量
if (fromX == toX) {
int startY = min(fromY, toY);
int endY = max(fromY, toY);
for (int y = startY + 1; y < endY; y++) {
if (board[fromX][y].type != EMPTY) pieceCount++;
}
} else {
int startX = min(fromX, toX);
int endX = max(fromX, toX);
for (int x = startX + 1; x < endX; x++) {
if (board[x][fromY].type != EMPTY) pieceCount++;
}
}
// 如果目标位置有棋子,必须隔一个棋子吃子
if (board[toX][toY].type != EMPTY) {
return pieceCount == 1;
} else {
// 如果目标位置没有棋子,路径上不能有棋子
return pieceCount == 0;
}
}
// 兵/卒移动规则
bool isValidSoldierMove(int fromX, int fromY, int toX, int toY) {
// 兵只能向前移动一步,过河后可以左右移动
if (currentPlayer == RED) {
// 红方兵向上移动
if (fromY < toY) return false; // 不能后退
if (fromY > 4) {
// 未过河,只能向前
if (fromX != toX || fromY - toY != 1) return false;
} else {
// 已过河,可以向前或左右
if (!((fromX == toX && fromY - toY == 1) ||
(fromY == toY && abs(fromX - toX) == 1))) return false;
}
} else {
// 黑方卒向下移动
if (fromY > toY) return false; // 不能后退
if (fromY < 5) {
// 未过河,只能向前
if (fromX != toX || toY - fromY != 1) return false;
} else {
// 已过河,可以向前或左右
if (!((fromX == toX && toY - fromY == 1) ||
(fromY == toY && abs(fromX - toX) == 1))) return false;
}
}
return true;
}
// 执行移动
void makeMove(int fromX, int fromY, int toX, int toY) {
// 检查是否吃将/帅
if (board[toX][toY].type == GENERAL) {
gameOver = true;
winner = (currentPlayer == RED) ? "红方" : "黑方";
}
// 移动棋子
board[toX][toY] = board[fromX][fromY];
board[toX][toY].x = toX;
board[toX][toY].y = toY;
board[fromX][fromY] = Piece(EMPTY, NONE, fromX, fromY);
// 切换玩家
currentPlayer = (currentPlayer == RED) ? BLACK : RED;
}
// 执行移动(不切换玩家,用于AI搜索)
void makeMoveForSearch(int fromX, int fromY, int toX, int toY) {
// 移动棋子
board[toX][toY] = board[fromX][fromY];
board[toX][toY].x = toX;
board[toX][toY].y = toY;
board[fromX][fromY] = Piece(EMPTY, NONE, fromX, fromY);
}
// 撤销移动(用于AI搜索)
void undoMove(int fromX, int fromY, int toX, int toY, Piece capturedPiece) {
// 恢复原棋子
board[fromX][fromY] = board[toX][toY];
board[fromX][fromY].x = fromX;
board[fromX][fromY].y = fromY;
// 恢复被吃的棋子
board[toX][toY] = capturedPiece;
}
// 获取当前玩家
PieceColor getCurrentPlayer() const {
return currentPlayer;
}
// 设置当前玩家
void setCurrentPlayer(PieceColor player) {
currentPlayer = player;
}
// 检查游戏是否结束
bool isGameOver() const {
return gameOver;
}
// 获取所有合法移动
vector<Move> getAllLegalMoves(PieceColor player) {
vector<Move> moves;
// 保存当前玩家
PieceColor originalPlayer = currentPlayer;
currentPlayer = player;
// 遍历棋盘上的所有棋子
for (int x = 0; x < 9; x++) {
for (int y = 0; y < 10; y++) {
if (board[x][y].color == player) {
// 对于每个棋子,检查所有可能的移动
for (int tx = 0; tx < 9; tx++) {
for (int ty = 0; ty < 10; ty++) {
if (isValidMove(x, y, tx, ty)) {
moves.push_back(Move(x, y, tx, ty));
}
}
}
}
}
}
// 恢复原玩家
currentPlayer = originalPlayer;
return moves;
}
// 评估棋盘状态(从黑方视角)
int evaluate() {
int score = 0;
// 遍历棋盘上的所有棋子
for (int x = 0; x < 9; x++) {
for (int y = 0; y < 10; y++) {
Piece piece = board[x][y];
if (piece.type != EMPTY) {
int pieceValue = PIECE_VALUES[piece.type];
// 黑方棋子加正分,红方棋子加负分
if (piece.color == BLACK) {
score += pieceValue;
// 为兵/卒添加位置价值
if (piece.type == SOLDIER) {
score += SOLDIER_POSITION_VALUE[y][x];
}
} else {
score -= pieceValue;
// 为兵/卒添加位置价值(红方兵的位置价值需要转换视角)
if (piece.type == SOLDIER) {
score -= SOLDIER_POSITION_VALUE[9-y][8-x]; // 转换坐标
}
}
}
}
}
return score;
}
// Minimax算法与Alpha-Beta剪枝
int minimax(int depth, int alpha, int beta, bool maximizingPlayer) {
if (depth == 0 || isGameOver()) {
return evaluate();
}
vector<Move> moves = getAllLegalMoves(maximizingPlayer ? BLACK : RED);
if (maximizingPlayer) {
int maxEval = numeric_limits<int>::min();
for (Move move : moves) {
// 保存被吃的棋子
Piece capturedPiece = board[move.toX][move.toY];
// 执行移动
makeMoveForSearch(move.fromX, move.fromY, move.toX, move.toY);
// 递归评估
int eval = minimax(depth - 1, alpha, beta, false);
// 撤销移动
undoMove(move.fromX, move.fromY, move.toX, move.toY, capturedPiece);
maxEval = max(maxEval, eval);
alpha = max(alpha, eval);
if (beta <= alpha) {
break; // Alpha-Beta剪枝
}
}
return maxEval;
} else {
int minEval = numeric_limits<int>::max();
for (Move move : moves) {
// 保存被吃的棋子
Piece capturedPiece = board[move.toX][move.toY];
// 执行移动
makeMoveForSearch(move.fromX, move.fromY, move.toX, move.toY);
// 递归评估
int eval = minimax(depth - 1, alpha, beta, true);
// 撤销移动
undoMove(move.fromX, move.fromY, move.toX, move.toY, capturedPiece);
minEval = min(minEval, eval);
beta = min(beta, eval);
if (beta <= alpha) {
break; // Alpha-Beta剪枝
}
}
return minEval;
}
}
// AI选择最佳移动
Move findBestMove() {
vector<Move> moves = getAllLegalMoves(BLACK);
if (moves.empty()) {
// 如果没有合法移动,返回一个无效移动
return Move(-1, -1, -1, -1);
}
int bestValue = numeric_limits<int>::min();
Move bestMove = moves[0];
// 设置搜索深度(可以根据需要调整)
int depth = 4;
for (Move move : moves) {
// 保存被吃的棋子
Piece capturedPiece = board[move.toX][move.toY];
// 执行移动
makeMoveForSearch(move.fromX, move.fromY, move.toX, move.toY);
// 评估移动
int moveValue = minimax(depth - 1, numeric_limits<int>::min(), numeric_limits<int>::max(), false);
// 撤销移动
undoMove(move.fromX, move.fromY, move.toX, move.toY, capturedPiece);
// 更新最佳移动
if (moveValue > bestValue) {
bestValue = moveValue;
bestMove = move;
}
}
return bestMove;
}
// AI进行移动
void makeAIMove() {
if (currentPlayer == BLACK && !gameOver) {
cout << "AI正在思考..." << endl;
// 添加延迟,使AI思考看起来更自然
auto start = chrono::steady_clock::now();
Move bestMove = findBestMove();
auto end = chrono::steady_clock::now();
auto duration = chrono::duration_cast<chrono::milliseconds>(end - start);
// 确保AI思考至少1秒,使其看起来更真实
if (duration.count() < 1000) {
this_thread::sleep_for(chrono::milliseconds(1000 - duration.count()));
}
if (bestMove.fromX != -1) {
cout << "AI移动: " << bestMove.fromX << " " << bestMove.fromY << " "
<< bestMove.toX << " " << bestMove.toY << endl;
makeMove(bestMove.fromX, bestMove.fromY, bestMove.toX, bestMove.toY);
}
}
}
// 处理玩家输入
void handlePlayerInput() {
int fromX, fromY, toX, toY;
cout << "请输入移动(从列从行到列到行)方格内: ";
cin >> fromX >> fromY >> toX >> toY;
if (isValidMove(fromX, fromY, toX, toY)) {
makeMove(fromX, fromY, toX, toY);
} else {
cout << "无效移动,请重新输入!" << endl;
}
}
// 游戏主循环
void playGame() {
cout << "欢迎来到中国象棋游戏!" << endl;
cout << "红方先行(红是下方,黑是上方),使用坐标选择棋子并移动(例如:3 7 3 6)" << endl;
// 选择游戏模式
int mode;
cout << "请选择游戏模式:" << endl;
cout << "1. 单人模式 (玩家执红 vs AI执黑)" << endl;
cout << "2. 双人模式 (两个玩家轮流)" << endl;
cout << "请输入选择 (1 或 2): ";
cin >> mode;
if (mode == 1) {
aiEnabled = true;
cout << "已选择单人模式,黑方由AI控制" << endl;
} else {
aiEnabled = false;
cout << "已选择双人模式" << endl;
}
while (!gameOver) {
display();
if (currentPlayer == RED) {
// 红方总是玩家
handlePlayerInput();
} else {
// 黑方:如果是单人模式且启用了AI,则使用AI;否则由玩家控制
if (aiEnabled) {
makeAIMove();
} else {
cout << "黑方回合:" << endl;
handlePlayerInput();
}
}
}
cout << "游戏结束!" << winner << "获胜!" << endl;
}
};
int main() {
ChessBoard game;
game.playGame();
return 0;
}
1 条评论
-
梁家硕 @ 2025-10-29 17:15:35666
- 1
信息
- ID
- 940
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 8
- 标签
- 递交数
- 135
- 已通过
- 25
- 上传者