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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -54,12 +54,12 @@ public:
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);
int inHowManyMills(Square square, player_t player, Square squareSelected = SQ_0);
bool isAllInMills(player_t);
int inHowManyMills(Square square, Color c, Square squareSelected = SQ_0);
bool isAllInMills(Color c);
int getSurroundedEmptyLocationCount(int sideId, int nPiecesOnBoard[], Square square, bool includeFobidden);
void getSurroundedPieceCount(Square square, int sideId, int &nPlayerPiece, int &nOpponentPiece, int &nBanned, int &nEmpty);
bool isAllSurrounded(int sideId, int nPiecesOnBoard[], player_t ply);
int getSurroundedEmptyLocationCount(Color sideToMove, int nPiecesOnBoard[], Square square, bool includeFobidden);
void getSurroundedPieceCount(Square square, Color sideToMove, int &nPlayerPiece, int &nOpponentPiece, int &nBanned, int &nEmpty);
bool isAllSurrounded(Color sideToMove, int nPiecesOnBoard[]);
int addMills(Square square);
@ -68,7 +68,7 @@ public:
static void printBoard();
player_t locationToPlayer(Square square);
Color locationToColor(Square square);
//private:

View File

@ -31,29 +31,14 @@ public:
explicit 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;
}
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);
return static_cast<char>('0' + color);
}
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;
}
inline static int getOpponentById(int id)
{
return id == 1 ? 2 : 1;
return c == BLACK ? WHITE : BLACK;
}
private:
player_t who;
int id;
Color color;
};
#endif // PLAYER_H

View File

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

View File

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

View File

@ -51,22 +51,16 @@ enum MoveType
enum Color : uint8_t
{
NOCOLOR,
BLACK,
WHITE,
COLOR_NB
NOCOLOR = 0,
BLACK = 1,
WHITE = 2,
COLOR_NB = 3,
DRAW = 4,
NOBODY = 8
};
#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
{
PHASE_NONE = 0,

View File

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

View File

@ -186,7 +186,7 @@ public slots:
void setInvert(bool arg = true);
// id为1时让电脑执先手, id为2时让的电脑执后手
void setEngine(int id, bool arg = true);
void setEngine(int color, bool arg = true);
void setEngine1(bool arg);
void setEngine2(bool arg);
@ -197,7 +197,7 @@ public slots:
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);
@ -296,16 +296,10 @@ public slots:
waitThreads();
}
void resumeAiThreads(player_t sideToMove)
void resumeAiThreads(Color sideToMove)
{
if (sideToMove == PLAYER_BLACK) {
if (isAiPlayer[BLACK]) {
aiThread[BLACK]->resume();
}
} else {
if (isAiPlayer[WHITE]) {
aiThread[WHITE]->resume();
}
if (isAiPlayer[sideToMove]) {
aiThread[sideToMove]->resume();
}
}

View File

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

View File

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