refactor ninechess.cpp etc

This commit is contained in:
CalciteM Team 2019-08-31 12:27:45 +08:00
parent d311183bf4
commit 21809d5dda
5 changed files with 179 additions and 173 deletions

View File

@ -108,12 +108,7 @@ void AiThread::run()
while (!isInterruptionRequested()) {
mutex.lock();
if (chess_->whosTurn() == NineChess::PLAYER1)
i = 1;
else if (chess_->whosTurn() == NineChess::PLAYER2)
i = 2;
else
i = 0;
i = NineChess::playerToId(chess_->whosTurn());
if (i != id || waiting_) {
pauseCondition.wait(&mutex);

View File

@ -45,8 +45,8 @@ GameController::GameController(GameScene & scene, QObject * parent) :
currentRow(-1),
isEditing(false),
isInverted(false),
isEngine1(false),
isEngine2(false),
isAiPlayer1(false),
isAiPlayer2(false),
hasAnimation(true),
durationTime(500),
hasSound(true),
@ -146,8 +146,8 @@ void GameController::gameReset()
// 停掉线程
ai1.stop();
ai2.stop();
isEngine1 = false;
isEngine2 = false;
isAiPlayer1 = false;
isAiPlayer2 = false;
// 清除棋子
qDeleteAll(pieceList);
@ -278,7 +278,7 @@ void GameController::setRule(int ruleNo, NineChess::step_t stepLimited /*= -1*/,
void GameController::setEngine1(bool arg)
{
isEngine1 = arg;
isAiPlayer1 = arg;
if (arg) {
ai1.setAi(chess_);
if (ai1.isRunning())
@ -292,7 +292,7 @@ void GameController::setEngine1(bool arg)
void GameController::setEngine2(bool arg)
{
isEngine2 = arg;
isAiPlayer2 = arg;
if (arg) {
ai2.setAi(chess_);
if (ai2.isRunning())
@ -306,11 +306,11 @@ void GameController::setEngine2(bool arg)
void GameController::setAiDepthTime(NineChessAi_ab::depth_t depth1, int time1, NineChessAi_ab::depth_t depth2, int time2)
{
if (isEngine1) {
if (isAiPlayer1) {
ai1.stop();
ai1.wait();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.stop();
ai2.wait();
}
@ -318,10 +318,10 @@ void GameController::setAiDepthTime(NineChessAi_ab::depth_t depth1, int time1, N
ai1.setAi(chess_, depth1, time1);
ai2.setAi(chess_, depth2, time2);
if (isEngine1) {
if (isAiPlayer1) {
ai1.start();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.start();
}
}
@ -364,11 +364,11 @@ void GameController::playSound(const QString &soundPath)
// 上下翻转
void GameController::flip()
{
if (isEngine1) {
if (isAiPlayer1) {
ai1.stop();
ai1.wait();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.stop();
ai2.wait();
}
@ -392,11 +392,11 @@ void GameController::flip()
ai1.setAi(chess_);
ai2.setAi(chess_);
if (isEngine1) {
if (isAiPlayer1) {
ai1.start();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.start();
}
}
@ -404,11 +404,11 @@ void GameController::flip()
// 左右镜像
void GameController::mirror()
{
if (isEngine1) {
if (isAiPlayer1) {
ai1.stop();
ai1.wait();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.stop();
ai2.wait();
}
@ -434,11 +434,11 @@ void GameController::mirror()
ai1.setAi(chess_);
ai2.setAi(chess_);
if (isEngine1) {
if (isAiPlayer1) {
ai1.start();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.start();
}
}
@ -446,11 +446,11 @@ void GameController::mirror()
// 视图须时针旋转90°
void GameController::turnRight()
{
if (isEngine1) {
if (isAiPlayer1) {
ai1.stop();
ai1.wait();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.stop();
ai2.wait();
}
@ -474,11 +474,11 @@ void GameController::turnRight()
ai1.setAi(chess_);
ai2.setAi(chess_);
if (isEngine1) {
if (isAiPlayer1) {
ai1.start();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.start();
}
}
@ -486,11 +486,11 @@ void GameController::turnRight()
// 视图逆时针旋转90°
void GameController::turnLeft()
{
if (isEngine1) {
if (isAiPlayer1) {
ai1.stop();
ai1.wait();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.stop();
ai2.wait();
}
@ -509,10 +509,10 @@ void GameController::turnLeft()
ai1.setAi(chess_);
ai2.setAi(chess_);
if (isEngine1) {
if (isAiPlayer1) {
ai1.start();
}
if (isEngine2) {
if (isAiPlayer2) {
ai2.start();
}
}
@ -584,6 +584,12 @@ void GameController::timerEvent(QTimerEvent *event)
#endif
}
bool GameController::isAIsTurn()
{
return ((chess_.whosTurn() == NineChess::PLAYER1 && isAiPlayer1) ||
(chess_.whosTurn() == NineChess::PLAYER2 && isAiPlayer2));
}
// 关键槽函数根据QGraphicsScene的信号和状态来执行选子、落子或去子
bool GameController::actionPiece(QPointF pos)
{
@ -594,11 +600,9 @@ bool GameController::actionPiece(QPointF pos)
}
// 电脑走棋时,点击无效
if (chess_.whosTurn() == NineChess::PLAYER1 && isEngine1)
return false;
if (chess_.whosTurn() == NineChess::PLAYER2 && isEngine2)
if (isAIsTurn()) {
return false;
}
// 在浏览历史记录时点击棋盘,则认为是悔棋
if (currentRow != manualListModel.rowCount() - 1) {
@ -722,15 +726,15 @@ bool GameController::actionPiece(QPointF pos)
// 如果还未决出胜负
if (chess_.whoWin() == NineChess::NOBODY) {
if (chess_.whosTurn() == NineChess::PLAYER1) {
if (isEngine1) {
if (isAiPlayer1) {
ai1.resume();
}
if (isEngine2)
if (isAiPlayer2)
ai2.pause();
} else {
if (isEngine1)
if (isAiPlayer1)
ai1.pause();
if (isEngine2) {
if (isAiPlayer2) {
ai2.resume();
}
}
@ -790,10 +794,10 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
Q_UNUSED(hasSound)
// 防止接收滞后结束的线程发送的指令
if (sender() == &ai1 && !isEngine1)
if (sender() == &ai1 && !isAiPlayer1)
return false;
if (sender() == &ai2 && !isEngine2)
if (sender() == &ai2 && !isAiPlayer2)
return false;
// 声音
@ -867,15 +871,15 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
// 如果还未决出胜负
if (chess_.whoWin() == NineChess::NOBODY) {
if (chess_.whosTurn() == NineChess::PLAYER1) {
if (isEngine1) {
if (isAiPlayer1) {
ai1.resume();
}
if (isEngine2)
if (isAiPlayer2)
ai2.pause();
} else {
if (isEngine1)
if (isAiPlayer1)
ai1.pause();
if (isEngine2) {
if (isAiPlayer2) {
ai2.resume();
}
}
@ -894,11 +898,11 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
}
// 网络: 将着法放到服务器的发送列表中
if (isEngine1)
if (isAiPlayer1)
{
ai1.getServer()->setAction(cmd);
qDebug() << "isEngine1: AI(1) set Action: " << cmd;
} else if (isEngine2) {
} else if (isAiPlayer2) {
ai1.getServer()->setAction(cmd); // 注意: 同样是AI1
qDebug() << "isEngine2: AI(1) set Action: " << cmd;
}

View File

@ -157,6 +157,8 @@ public slots:
// 视图逆时针旋转90°
void turnLeft();
bool isAIsTurn();
// 根据QGraphicsScene的信号和状态来执行选子、落子或去子
bool actionPiece(QPointF p);
@ -213,10 +215,10 @@ private:
bool isInverted;
// 是否电脑执先手
bool isEngine1;
bool isAiPlayer1;
// 是否电脑执后手
bool isEngine2;
bool isAiPlayer2;
// 是否有落子动画
bool hasAnimation;

View File

@ -152,6 +152,8 @@ NineChess::NineChess()
score_1 = score_2 = score_draw = 0;
}
NineChess::~NineChess() = default;
NineChess::NineChess(const NineChess &chess)
{
*this = chess;
@ -177,11 +179,19 @@ NineChess &NineChess::operator = (const NineChess &chess)
memcpy(cmdline, chess.cmdline, sizeof(cmdline));
cmdlist = chess.cmdlist;
tips = chess.tips;
return *this;
}
int NineChess::playerToId(enum Player player)
{
if (player == NineChess::PLAYER1)
return 1;
else if (player == NineChess::PLAYER2)
return 2;
NineChess::~NineChess() = default;
return 0;
}
NineChess::Player NineChess::getOpponent(NineChess::Player player)
{
@ -323,7 +333,7 @@ bool NineChess::setContext(const struct Rule *rule, step_t maxStepsLedToDraw, in
this->currentRule.maxTimeLedToLose = maxTimeLedToLose;
// 设置棋局数据
{
// 设置步数
this->currentStep = initialStep;
this->moveStep = initialStep;
@ -331,47 +341,35 @@ bool NineChess::setContext(const struct Rule *rule, step_t maxStepsLedToDraw, in
// 局面阶段标识
if (flags & GAME_NOTSTARTED) {
context.stage = GAME_NOTSTARTED;
}
else if (flags & GAME_PLACING) {
} else if (flags & GAME_PLACING) {
context.stage = GAME_PLACING;
}
else if (flags & GAME_MOVING) {
} else if (flags & GAME_MOVING) {
context.stage = GAME_MOVING;
//context.hash ^= // TODO
}
else if (flags & GAME_OVER) {
} else if (flags & GAME_OVER) {
context.stage = GAME_OVER;
}
else {
} else {
return false;
}
// 轮流状态标识
if (flags & PLAYER1) {
// if (context.turn == PLAYER2) {
// context.hash ^= player2sTurnHash;
// }
context.turn = PLAYER1;
}
else if (flags & PLAYER2) {
// if (context.turn == PLAYER1) {
// context.hash ^= player2sTurnHash;
// }
} else if (flags & PLAYER2) {
context.turn = PLAYER2;
}
else {
} else {
return false;
}
// 动作状态标识
if (flags & ACTION_CHOOSE)
if (flags & ACTION_CHOOSE) {
context.action = ACTION_CHOOSE;
else if (flags & ACTION_PLACE)
} else if (flags & ACTION_PLACE) {
context.action = ACTION_PLACE;
else if (flags & ACTION_CAPTURE)
} else if (flags & ACTION_CAPTURE) {
context.action = ACTION_CAPTURE;
else
} else {
return false;
}
// 当前棋局3×8
if (board == nullptr) {
@ -394,20 +392,17 @@ bool NineChess::setContext(const struct Rule *rule, step_t maxStepsLedToDraw, in
(board[i] & 0x20)
*/
context.nPiecesOnBoard_1 = context.nPiecesOnBoard_2 = 0;
for (int r = 1; r < N_RINGS + 2; r++) {
for (int s = 0; s < N_SEATS; s++) {
int pos = r * N_SEATS + s;
if (context.board[pos] & '\x10') {
if (context.board[pos] & 0x10) {
context.nPiecesOnBoard_1++;
}
else if (context.board[pos] & '\x20') {
} else if (context.board[pos] & 0x20) {
context.nPiecesOnBoard_2++;
}
else if (context.board[pos] & '\x0F') {
} else if (context.board[pos] & 0x0F) {
// 不计算盘面子数
}
//updateHash(pos);
}
}
@ -428,15 +423,15 @@ bool NineChess::setContext(const struct Rule *rule, step_t maxStepsLedToDraw, in
// 设置去子状态时的剩余尚待去除子数
if (flags & ACTION_CAPTURE) {
if (0 <= nPiecesNeedRemove && nPiecesNeedRemove < 3)
if (0 <= nPiecesNeedRemove && nPiecesNeedRemove < 3) {
context.nPiecesNeedRemove = nPiecesNeedRemove;
}
} else {
context.nPiecesNeedRemove = 0;
}
// 清空成三记录
context.millList.clear();
}
// 胜负标识
winner = NOBODY;
@ -480,7 +475,7 @@ void NineChess::getContext(struct Rule &rule, step_t &step, int &flags,
rule = this->currentRule;
step = this->currentStep;
flags = context.stage | context.turn | context.action;
this->board_ = board;
board_ = board;
nPiecesInHand_1 = context.nPiecesInHand_1;
nPiecesInHand_2 = context.nPiecesInHand_2;
nPiecesNeedRemove = context.nPiecesNeedRemove;
@ -488,8 +483,10 @@ void NineChess::getContext(struct Rule &rule, step_t &step, int &flags,
bool NineChess::reset()
{
if (context.stage == GAME_NOTSTARTED && elapsedSeconds_1 == elapsedSeconds_2 == 0)
if (context.stage == GAME_NOTSTARTED &&
elapsedSeconds_1 == elapsedSeconds_2 == 0) {
return true;
}
// 步数归零
currentStep = 0;
@ -546,7 +543,8 @@ bool NineChess::reset()
break;
}
if (sprintf(cmdline, "r%1u s%03u t%02u", i + 1, currentRule.maxStepsLedToDraw, currentRule.maxTimeLedToLose) > 0) {
if (sprintf(cmdline, "r%1u s%03u t%02u",
i + 1, currentRule.maxStepsLedToDraw, currentRule.maxTimeLedToLose) > 0) {
cmdlist.emplace_back(string(cmdline));
return true;
}
@ -579,16 +577,18 @@ bool NineChess::start()
}
}
// Unused
bool NineChess::getPieceCP(const Player &player, const int &number, int &c, int &p)
{
int piece;
if (player == PLAYER1)
if (player == PLAYER1) {
piece = 0x10;
else if (player == PLAYER2)
} else if (player == PLAYER2) {
piece = 0x20;
else
} else {
return false;
}
if (number > 0 && number <= currentRule.nTotalPiecesEachSide)
piece &= number;
@ -611,14 +611,17 @@ bool NineChess::getCurrentPiece(Player &player, int &number)
if (!onBoard[currentPos])
return false;
if (board_[currentPos] & 0x10) {
int p = board_[currentPos];
if (p & 0x10) {
player = PLAYER1;
number = board_[currentPos] - 0x10;
} else if (board_[currentPos] & 0x20) {
number = p - 0x10;
} else if (p & 0x20) {
player = PLAYER2;
number = board_[currentPos] - 0x20;
} else
number = p - 0x20;
} else {
return false;
}
return true;
}
@ -1427,12 +1430,12 @@ bool NineChess::isAllInMills(char ch)
bool NineChess::isAllInMills(enum Player player)
{
char ch = '\x00';
char ch = 0x00;
if (player == PLAYER1)
ch = '\x10';
ch = 0x10;
else if (player == PLAYER2)
ch = '\x20';
ch = 0x20;
else
return true;

View File

@ -166,14 +166,16 @@ public:
}
// 玩家标识, 轮流状态, 胜负标识
enum Player : uint16_t
enum Player : uint8_t
{
PLAYER1 = 0x0010, // 玩家1
PLAYER2 = 0x0020, // 玩家2
DRAW = 0x0040, // 双方和棋
NOBODY = 0x0080 // 胜负未分
PLAYER1 = 0x10, // 玩家1
PLAYER2 = 0x20, // 玩家2
DRAW = 0x40, // 双方和棋
NOBODY = 0x80 // 胜负未分
};
static int playerToId(enum Player player);
static Player getOpponent(enum Player player);
// 动作状态标识