移除 player_t 类型并全部用 Color 类型取代

This commit is contained in:
Calcitem 2020-07-05 10:57:31 +08:00
parent 58acff7ce2
commit 1d7ecd6680
16 changed files with 157 additions and 200 deletions

View File

@ -45,7 +45,7 @@ Value Eval::evaluate(Position *pos)
break; break;
case ACTION_REMOVE: case ACTION_REMOVE:
nPiecesNeedRemove = (pos->sideToMove == PLAYER_BLACK) ? nPiecesNeedRemove = (pos->sideToMove == BLACK) ?
pos->nPiecesNeedRemove : -(pos->nPiecesNeedRemove); pos->nPiecesNeedRemove : -(pos->nPiecesNeedRemove);
value += nPiecesNeedRemove * VALUE_EACH_PIECE_PLACING_NEEDREMOVE; value += nPiecesNeedRemove * VALUE_EACH_PIECE_PLACING_NEEDREMOVE;
break; break;
@ -69,7 +69,7 @@ Value Eval::evaluate(Position *pos)
break; break;
case ACTION_REMOVE: case ACTION_REMOVE:
nPiecesNeedRemove = (pos->sideToMove == PLAYER_BLACK) ? nPiecesNeedRemove = (pos->sideToMove == BLACK) ?
pos->nPiecesNeedRemove : -(pos->nPiecesNeedRemove); pos->nPiecesNeedRemove : -(pos->nPiecesNeedRemove);
value += nPiecesNeedRemove * VALUE_EACH_PIECE_MOVING_NEEDREMOVE; value += nPiecesNeedRemove * VALUE_EACH_PIECE_MOVING_NEEDREMOVE;
break; break;
@ -88,9 +88,9 @@ Value Eval::evaluate(Position *pos)
value = VALUE_DRAW; value = VALUE_DRAW;
} }
} else if (pos->action == ACTION_SELECT && } else if (pos->action == ACTION_SELECT &&
pos->board.isAllSurrounded(pos->sideId, pos->nPiecesOnBoard, pos->sideToMove) && pos->board.isAllSurrounded(pos->sideToMove, pos->nPiecesOnBoard) &&
rule.isLoseButNotChangeTurnWhenNoWay) { rule.isLoseButNotChangeTurnWhenNoWay) {
Value delta = pos->sideToMove == PLAYER_BLACK ? -VALUE_MATE : VALUE_MATE; Value delta = pos->sideToMove == BLACK ? -VALUE_MATE : VALUE_MATE;
value += delta; value += delta;
} }
@ -106,7 +106,7 @@ Value Eval::evaluate(Position *pos)
break; break;
} }
if (pos->sideToMove == PLAYER_WHITE) { if (pos->sideToMove == WHITE) {
value = -value; value = -value;
} }

View File

@ -293,7 +293,7 @@ void MoveList::shuffle()
ExtMove *generateMoves(/* TODO: const */ Position *position, ExtMove *moveList) ExtMove *generateMoves(/* TODO: const */ Position *position, ExtMove *moveList)
{ {
Square square; Square square;
player_t opponent; Color opponent;
//moves.clear(); //moves.clear();
ExtMove *cur = moveList; ExtMove *cur = moveList;
@ -340,7 +340,7 @@ ExtMove *generateMoves(/* TODO: const */ Position *position, ExtMove *moveList)
continue; continue;
} }
if (position->nPiecesOnBoard[position->sideId] > rule.nPiecesAtLeast || if (position->nPiecesOnBoard[position->sideToMove] > rule.nPiecesAtLeast ||
!rule.allowFlyWhenRemainThreePieces) { !rule.allowFlyWhenRemainThreePieces) {
for (int direction = MD_BEGIN; direction < MD_NB; direction++) { for (int direction = MD_BEGIN; direction < MD_NB; direction++) {
newSquare = static_cast<Square>(MoveList::moveTable[oldSquare][direction]); newSquare = static_cast<Square>(MoveList::moveTable[oldSquare][direction]);
@ -368,7 +368,7 @@ ExtMove *generateMoves(/* TODO: const */ Position *position, ExtMove *moveList)
if (position->board.isAllInMills(opponent)) { if (position->board.isAllInMills(opponent)) {
for (int i = Board::MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) { for (int i = Board::MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) {
square = static_cast<Square>(MoveList::movePriorityTable[i]); square = static_cast<Square>(MoveList::movePriorityTable[i]);
if (position->board.locations[square] & opponent) { if (position->board.locations[square] & (opponent << PLAYER_SHIFT)) {
*cur++ = ((Move)-square); *cur++ = ((Move)-square);
} }
} }
@ -378,8 +378,8 @@ ExtMove *generateMoves(/* TODO: const */ Position *position, ExtMove *moveList)
// not is all in mills // not is all in mills
for (int i = Board::MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) { for (int i = Board::MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) {
square = static_cast<Square>(MoveList::movePriorityTable[i]); square = static_cast<Square>(MoveList::movePriorityTable[i]);
if (position->board.locations[square] & opponent) { if (position->board.locations[square] & (opponent << PLAYER_SHIFT)) {
if (rule.allowRemovePieceInMill || !position->board.inHowManyMills(square, PLAYER_NOBODY)) { if (rule.allowRemovePieceInMill || !position->board.inHowManyMills(square, NOBODY)) {
*cur++ = ((Move)-square); *cur++ = ((Move)-square);
} }
} }

View File

@ -84,7 +84,7 @@ void MovePicker::score()
int nBanned = 0; int nBanned = 0;
int nEmpty = 0; int nEmpty = 0;
position->board.getSurroundedPieceCount(sq, position->sideId, position->board.getSurroundedPieceCount(sq, position->sideToMove,
nPlayerPiece, nOpponentPiece, nBanned, nEmpty); nPlayerPiece, nOpponentPiece, nBanned, nEmpty);
#ifdef ALPHABETA_AI #ifdef ALPHABETA_AI
@ -114,7 +114,7 @@ void MovePicker::score()
int nBanned = 0; int nBanned = 0;
int nEmpty = 0; int nEmpty = 0;
position->board.getSurroundedPieceCount(sq, position->sideId, position->board.getSurroundedPieceCount(sq, position->sideToMove,
nPlayerPiece, nOpponentPiece, nBanned, nEmpty); nPlayerPiece, nOpponentPiece, nBanned, nEmpty);
#ifdef ALPHABETA_AI #ifdef ALPHABETA_AI

View File

@ -33,8 +33,6 @@
#include "misc.h" #include "misc.h"
#include "movepick.h" #include "movepick.h"
player_t gSideToMove;
using namespace CTSL; using namespace CTSL;
vector<Key> moveHistory; vector<Key> moveHistory;
@ -471,10 +469,10 @@ Value AIAlgorithm::search(Depth depth, Value alpha, Value beta)
for (int i = 0; i < nchild; i++) { for (int i = 0; i < nchild; i++) {
stashPosition(); stashPosition();
player_t before = pos->sideToMove; Color before = pos->sideToMove;
Move move = extMoves[i].move; Move move = extMoves[i].move;
doMove(move); doMove(move);
player_t after = pos->sideToMove; Color after = pos->sideToMove;
if (gameOptions.getDepthExtension() == true && nchild == 1) { if (gameOptions.getDepthExtension() == true && nchild == 1) {
epsilon = 1; epsilon = 1;
@ -617,14 +615,14 @@ const char* AIAlgorithm::nextMove()
moveIndex++; moveIndex++;
} }
//player_t side = position->sideToMove; Color side = position->sideToMove;
#ifdef ENDGAME_LEARNING #ifdef ENDGAME_LEARNING
// Check if very weak // Check if very weak
if (gameOptions.getLearnEndgameEnabled()) { if (gameOptions.getLearnEndgameEnabled()) {
if (bestValue <= -VALUE_KNOWN_WIN) { if (bestValue <= -VALUE_KNOWN_WIN) {
Endgame endgame; Endgame endgame;
endgame.type = state->position->sideToMove == PLAYER_BLACK ? endgame.type = state->position->playerSideToMove == PLAYER_BLACK ?
ENDGAME_PLAYER_WHITE_WIN : ENDGAME_PLAYER_BLACK_WIN; ENDGAME_PLAYER_WHITE_WIN : ENDGAME_PLAYER_BLACK_WIN;
key_t endgameHash = position->getPosKey(); // TODO: Do not generate hash repeately key_t endgameHash = position->getPosKey(); // TODO: Do not generate hash repeately
recordEndgameHash(endgameHash, endgame); recordEndgameHash(endgameHash, endgame);
@ -634,7 +632,7 @@ const char* AIAlgorithm::nextMove()
if (gameOptions.getGiveUpIfMostLose() == true) { if (gameOptions.getGiveUpIfMostLose() == true) {
if (root->value <= -VALUE_MATE) { if (root->value <= -VALUE_MATE) {
sprintf(cmdline, "Player%d give up!", position->sideId); sprintf(cmdline, "Player%d give up!", position->sideToMove);
return cmdline; return cmdline;
} }
} }

View File

@ -31,20 +31,20 @@ using namespace std;
#pragma execution_character_set("GB2312") #pragma execution_character_set("GB2312")
#endif #endif
AiThread::AiThread(int id, QObject *parent) : AiThread::AiThread(int color, QObject *parent) :
QThread(parent), QThread(parent),
position(nullptr), position(nullptr),
depth(2), depth(2),
timeLimit(3600) timeLimit(3600)
{ {
this->playerId = id; this->playerId = color;
connect(this, &AiThread::searchStarted, this, [=]() {timer.start(timeLimit * 1000 - 118 /* 118ms is return time */); }, Qt::QueuedConnection); connect(this, &AiThread::searchStarted, this, [=]() {timer.start(timeLimit * 1000 - 118 /* 118ms is return time */); }, Qt::QueuedConnection);
connect(this, &AiThread::searchFinished, this, [=]() {timer.stop(); }, Qt::QueuedConnection); connect(this, &AiThread::searchFinished, this, [=]() {timer.stop(); }, Qt::QueuedConnection);
connect(&timer, &QTimer::timeout, this, &AiThread::act, Qt::QueuedConnection); connect(&timer, &QTimer::timeout, this, &AiThread::act, Qt::QueuedConnection);
#ifndef TRAINING_MODE #ifndef TRAINING_MODE
if (id == 1) { if (color == 1) {
server = new Server(nullptr, 30001); // TODO: WARNING: ThreadSanitizer: data race server = new Server(nullptr, 30001); // TODO: WARNING: ThreadSanitizer: data race
uint16_t clientPort = server->getPort() == 30001 ? 30002 : 30001; uint16_t clientPort = server->getPort() == 30001 ? 30002 : 30001;
client = new Client(nullptr, clientPort); client = new Client(nullptr, clientPort);
@ -208,7 +208,7 @@ void AiThread::run()
int iTemp = 0; int iTemp = 0;
#endif #endif
int sideId = 0; Color sideToMove = NOCOLOR;
loggerDebug("Thread %d start\n", playerId); loggerDebug("Thread %d start\n", playerId);
@ -217,9 +217,9 @@ void AiThread::run()
while (!isInterruptionRequested()) { while (!isInterruptionRequested()) {
mutex.lock(); mutex.lock();
sideId = Player::toId(position->sideToMove); sideToMove = position->sideToMove;
if (sideId != playerId) { if (sideToMove != playerId) {
pauseCondition.wait(&mutex); pauseCondition.wait(&mutex);
mutex.unlock(); mutex.unlock();
continue; continue;

View File

@ -36,7 +36,7 @@ class AiThread : public QThread
public: public:
explicit AiThread(QObject *parent = nullptr); explicit AiThread(QObject *parent = nullptr);
explicit AiThread(int id, QObject *parent = nullptr); explicit AiThread(int color, QObject *parent = nullptr);
~AiThread() override; ~AiThread() override;
signals: signals:

View File

@ -198,18 +198,18 @@ Square Board::polarToSquare(File file, Rank rank)
return static_cast<Square>(file * N_RANKS + rank - 1); return static_cast<Square>(file * N_RANKS + rank - 1);
} }
player_t Board::locationToPlayer(Square square) Color Board::locationToColor(Square square)
{ {
return player_t(locations[square] & 0x30); return Color((locations[square] & 0x30) >> PLAYER_SHIFT);
} }
int Board::inHowManyMills(Square square, player_t player, Square squareSelected) int Board::inHowManyMills(Square square, Color c, Square squareSelected)
{ {
int n = 0; int n = 0;
Location locbak = SQ_0; Location locbak = SQ_0;
if (player == PLAYER_NOBODY) { if (c == NOBODY) {
player = locationToPlayer(square); c = Color(locationToColor(square) >> PLAYER_SHIFT);
} }
if (squareSelected != SQ_0) { if (squareSelected != SQ_0) {
@ -218,7 +218,7 @@ int Board::inHowManyMills(Square square, player_t player, Square squareSelected)
} }
for (int l = 0; l < LD_NB; l++) { for (int l = 0; l < LD_NB; l++) {
if (player & if ((c << PLAYER_SHIFT) &
locations[millTable[square][l][0]] & locations[millTable[square][l][0]] &
locations[millTable[square][l][1]]) { locations[millTable[square][l][1]]) {
n++; n++;
@ -237,7 +237,7 @@ int Board::addMills(Square square)
uint64_t mill = 0; uint64_t mill = 0;
int n = 0; int n = 0;
int idx[3], min, temp; int idx[3], min, temp;
player_t m = locationToPlayer(square); Color m = locationToColor(square);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
idx[0] = square; idx[0] = square;
@ -245,7 +245,7 @@ int Board::addMills(Square square)
idx[2] = millTable[square][i][1]; idx[2] = millTable[square][i][1];
// no mill // no mill
if (!(m & locations[idx[1]] & locations[idx[2]])) { if (!((m << PLAYER_SHIFT) & locations[idx[1]] & locations[idx[2]])) {
continue; continue;
} }
@ -298,11 +298,11 @@ int Board::addMills(Square square)
return n; return n;
} }
bool Board::isAllInMills(player_t player) bool Board::isAllInMills(Color c)
{ {
for (Square i = SQ_BEGIN; i < SQ_END; i = static_cast<Square>(i + 1)) { for (Square i = SQ_BEGIN; i < SQ_END; i = static_cast<Square>(i + 1)) {
if (locations[i] & (uint8_t)player) { if (locations[i] & ((uint8_t)(c << PLAYER_SHIFT))) {
if (!inHowManyMills(i, PLAYER_NOBODY)) { if (!inHowManyMills(i, NOBODY)) {
return false; return false;
} }
} }
@ -312,14 +312,14 @@ bool Board::isAllInMills(player_t player)
} }
// Stat include ban // Stat include ban
int Board::getSurroundedEmptyLocationCount(int sideId, int nPiecesOnBoard[], int Board::getSurroundedEmptyLocationCount(Color sideToMove, int nPiecesOnBoard[],
Square square, bool includeFobidden) Square square, bool includeFobidden)
{ {
//assert(rule.hasBannedLocations == includeFobidden); //assert(rule.hasBannedLocations == includeFobidden);
int count = 0; int count = 0;
if (nPiecesOnBoard[sideId] > rule.nPiecesAtLeast || if (nPiecesOnBoard[sideToMove] > rule.nPiecesAtLeast ||
!rule.allowFlyWhenRemainThreePieces) { !rule.allowFlyWhenRemainThreePieces) {
Square moveSquare; Square moveSquare;
for (MoveDirection d = MD_BEGIN; d < MD_NB; d = (MoveDirection)(d + 1)) { for (MoveDirection d = MD_BEGIN; d < MD_NB; d = (MoveDirection)(d + 1)) {
@ -336,7 +336,7 @@ int Board::getSurroundedEmptyLocationCount(int sideId, int nPiecesOnBoard[],
return count; return count;
} }
void Board::getSurroundedPieceCount(Square square, int sideId, int &nPlayerPiece, int &nOpponentPiece, int &nBanned, int &nEmpty) void Board::getSurroundedPieceCount(Square square, Color sideToMove, int &nPlayerPiece, int &nOpponentPiece, int &nBanned, int &nEmpty)
{ {
Square moveSquare; Square moveSquare;
@ -357,7 +357,7 @@ void Board::getSurroundedPieceCount(Square square, int sideId, int &nPlayerPiece
nBanned++; nBanned++;
break; break;
default: default:
if (sideId == pieceType >> PLAYER_SHIFT) { if (sideToMove == pieceType >> PLAYER_SHIFT) {
nPlayerPiece++; nPlayerPiece++;
} else { } else {
nOpponentPiece++; nOpponentPiece++;
@ -367,14 +367,14 @@ void Board::getSurroundedPieceCount(Square square, int sideId, int &nPlayerPiece
} }
} }
bool Board::isAllSurrounded(int sideId, int nPiecesOnBoard[], player_t player) bool Board::isAllSurrounded(Color sideToMove, int nPiecesOnBoard[])
{ {
// Full // Full
if (nPiecesOnBoard[BLACK] + nPiecesOnBoard[WHITE] >= N_RANKS * N_FILES) if (nPiecesOnBoard[BLACK] + nPiecesOnBoard[WHITE] >= N_RANKS * N_FILES)
return true; return true;
// Can fly // Can fly
if (nPiecesOnBoard[sideId] <= rule.nPiecesAtLeast && if (nPiecesOnBoard[sideToMove] <= rule.nPiecesAtLeast &&
rule.allowFlyWhenRemainThreePieces) { rule.allowFlyWhenRemainThreePieces) {
return false; return false;
} }
@ -382,7 +382,7 @@ bool Board::isAllSurrounded(int sideId, int nPiecesOnBoard[], player_t player)
Square moveSquare; Square moveSquare;
for (Square sq = SQ_BEGIN; sq < SQ_END; sq = (Square)(sq + 1)) { for (Square sq = SQ_BEGIN; sq < SQ_END; sq = (Square)(sq + 1)) {
if (!(player & locationToPlayer(sq))) { if (!(sideToMove & locationToColor(sq))) {
continue; continue;
} }

View File

@ -54,12 +54,12 @@ public:
void turn(vector<string> &cmdlist, char *cmdline, int32_t move_, Square square, bool cmdChange = true); void turn(vector<string> &cmdlist, char *cmdline, int32_t move_, Square square, bool cmdChange = true);
void rotate(int degrees, vector<string> &cmdlist, char *cmdline, int32_t move_, Square square, bool cmdChange = true); void rotate(int degrees, vector<string> &cmdlist, char *cmdline, int32_t move_, Square square, bool cmdChange = true);
int inHowManyMills(Square square, player_t player, Square squareSelected = SQ_0); int inHowManyMills(Square square, Color c, Square squareSelected = SQ_0);
bool isAllInMills(player_t); bool isAllInMills(Color c);
int getSurroundedEmptyLocationCount(int sideId, int nPiecesOnBoard[], Square square, bool includeFobidden); int getSurroundedEmptyLocationCount(Color sideToMove, int nPiecesOnBoard[], Square square, bool includeFobidden);
void getSurroundedPieceCount(Square square, int sideId, int &nPlayerPiece, int &nOpponentPiece, int &nBanned, int &nEmpty); void getSurroundedPieceCount(Square square, Color sideToMove, int &nPlayerPiece, int &nOpponentPiece, int &nBanned, int &nEmpty);
bool isAllSurrounded(int sideId, int nPiecesOnBoard[], player_t ply); bool isAllSurrounded(Color sideToMove, int nPiecesOnBoard[]);
int addMills(Square square); int addMills(Square square);
@ -68,7 +68,7 @@ public:
static void printBoard(); static void printBoard();
player_t locationToPlayer(Square square); Color locationToColor(Square square);
//private: //private:

View File

@ -31,29 +31,14 @@ public:
explicit Player(); explicit Player();
virtual ~Player(); virtual ~Player();
player_t getPlayer() const Color getColor() const
{ {
return who; return color;
} }
int getId() const inline static char colorToCh(Color color)
{ {
return id; return static_cast<char>('0' + color);
}
inline static int toId(player_t player)
{
return player >> PLAYER_SHIFT;
}
inline static player_t idToPlayer(int id)
{
return id == 1? PLAYER_BLACK : PLAYER_WHITE;
}
inline static char idToCh(int id)
{
return static_cast<char>('0' + id);
} }
inline static std::string chToStr(char ch) inline static std::string chToStr(char ch)
@ -65,19 +50,13 @@ public:
} }
} }
inline static player_t getOpponent(player_t player) inline static Color getOpponent(Color c)
{ {
return player == PLAYER_BLACK ? PLAYER_WHITE : PLAYER_BLACK; return c == BLACK ? WHITE : BLACK;
}
inline static int getOpponentById(int id)
{
return id == 1 ? 2 : 1;
} }
private: private:
player_t who; Color color;
int id;
}; };
#endif // PLAYER_H #endif // PLAYER_H

View File

@ -89,7 +89,7 @@ bool Position::setPosition(const struct Rule *newRule)
this->moveStep = 0; this->moveStep = 0;
phase = PHASE_READY; phase = PHASE_READY;
setSideToMove(PLAYER_BLACK); setSideToMove(BLACK);
action = ACTION_PLACE; action = ACTION_PLACE;
memset(board.locations, 0, sizeof(board.locations)); memset(board.locations, 0, sizeof(board.locations));
@ -103,7 +103,7 @@ bool Position::setPosition(const struct Rule *newRule)
countPiecesInHand(); countPiecesInHand();
nPiecesNeedRemove = 0; nPiecesNeedRemove = 0;
board.millListSize = 0; board.millListSize = 0;
winner = PLAYER_NOBODY; winner = NOBODY;
MoveList::create(); MoveList::create();
board.createMillTable(); board.createMillTable();
currentSquare = SQ_0; currentSquare = SQ_0;
@ -137,10 +137,10 @@ bool Position::reset()
moveStep = 0; moveStep = 0;
phase = PHASE_READY; phase = PHASE_READY;
setSideToMove(PLAYER_BLACK); setSideToMove(BLACK);
action = ACTION_PLACE; action = ACTION_PLACE;
winner = PLAYER_NOBODY; winner = NOBODY;
memset(board.locations, 0, sizeof(board.locations)); memset(board.locations, 0, sizeof(board.locations));
key = 0; key = 0;
@ -207,7 +207,7 @@ bool Position::placePiece(Square square, bool updateCmdlist)
int piece = '\x00'; int piece = '\x00';
int n = 0; int n = 0;
int playerId = Player::toId(sideToMove); int playerId = sideToMove;
Bitboard fromTo; Bitboard fromTo;
@ -226,7 +226,7 @@ bool Position::placePiece(Square square, bool updateCmdlist)
Board::squareToPolar(square, file, rank); Board::squareToPolar(square, file, rank);
if (phase == PHASE_PLACING) { if (phase == PHASE_PLACING) {
piece = (0x01 | sideToMove) + rule.nTotalPiecesEachSide - nPiecesInHand[playerId]; piece = (0x01 | (sideToMove << PLAYER_SHIFT)) + rule.nTotalPiecesEachSide - nPiecesInHand[playerId];
nPiecesInHand[playerId]--; nPiecesInHand[playerId]--;
nPiecesOnBoard[playerId]++; nPiecesOnBoard[playerId]++;
@ -264,9 +264,9 @@ bool Position::placePiece(Square square, bool updateCmdlist)
cleanBannedLocations(); cleanBannedLocations();
if (rule.isDefenderMoveFirst) { if (rule.isDefenderMoveFirst) {
setSideToMove(PLAYER_WHITE); setSideToMove(WHITE);
} else { } else {
setSideToMove(PLAYER_BLACK); setSideToMove(BLACK);
} }
if (checkGameOverCondition(updateCmdlist)) { if (checkGameOverCondition(updateCmdlist)) {
@ -290,7 +290,7 @@ bool Position::placePiece(Square square, bool updateCmdlist)
// When hase == GAME_MOVING // When hase == GAME_MOVING
// if illegal // if illegal
if (nPiecesOnBoard[sideId] > rule.nPiecesAtLeast || if (nPiecesOnBoard[sideToMove] > rule.nPiecesAtLeast ||
!rule.allowFlyWhenRemainThreePieces) { !rule.allowFlyWhenRemainThreePieces) {
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (square == MoveList::moveTable[currentSquare][i]) if (square == MoveList::moveTable[currentSquare][i])
@ -380,14 +380,14 @@ bool Position::removePiece(Square square, bool updateCmdlist)
int seconds = -1; int seconds = -1;
int oppId = Player::toId(opponent); int oppId = opponent;
// if piece is not opponent's // if piece is not opponent's
if (!(opponent & board.locations[square])) if (!((opponent << PLAYER_SHIFT) & board.locations[square]))
return false; return false;
if (!rule.allowRemovePieceInMill && if (!rule.allowRemovePieceInMill &&
board.inHowManyMills(square, PLAYER_NOBODY) && board.inHowManyMills(square, NOBODY) &&
!board.isAllInMills(Player::getOpponent(sideToMove))) { !board.isAllInMills(Player::getOpponent(sideToMove))) {
return false; return false;
} }
@ -404,10 +404,10 @@ bool Position::removePiece(Square square, bool updateCmdlist)
board.locations[square] = '\x00'; board.locations[square] = '\x00';
board.byTypeBB[ALL_PIECES] ^= square; board.byTypeBB[ALL_PIECES] ^= square;
board.byTypeBB[opponentId] ^= square; board.byTypeBB[opponent] ^= square;
} }
nPiecesOnBoard[opponentId]--; nPiecesOnBoard[opponent]--;
move = static_cast<Move>(-square); move = static_cast<Move>(-square);
@ -440,9 +440,9 @@ bool Position::removePiece(Square square, bool updateCmdlist)
cleanBannedLocations(); cleanBannedLocations();
if (rule.isDefenderMoveFirst) { if (rule.isDefenderMoveFirst) {
setSideToMove(PLAYER_WHITE); setSideToMove(WHITE);
} else { } else {
setSideToMove(PLAYER_BLACK); setSideToMove(BLACK);
} }
if (checkGameOverCondition(updateCmdlist)) { if (checkGameOverCondition(updateCmdlist)) {
@ -481,7 +481,7 @@ bool Position::selectPiece(Square square)
if (action != ACTION_SELECT && action != ACTION_PLACE) if (action != ACTION_SELECT && action != ACTION_PLACE)
return false; return false;
if (board.locations[square] & sideToMove) { if (board.locations[square] & (sideToMove << PLAYER_SHIFT)) {
currentSquare = square; currentSquare = square;
action = ACTION_PLACE; action = ACTION_PLACE;
@ -496,7 +496,7 @@ bool Position::selectPiece(File file, Rank rank)
return selectPiece(Board::polarToSquare(file, rank)); return selectPiece(Board::polarToSquare(file, rank));
} }
bool Position::giveup(player_t loser) bool Position::giveup(Color loser)
{ {
if (phase & PHASE_NOTPLAYING || if (phase & PHASE_NOTPLAYING ||
phase == PHASE_NONE) { phase == PHASE_NONE) {
@ -505,14 +505,14 @@ bool Position::giveup(player_t loser)
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
int loserId = Player::toId(loser); Color loserColor = loser;
char loserCh = Player::idToCh(loserId); char loserCh = Player::colorToCh(loserColor);
string loserStr = Player::chToStr(loserCh); string loserStr = Player::chToStr(loserCh);
winner = Player::getOpponent(loser); winner = Player::getOpponent(loser);
tips = "玩家" + loserStr + "投子认负"; tips = "玩家" + loserStr + "投子认负";
sprintf(cmdline, "Player%d give up!", loserId); sprintf(cmdline, "Player%d give up!", loserColor);
score[Player::toId(winner)]++; score[winner]++;
cmdlist.emplace_back(string(cmdline)); cmdlist.emplace_back(string(cmdline));
@ -573,7 +573,7 @@ bool Position::command(const char *cmd)
args = sscanf(cmd, "Player%1u give up!", &t); args = sscanf(cmd, "Player%1u give up!", &t);
if (args == 1) { if (args == 1) {
return giveup(Player::idToPlayer(t)); return giveup((Color)t);
} }
#ifdef THREEFOLD_REPETITION #ifdef THREEFOLD_REPETITION
@ -583,7 +583,7 @@ bool Position::command(const char *cmd)
if (!strcmp(cmd, "draw")) { if (!strcmp(cmd, "draw")) {
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
winner = PLAYER_DRAW; winner = DRAW;
score_draw++; score_draw++;
tips = "三次重复局面判和。"; tips = "三次重复局面判和。";
sprintf(cmdline, "Threefold Repetition. Draw!"); sprintf(cmdline, "Threefold Repetition. Draw!");
@ -616,7 +616,7 @@ bool Position::doMove(Move m)
return false; return false;
} }
player_t Position::getWinner() const Color Position::getWinner() const
{ {
return winner; return winner;
} }
@ -625,8 +625,8 @@ int Position::update()
{ {
int ret = -1; int ret = -1;
int timePoint = -1; int timePoint = -1;
time_t *seconds = &elapsedSeconds[sideId]; time_t *seconds = &elapsedSeconds[sideToMove];
time_t opponentSeconds = elapsedSeconds[opponentId]; time_t opponentSeconds = elapsedSeconds[opponent];
if (!(phase & PHASE_PLAYING)) { if (!(phase & PHASE_PLAYING)) {
return -1; return -1;
@ -661,9 +661,9 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist)
for (int i = 1; i <= 2; i++) { for (int i = 1; i <= 2; i++) {
if (elapsedSeconds[i] > rule.maxTimeLedToLose * 60) { if (elapsedSeconds[i] > rule.maxTimeLedToLose * 60) {
elapsedSeconds[i] = rule.maxTimeLedToLose * 60; elapsedSeconds[i] = rule.maxTimeLedToLose * 60;
winner = Player::idToPlayer(Player::getOpponentById(i)); winner = Player::getOpponent(Color(i));
tips = "玩家" + Player::chToStr(Player::idToCh(i)) + "超时判负。"; tips = "玩家" + Player::chToStr(Player::colorToCh(Color(i))) + "超时判负。";
sprintf(cmdline, "Time over. Player%d win!", Player::getOpponentById(i)); sprintf(cmdline, "Time over. Player%d win!", Player::getOpponent(Color(i)));
} }
} }
@ -675,7 +675,7 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist)
if (rule.maxStepsLedToDraw > 0 && if (rule.maxStepsLedToDraw > 0 &&
moveStep > rule.maxStepsLedToDraw) { moveStep > rule.maxStepsLedToDraw) {
winner = PLAYER_DRAW; winner = DRAW;
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
if (updateCmdlist) { if (updateCmdlist) {
sprintf(cmdline, "Steps over. In draw!"); sprintf(cmdline, "Steps over. In draw!");
@ -688,11 +688,11 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist)
for (int i = 1; i <= 2; i++) for (int i = 1; i <= 2; i++)
{ {
if (nPiecesOnBoard[i] + nPiecesInHand[i] < rule.nPiecesAtLeast) { if (nPiecesOnBoard[i] + nPiecesInHand[i] < rule.nPiecesAtLeast) {
int o = Player::getOpponentById(i); winner = Player::getOpponent(Color(i));
winner = Player::idToPlayer(o);
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
if (updateCmdlist) { if (updateCmdlist) {
sprintf(cmdline, "Player%d win!", o); sprintf(cmdline, "Player%d win!", winner);
cmdlist.emplace_back(string(cmdline)); cmdlist.emplace_back(string(cmdline));
} }
@ -704,7 +704,7 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist)
#if 0 #if 0
int diff = nPiecesOnBoard[BLACK] - nPiecesOnBoard[WHITE]; int diff = nPiecesOnBoard[BLACK] - nPiecesOnBoard[WHITE];
if (diff > 4) { if (diff > 4) {
winner = PLAYER_BLACK; winner = BLACK;
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
sprintf(cmdline, "Player1 win!"); sprintf(cmdline, "Player1 win!");
cmdlist.emplace_back(string(cmdline)); cmdlist.emplace_back(string(cmdline));
@ -713,7 +713,7 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist)
} }
if (diff < -4) { if (diff < -4) {
winner = PLAYER_WHITE; winner = WHITE;
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
sprintf(cmdline, "Player2 win!"); sprintf(cmdline, "Player2 win!");
cmdlist.emplace_back(string(cmdline)); cmdlist.emplace_back(string(cmdline));
@ -727,12 +727,12 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist)
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
if (rule.isBlackLosebutNotDrawWhenBoardFull) { if (rule.isBlackLosebutNotDrawWhenBoardFull) {
winner = PLAYER_WHITE; winner = WHITE;
if (updateCmdlist) { if (updateCmdlist) {
sprintf(cmdline, "Player2 win!"); sprintf(cmdline, "Player2 win!");
} }
} else { } else {
winner = PLAYER_DRAW; winner = DRAW;
if (updateCmdlist) { if (updateCmdlist) {
sprintf(cmdline, "Full. In draw!"); sprintf(cmdline, "Full. In draw!");
} }
@ -745,7 +745,7 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist)
return true; return true;
} }
if (phase == PHASE_MOVING && action == ACTION_SELECT && board.isAllSurrounded(sideId, nPiecesOnBoard, sideToMove)) { if (phase == PHASE_MOVING && action == ACTION_SELECT && board.isAllSurrounded(sideToMove, nPiecesOnBoard)) {
// TODO: move to next branch // TODO: move to next branch
phase = PHASE_GAMEOVER; phase = PHASE_GAMEOVER;
@ -753,8 +753,7 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist)
if (updateCmdlist) { if (updateCmdlist) {
tips = "玩家" + Player::chToStr(chSide) + "无子可走被闷"; tips = "玩家" + Player::chToStr(chSide) + "无子可走被闷";
winner = Player::getOpponent(sideToMove); winner = Player::getOpponent(sideToMove);
int winnerId = Player::toId(winner); sprintf(cmdline, "Player%d no way to go. Player%d win!", sideToMove, winner);
sprintf(cmdline, "Player%d no way to go. Player%d win!", sideId, winnerId);
cmdlist.emplace_back(string(cmdline)); // TODO: memleak cmdlist.emplace_back(string(cmdline)); // TODO: memleak
} }
@ -769,7 +768,7 @@ bool Position::checkGameOverCondition(int8_t updateCmdlist)
return false; return false;
} }
int Position::getMobilityDiff(player_t turn, int piecesOnBoard[], bool includeFobidden) int Position::getMobilityDiff(Color turn, int piecesOnBoard[], bool includeFobidden)
{ {
// TODO: Deal with rule is no ban location // TODO: Deal with rule is no ban location
Location *locations = board.locations; Location *locations = board.locations;
@ -814,20 +813,17 @@ void Position::cleanBannedLocations()
} }
} }
void Position::setSideToMove(player_t player) void Position::setSideToMove(Color c)
{ {
sideToMove = player; sideToMove = c;
sideId = Player::toId(sideToMove); chSide = Player::colorToCh(sideToMove);
chSide = Player::idToCh(sideId);
opponent = Player::getOpponent(player); opponent = Player::getOpponent(sideToMove);
chOpponent = Player::colorToCh(opponent);
opponentId = Player::toId(opponent);
chOpponent = Player::idToCh(opponentId);
} }
player_t Position::getSideToMove() Color Position::getSideToMove()
{ {
return sideToMove; return sideToMove;
} }
@ -852,7 +848,6 @@ bool Position::undoNullMove()
void Position::setTips() void Position::setTips()
{ {
string winnerStr, t; string winnerStr, t;
int winnerId;
string turnStr = Player::chToStr(chSide); string turnStr = Player::chToStr(chSide);
switch (phase) { switch (phase) {
@ -863,7 +858,7 @@ void Position::setTips()
case PHASE_PLACING: case PHASE_PLACING:
if (action == ACTION_PLACE) { if (action == ACTION_PLACE) {
tips = "轮到玩家" + turnStr + "落子,剩余" + std::to_string(nPiecesInHand[sideId]) + ""; tips = "轮到玩家" + turnStr + "落子,剩余" + std::to_string(nPiecesInHand[sideToMove]) + "";
} else if (action == ACTION_REMOVE) { } else if (action == ACTION_REMOVE) {
tips = "成三!轮到玩家" + turnStr + "去子,需去" + std::to_string(nPiecesNeedRemove) + ""; tips = "成三!轮到玩家" + turnStr + "去子,需去" + std::to_string(nPiecesNeedRemove) + "";
} }
@ -878,16 +873,15 @@ void Position::setTips()
break; break;
case PHASE_GAMEOVER: case PHASE_GAMEOVER:
if (winner == PLAYER_DRAW) { if (winner == DRAW) {
score_draw++; score_draw++;
tips = "双方平局!比分 " + to_string(score[BLACK]) + ":" + to_string(score[WHITE]) + ", 和棋 " + to_string(score_draw); tips = "双方平局!比分 " + to_string(score[BLACK]) + ":" + to_string(score[WHITE]) + ", 和棋 " + to_string(score_draw);
break; break;
} }
winnerId = Player::toId(winner); winnerStr = Player::chToStr(Player::colorToCh(winner));
winnerStr = Player::chToStr(Player::idToCh(winnerId));
score[winnerId]++; score[winner]++;
t = "玩家" + winnerStr + "获胜!比分 " + to_string(score[BLACK]) + ":" + to_string(score[WHITE]) + ", 和棋 " + to_string(score_draw); t = "玩家" + winnerStr + "获胜!比分 " + to_string(score[BLACK]) + ":" + to_string(score[WHITE]) + ", 和棋 " + to_string(score_draw);
@ -925,7 +919,7 @@ Key Position::updateKey(Square square)
// PieceType is board.locations[square] // PieceType is board.locations[square]
// 0b00 - no piece0b01 = 1 black0b10 = 2 white0b11 = 3 ban // 0b00 - no piece0b01 = 1 black0b10 = 2 white0b11 = 3 ban
int pieceType = Player::toId(board.locationToPlayer(square)); int pieceType = board.locationToColor(square);
// TODO: this is std, but current code can work // TODO: this is std, but current code can work
//Location loc = board.locations[square]; //Location loc = board.locations[square];
//int pieceType = loc == 0x0f? 3 : loc >> PLAYER_SHIFT; //int pieceType = loc == 0x0f? 3 : loc >> PLAYER_SHIFT;
@ -947,7 +941,7 @@ Key Position::updateKeyMisc()
key = key << KEY_MISC_BIT >> KEY_MISC_BIT; key = key << KEY_MISC_BIT >> KEY_MISC_BIT;
Key hi = 0; Key hi = 0;
if (sideToMove == PLAYER_WHITE) { if (sideToMove == WHITE) {
hi |= 1U; hi |= 1U;
} }
@ -970,7 +964,7 @@ Key Position::getNextPrimaryKey(Move m)
MoveType mt = type_of(m); MoveType mt = type_of(m);
if (mt == MOVETYPE_REMOVE) { if (mt == MOVETYPE_REMOVE) {
int pieceType = Player::getOpponentById(Player::toId(sideToMove)); int pieceType = Player::getOpponent(sideToMove);
npKey ^= zobrist[sq][pieceType]; npKey ^= zobrist[sq][pieceType];
if (rule.hasBannedLocations && phase == PHASE_PLACING) { if (rule.hasBannedLocations && phase == PHASE_PLACING) {
@ -980,7 +974,7 @@ Key Position::getNextPrimaryKey(Move m)
return npKey; return npKey;
} }
int pieceType = Player::toId(sideToMove); int pieceType = sideToMove;
npKey ^= zobrist[sq][pieceType]; npKey ^= zobrist[sq][pieceType];
if (mt == MOVETYPE_MOVE) { if (mt == MOVETYPE_MOVE) {

View File

@ -51,12 +51,10 @@ public:
enum Phase phase {PHASE_NONE}; enum Phase phase {PHASE_NONE};
player_t sideToMove {PLAYER_NOBODY}; Color sideToMove {NOCOLOR};
int sideId {0};
char chSide {'0'}; char chSide {'0'};
//string turnStr; //string turnStr;
player_t opponent {PLAYER_NOBODY}; Color opponent { NOCOLOR };
int opponentId {0};
char chOpponent {'0'}; char chOpponent {'0'};
//string opponentStr; //string opponentStr;
@ -138,13 +136,13 @@ public:
return nPiecesNeedRemove; return nPiecesNeedRemove;
} }
int getMobilityDiff(player_t turn, int nPiecesOnBoard[], bool includeFobidden); int getMobilityDiff(Color turn, int nPiecesOnBoard[], bool includeFobidden);
bool reset(); bool reset();
bool start(); bool start();
bool giveup(player_t loser); bool giveup(Color loser);
bool command(const char *cmd); bool command(const char *cmd);
@ -154,9 +152,9 @@ public:
void cleanBannedLocations(); void cleanBannedLocations();
void setSideToMove(player_t player); void setSideToMove(Color c);
player_t getSideToMove(); Color getSideToMove();
void changeSideToMove(); void changeSideToMove();
@ -165,7 +163,7 @@ public:
bool doNullMove(); bool doNullMove();
bool undoNullMove(); bool undoNullMove();
player_t getWinner() const; Color getWinner() const;
bool selectPiece(File file, Rank rank); bool selectPiece(File file, Rank rank);
bool _placePiece(File file, Rank rank); bool _placePiece(File file, Rank rank);
@ -224,7 +222,7 @@ private:
int countPiecesInHand(); int countPiecesInHand();
player_t winner; Color winner;
Step currentStep {}; Step currentStep {};

View File

@ -51,22 +51,16 @@ enum MoveType
enum Color : uint8_t enum Color : uint8_t
{ {
NOCOLOR, NOCOLOR = 0,
BLACK, BLACK = 1,
WHITE, WHITE = 2,
COLOR_NB COLOR_NB = 3,
DRAW = 4,
NOBODY = 8
}; };
#define PLAYER_SHIFT 4 #define PLAYER_SHIFT 4
enum player_t : uint8_t
{
PLAYER_BLACK = 0x1 << PLAYER_SHIFT,
PLAYER_WHITE = 0x2 << PLAYER_SHIFT,
PLAYER_DRAW = 0x4 << PLAYER_SHIFT,
PLAYER_NOBODY = 0x8 << PLAYER_SHIFT
};
enum Phase : uint16_t enum Phase : uint16_t
{ {
PHASE_NONE = 0, PHASE_NONE = 0,

View File

@ -337,18 +337,18 @@ void GameController::setRule(int ruleNo, Step stepLimited /*= -1*/, int timeLimi
gameReset(); gameReset();
} }
void GameController::setEngine(int id, bool arg) void GameController::setEngine(int color, bool arg)
{ {
isAiPlayer[id] = arg; isAiPlayer[color] = arg;
if (arg) { if (arg) {
aiThread[id]->setAi(position); aiThread[color]->setAi(position);
if (aiThread[id]->isRunning()) if (aiThread[color]->isRunning())
aiThread[id]->resume(); aiThread[color]->resume();
else else
aiThread[id]->start(); aiThread[color]->start();
} else { } else {
aiThread[id]->stop(); aiThread[color]->stop();
} }
} }
@ -401,11 +401,11 @@ void GameController::setSound(bool arg)
#endif // TRAINING_MODE #endif // TRAINING_MODE
} }
void GameController::playSound(sound_t soundType, player_t player) void GameController::playSound(sound_t soundType, Color c)
{ {
string soundDir = ":/sound/resources/sound/"; string soundDir = ":/sound/resources/sound/";
string sideStr = player == PLAYER_BLACK ? "B" : "W"; string sideStr = c == BLACK ? "B" : "W";
string oppenentStr = player == PLAYER_WHITE? "B" : "W"; string oppenentStr = c == WHITE? "B" : "W";
string filename; string filename;
switch (soundType) { switch (soundType) {
@ -476,7 +476,7 @@ void GameController::playSound(sound_t soundType, player_t player)
filename = "warning.wav"; filename = "warning.wav";
break; break;
case GAME_SOUND_WIN: case GAME_SOUND_WIN:
if (player == PLAYER_DRAW) { if (c == DRAW) {
filename = "Draw.wav"; filename = "Draw.wav";
} else { } else {
filename = "Win_" + sideStr + ".wav"; filename = "Win_" + sideStr + ".wav";
@ -683,8 +683,8 @@ void GameController::timerEvent(QTimerEvent *event)
emit time2Changed(qt2.toString("hh:mm:ss")); emit time2Changed(qt2.toString("hh:mm:ss"));
// 如果胜负已分 // 如果胜负已分
player_t winner = position->getWinner(); Color winner = position->getWinner();
if (winner != PLAYER_NOBODY) { if (winner != NOBODY) {
// 停止计时 // 停止计时
killTimer(timeID); killTimer(timeID);
@ -731,7 +731,7 @@ void GameController::timerEvent(QTimerEvent *event)
bool GameController::isAIsTurn() bool GameController::isAIsTurn()
{ {
return isAiPlayer[position->sideId]; return isAiPlayer[position->sideToMove];
} }
// 关键槽函数根据QGraphicsScene的信号和状态来执行选子、落子或去子 // 关键槽函数根据QGraphicsScene的信号和状态来执行选子、落子或去子
@ -771,7 +771,7 @@ bool GameController::actionPiece(QPointF pos)
manualListModel.removeRows(currentRow + 1, manualListModel.rowCount() - currentRow - 1); manualListModel.removeRows(currentRow + 1, manualListModel.rowCount() - currentRow - 1);
// 如果再决出胜负后悔棋,则重新启动计时 // 如果再决出胜负后悔棋,则重新启动计时
if (position->getWinner() == PLAYER_NOBODY) { if (position->getWinner() == NOBODY) {
// 重新启动计时 // 重新启动计时
timeID = startTimer(100); timeID = startTimer(100);
@ -863,15 +863,15 @@ bool GameController::actionPiece(QPointF pos)
// 播放胜利或失败音效 // 播放胜利或失败音效
#ifndef DONOT_PLAY_WIN_SOUND #ifndef DONOT_PLAY_WIN_SOUND
player_t winner = position->getWinner(); Color winner = position->getWinner();
if (winner != PLAYER_NOBODY && if (winner != NOBODY &&
(manualListModel.data(manualListModel.index(currentRow - 1))).toString().contains("Time over.")) (manualListModel.data(manualListModel.index(currentRow - 1))).toString().contains("Time over."))
playSound(GAME_SOUND_WIN, winner); playSound(GAME_SOUND_WIN, winner);
#endif #endif
// AI设置 // AI设置
// 如果还未决出胜负 // 如果还未决出胜负
if (position->getWinner() == PLAYER_NOBODY) { if (position->getWinner() == NOBODY) {
resumeAiThreads(position->sideToMove); resumeAiThreads(position->sideToMove);
} }
// 如果已经决出胜负 // 如果已经决出胜负
@ -911,7 +911,7 @@ bool GameController::giveUp()
manualListModel.setData(manualListModel.index(currentRow), i.c_str()); manualListModel.setData(manualListModel.index(currentRow), i.c_str());
} }
if (position->getWinner() != PLAYER_NOBODY) if (position->getWinner() != NOBODY)
playSound(GAME_SOUND_GIVE_UP, position->getSideToMove()); playSound(GAME_SOUND_GIVE_UP, position->getSideToMove());
#endif // TRAINING_MODE #endif // TRAINING_MODE
@ -997,8 +997,8 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
// 播放胜利或失败音效 // 播放胜利或失败音效
#ifndef DONOT_PLAY_WIN_SOUND #ifndef DONOT_PLAY_WIN_SOUND
player_t winner = position->getWinner(); Color winner = position->getWinner();
if (winner != PLAYER_NOBODY && if (winner != NOBODY &&
(manualListModel.data(manualListModel.index(currentRow - 1))).toString().contains("Time over.")) { (manualListModel.data(manualListModel.index(currentRow - 1))).toString().contains("Time over.")) {
playSound(GAME_SOUND_WIN, winner); playSound(GAME_SOUND_WIN, winner);
} }
@ -1007,7 +1007,7 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
// AI设置 // AI设置
// 如果还未决出胜负 // 如果还未决出胜负
if (position->getWinner() == PLAYER_NOBODY) { if (position->getWinner() == NOBODY) {
resumeAiThreads(position->sideToMove); resumeAiThreads(position->sideToMove);
} }
// 如果已经决出胜负 // 如果已经决出胜负
@ -1306,7 +1306,7 @@ void GameController::showTestWindow()
void GameController::humanGiveUp() void GameController::humanGiveUp()
{ {
if (position->getWinner() == PLAYER_NOBODY) { if (position->getWinner() == NOBODY) {
giveUp(); giveUp();
} }
} }

View File

@ -186,7 +186,7 @@ public slots:
void setInvert(bool arg = true); void setInvert(bool arg = true);
// id为1时让电脑执先手, id为2时让的电脑执后手 // id为1时让电脑执先手, id为2时让的电脑执后手
void setEngine(int id, bool arg = true); void setEngine(int color, bool arg = true);
void setEngine1(bool arg); void setEngine1(bool arg);
void setEngine2(bool arg); void setEngine2(bool arg);
@ -197,7 +197,7 @@ public slots:
void setSound(bool arg = true); void setSound(bool arg = true);
// 播放声音 // 播放声音
static void playSound(sound_t soundType, player_t player); static void playSound(sound_t soundType, Color c);
// 是否必败时认输 // 是否必败时认输
void setGiveUpIfMostLose(bool enabled); void setGiveUpIfMostLose(bool enabled);
@ -296,16 +296,10 @@ public slots:
waitThreads(); waitThreads();
} }
void resumeAiThreads(player_t sideToMove) void resumeAiThreads(Color sideToMove)
{ {
if (sideToMove == PLAYER_BLACK) { if (isAiPlayer[sideToMove]) {
if (isAiPlayer[BLACK]) { aiThread[sideToMove]->resume();
aiThread[BLACK]->resume();
}
} else {
if (isAiPlayer[WHITE]) {
aiThread[WHITE]->resume();
}
} }
} }

View File

@ -609,13 +609,13 @@ void MillGameWindow::on_actionNew_N_triggered()
QString whoWin; QString whoWin;
switch (gameController->getPosition()->getWinner()) { switch (gameController->getPosition()->getWinner()) {
case PLAYER_BLACK: case BLACK:
whoWin = "Black-Win"; whoWin = "Black-Win";
break; break;
case PLAYER_WHITE: case WHITE:
whoWin = "White-Win"; whoWin = "White-Win";
break; break;
case PLAYER_DRAW: case DRAW:
whoWin = "Draw"; whoWin = "Draw";
break; break;
default: default:

View File

@ -83,8 +83,8 @@ protected slots:
void rowsInserted(const QModelIndex &parent, int start, int end) { void rowsInserted(const QModelIndex &parent, int start, int end) {
// 调用父类函数为使滚动条更新否则scrollToBottom不能正确执行。 // 调用父类函数为使滚动条更新否则scrollToBottom不能正确执行。
QListView::rowsInserted(parent, start, end); QListView::rowsInserted(parent, start, end);
QModelIndex id = model()->square(end, 0); QModelIndex color = model()->square(end, 0);
setCurrentIndex(id); setCurrentIndex(color);
scrollToBottom(); scrollToBottom();
} }
#endif #endif