移除包裹 Position 类的 StateInfo 类
This commit is contained in:
parent
c2b6a3880c
commit
58acff7ce2
|
@ -60,7 +60,7 @@ Value Eval::evaluate(Position *pos)
|
||||||
pos->nPiecesOnBoard[WHITE] * VALUE_EACH_PIECE_ONBOARD;
|
pos->nPiecesOnBoard[WHITE] * VALUE_EACH_PIECE_ONBOARD;
|
||||||
|
|
||||||
#ifdef EVALUATE_MOBILITY
|
#ifdef EVALUATE_MOBILITY
|
||||||
value += st->position->getMobilityDiff(position->turn, position->nPiecesInHand[BLACK], position->nPiecesInHand[WHITE], false) * 10;
|
value += pos->getMobilityDiff(position->turn, position->nPiecesInHand[BLACK], position->nPiecesInHand[WHITE], false) * 10;
|
||||||
#endif /* EVALUATE_MOBILITY */
|
#endif /* EVALUATE_MOBILITY */
|
||||||
|
|
||||||
switch (pos->action) {
|
switch (pos->action) {
|
||||||
|
|
|
@ -85,8 +85,8 @@ public:
|
||||||
(Move)24, (Move)25, (Move)26, (Move)27, (Move)28, (Move)29, (Move)30, (Move)31,
|
(Move)24, (Move)25, (Move)26, (Move)27, (Move)28, (Move)29, (Move)30, (Move)31,
|
||||||
};
|
};
|
||||||
|
|
||||||
//explicit MoveList(const Position &pos) : last(generate<T>(pos, moveList))
|
//explicit MoveList(const Position &tmppos) : last(generate<T>(tmppos, moveList))
|
||||||
// explicit MoveList(const Position &pos) : last(generate(pos, moveList))
|
// explicit MoveList(const Position &tmppos) : last(generate(tmppos, moveList))
|
||||||
// {
|
// {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
|
@ -41,15 +41,14 @@ vector<Key> moveHistory;
|
||||||
|
|
||||||
AIAlgorithm::AIAlgorithm()
|
AIAlgorithm::AIAlgorithm()
|
||||||
{
|
{
|
||||||
state = new StateInfo();
|
position = new Position();
|
||||||
st = new StateInfo();
|
pos = new Position();
|
||||||
//movePicker = new MovePicker();
|
//movePicker = new MovePicker();
|
||||||
}
|
}
|
||||||
|
|
||||||
AIAlgorithm::~AIAlgorithm()
|
AIAlgorithm::~AIAlgorithm()
|
||||||
{
|
{
|
||||||
delete st;
|
//delete pos;
|
||||||
//delete state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Depth AIAlgorithm::changeDepth(Depth origDepth)
|
Depth AIAlgorithm::changeDepth(Depth origDepth)
|
||||||
|
@ -102,17 +101,17 @@ Depth AIAlgorithm::changeDepth(Depth origDepth)
|
||||||
};
|
};
|
||||||
#endif /* ENDGAME_LEARNING */
|
#endif /* ENDGAME_LEARNING */
|
||||||
|
|
||||||
if (st->position->phase & PHASE_PLACING) {
|
if (pos->phase & PHASE_PLACING) {
|
||||||
if (rule.nTotalPiecesEachSide == 12) {
|
if (rule.nTotalPiecesEachSide == 12) {
|
||||||
d = placingDepthTable_12[rule.nTotalPiecesEachSide * 2 - st->position->getPiecesInHandCount(BLACK) - st->position->getPiecesInHandCount(WHITE)];
|
d = placingDepthTable_12[rule.nTotalPiecesEachSide * 2 - pos->getPiecesInHandCount(BLACK) - pos->getPiecesInHandCount(WHITE)];
|
||||||
} else {
|
} else {
|
||||||
d = placingDepthTable_9[rule.nTotalPiecesEachSide * 2 - st->position->getPiecesInHandCount(BLACK) - st->position->getPiecesInHandCount(WHITE)];
|
d = placingDepthTable_9[rule.nTotalPiecesEachSide * 2 - pos->getPiecesInHandCount(BLACK) - pos->getPiecesInHandCount(WHITE)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st->position->phase & PHASE_MOVING) {
|
if (pos->phase & PHASE_MOVING) {
|
||||||
int pb = st->position->getPiecesOnBoardCount(BLACK);
|
int pb = pos->getPiecesOnBoardCount(BLACK);
|
||||||
int pw = st->position->getPiecesOnBoardCount(WHITE);
|
int pw = pos->getPiecesOnBoardCount(WHITE);
|
||||||
|
|
||||||
int pieces = pb + pw;
|
int pieces = pb + pw;
|
||||||
int diff = pb - pw;
|
int diff = pb - pw;
|
||||||
|
@ -145,7 +144,7 @@ Depth AIAlgorithm::changeDepth(Depth origDepth)
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIAlgorithm::setState(const StateInfo &g)
|
void AIAlgorithm::setPosition(Position *p)
|
||||||
{
|
{
|
||||||
if (strcmp(rule.name, rule.name) != 0) {
|
if (strcmp(rule.name, rule.name) != 0) {
|
||||||
#ifdef TRANSPOSITION_TABLE_ENABLE
|
#ifdef TRANSPOSITION_TABLE_ENABLE
|
||||||
|
@ -161,13 +160,10 @@ void AIAlgorithm::setState(const StateInfo &g)
|
||||||
moveHistory.clear();
|
moveHistory.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
*state = g;
|
//position = p;
|
||||||
*st = g;
|
pos = p;
|
||||||
|
position = pos;
|
||||||
|
|
||||||
//memcpy(this->state, &g, sizeof(StateInfo));
|
|
||||||
//memcpy(this->st, &this->state, sizeof(StateInfo));
|
|
||||||
|
|
||||||
position = st->position;
|
|
||||||
requiredQuit = false;
|
requiredQuit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,8 +189,8 @@ int AIAlgorithm::search(Depth depth)
|
||||||
#ifdef THREEFOLD_REPETITION
|
#ifdef THREEFOLD_REPETITION
|
||||||
static int nRepetition = 0;
|
static int nRepetition = 0;
|
||||||
|
|
||||||
if (state->position->getPhase() == PHASE_MOVING) {
|
if (position->getPhase() == PHASE_MOVING) {
|
||||||
Key key = state->position->getPosKey();
|
Key key = position->getPosKey();
|
||||||
|
|
||||||
if (std::find(moveHistory.begin(), moveHistory.end(), key) != moveHistory.end()) {
|
if (std::find(moveHistory.begin(), moveHistory.end(), key) != moveHistory.end()) {
|
||||||
nRepetition++;
|
nRepetition++;
|
||||||
|
@ -207,7 +203,7 @@ int AIAlgorithm::search(Depth depth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->position->getPhase() == PHASE_PLACING) {
|
if (position->getPhase() == PHASE_PLACING) {
|
||||||
moveHistory.clear();
|
moveHistory.clear();
|
||||||
}
|
}
|
||||||
#endif // THREEFOLD_REPETITION
|
#endif // THREEFOLD_REPETITION
|
||||||
|
@ -319,7 +315,7 @@ Value AIAlgorithm::search(Depth depth, Value alpha, Value beta)
|
||||||
#endif // TT_MOVE_ENABLE
|
#endif // TT_MOVE_ENABLE
|
||||||
|
|
||||||
#if defined (TRANSPOSITION_TABLE_ENABLE) || defined(ENDGAME_LEARNING)
|
#if defined (TRANSPOSITION_TABLE_ENABLE) || defined(ENDGAME_LEARNING)
|
||||||
Key posKey = st->position->getPosKey();
|
Key posKey = pos->getPosKey();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENDGAME_LEARNING
|
#ifdef ENDGAME_LEARNING
|
||||||
|
@ -387,7 +383,7 @@ Value AIAlgorithm::search(Depth depth, Value alpha, Value beta)
|
||||||
#endif /* TRANSPOSITION_TABLE_ENABLE */
|
#endif /* TRANSPOSITION_TABLE_ENABLE */
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (position->phase == PHASE_PLACING && depth == 1 && st->position->nPiecesNeedRemove > 0) {
|
if (position->phase == PHASE_PLACING && depth == 1 && pos->nPiecesNeedRemove > 0) {
|
||||||
depth--;
|
depth--;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -443,8 +439,8 @@ Value AIAlgorithm::search(Depth depth, Value alpha, Value beta)
|
||||||
|
|
||||||
ExtMove extMoves[MAX_MOVES];
|
ExtMove extMoves[MAX_MOVES];
|
||||||
memset(extMoves, 0, sizeof(extMoves));
|
memset(extMoves, 0, sizeof(extMoves));
|
||||||
ExtMove *end = generateMoves(st->position, extMoves);
|
ExtMove *end = generateMoves(pos, extMoves);
|
||||||
MovePicker mp(st->position, extMoves);
|
MovePicker mp(pos, extMoves);
|
||||||
mp.score();
|
mp.score();
|
||||||
|
|
||||||
partial_insertion_sort(extMoves, end, -100);
|
partial_insertion_sort(extMoves, end, -100);
|
||||||
|
@ -461,7 +457,7 @@ Value AIAlgorithm::search(Depth depth, Value alpha, Value beta)
|
||||||
#ifdef TRANSPOSITION_TABLE_ENABLE
|
#ifdef TRANSPOSITION_TABLE_ENABLE
|
||||||
#ifdef PREFETCH_SUPPORT
|
#ifdef PREFETCH_SUPPORT
|
||||||
for (int i = 0; i < nchild; i++) {
|
for (int i = 0; i < nchild; i++) {
|
||||||
TranspositionTable::prefetch(st->position->getNextPrimaryKey(extMoves[i].move));
|
TranspositionTable::prefetch(pos->getNextPrimaryKey(extMoves[i].move));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef PREFETCH_DEBUG
|
#ifdef PREFETCH_DEBUG
|
||||||
|
@ -475,10 +471,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 = st->position->sideToMove;
|
player_t before = pos->sideToMove;
|
||||||
Move move = extMoves[i].move;
|
Move move = extMoves[i].move;
|
||||||
doMove(move);
|
doMove(move);
|
||||||
player_t after = st->position->sideToMove;
|
player_t after = pos->sideToMove;
|
||||||
|
|
||||||
if (gameOptions.getDepthExtension() == true && nchild == 1) {
|
if (gameOptions.getDepthExtension() == true && nchild == 1) {
|
||||||
epsilon = 1;
|
epsilon = 1;
|
||||||
|
@ -559,29 +555,29 @@ Value AIAlgorithm::search(Depth depth, Value alpha, Value beta)
|
||||||
|
|
||||||
void AIAlgorithm::stashPosition()
|
void AIAlgorithm::stashPosition()
|
||||||
{
|
{
|
||||||
positionStack.push(*(st->position));
|
positionStack.push(*(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIAlgorithm::doMove(Move move)
|
void AIAlgorithm::doMove(Move move)
|
||||||
{
|
{
|
||||||
st->position->doMove(move);
|
pos->doMove(move);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIAlgorithm::undoMove()
|
void AIAlgorithm::undoMove()
|
||||||
{
|
{
|
||||||
memcpy(st->position, positionStack.top(), sizeof(Position));
|
memcpy(pos, positionStack.top(), sizeof(Position));
|
||||||
//st->position = positionStack.top();
|
//tmppos = positionStack.top();
|
||||||
positionStack.pop();
|
positionStack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIAlgorithm::doNullMove()
|
void AIAlgorithm::doNullMove()
|
||||||
{
|
{
|
||||||
st->position->doNullMove();
|
pos->doNullMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIAlgorithm::undoNullMove()
|
void AIAlgorithm::undoNullMove()
|
||||||
{
|
{
|
||||||
st->position->undoNullMove();
|
pos->undoNullMove();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ALPHABETA_AI
|
#ifdef ALPHABETA_AI
|
||||||
|
@ -621,7 +617,7 @@ const char* AIAlgorithm::nextMove()
|
||||||
moveIndex++;
|
moveIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//player_t side = state->position->sideToMove;
|
//player_t side = position->sideToMove;
|
||||||
|
|
||||||
#ifdef ENDGAME_LEARNING
|
#ifdef ENDGAME_LEARNING
|
||||||
// Check if very weak
|
// Check if very weak
|
||||||
|
@ -630,7 +626,7 @@ const char* AIAlgorithm::nextMove()
|
||||||
Endgame endgame;
|
Endgame endgame;
|
||||||
endgame.type = state->position->sideToMove == PLAYER_BLACK ?
|
endgame.type = state->position->sideToMove == PLAYER_BLACK ?
|
||||||
ENDGAME_PLAYER_WHITE_WIN : ENDGAME_PLAYER_BLACK_WIN;
|
ENDGAME_PLAYER_WHITE_WIN : ENDGAME_PLAYER_BLACK_WIN;
|
||||||
key_t endgameHash = state->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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -638,7 +634,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!", state->position->sideId);
|
sprintf(cmdline, "Player%d give up!", position->sideId);
|
||||||
return cmdline;
|
return cmdline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class AIAlgorithm;
|
class AIAlgorithm;
|
||||||
class StateInfo;
|
|
||||||
class Node;
|
class Node;
|
||||||
class Position;
|
class Position;
|
||||||
class MovePicker;
|
class MovePicker;
|
||||||
|
@ -65,7 +64,7 @@ public:
|
||||||
AIAlgorithm();
|
AIAlgorithm();
|
||||||
~AIAlgorithm();
|
~AIAlgorithm();
|
||||||
|
|
||||||
void setState(const StateInfo &state);
|
void setPosition(Position *p);
|
||||||
|
|
||||||
void quit()
|
void quit()
|
||||||
{
|
{
|
||||||
|
@ -140,8 +139,6 @@ protected:
|
||||||
Depth changeDepth(Depth origDepth);
|
Depth changeDepth(Depth origDepth);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StateInfo *state { nullptr };
|
|
||||||
|
|
||||||
MovePicker *movePicker { nullptr };
|
MovePicker *movePicker { nullptr };
|
||||||
|
|
||||||
Value bestvalue { VALUE_ZERO };
|
Value bestvalue { VALUE_ZERO };
|
||||||
|
@ -150,8 +147,7 @@ public:
|
||||||
Depth originDepth{ 0 };
|
Depth originDepth{ 0 };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StateInfo *st { nullptr };
|
Position *pos { nullptr };
|
||||||
|
|
||||||
Position *position { nullptr };
|
Position *position { nullptr };
|
||||||
|
|
||||||
Stack<Position> positionStack;
|
Stack<Position> positionStack;
|
||||||
|
|
|
@ -33,7 +33,7 @@ using namespace std;
|
||||||
|
|
||||||
AiThread::AiThread(int id, QObject *parent) :
|
AiThread::AiThread(int id, QObject *parent) :
|
||||||
QThread(parent),
|
QThread(parent),
|
||||||
state(nullptr),
|
position(nullptr),
|
||||||
depth(2),
|
depth(2),
|
||||||
timeLimit(3600)
|
timeLimit(3600)
|
||||||
{
|
{
|
||||||
|
@ -62,12 +62,12 @@ AiThread::~AiThread()
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiThread::setAi(const StateInfo &g)
|
void AiThread::setAi(Position *p)
|
||||||
{
|
{
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
|
|
||||||
this->state = &g;
|
this->position = p;
|
||||||
ai.setState(*(this->state));
|
ai.setPosition(p);
|
||||||
|
|
||||||
#ifdef TRANSPOSITION_TABLE_ENABLE
|
#ifdef TRANSPOSITION_TABLE_ENABLE
|
||||||
#ifdef CLEAR_TRANSPOSITION_TABLE
|
#ifdef CLEAR_TRANSPOSITION_TABLE
|
||||||
|
@ -78,11 +78,11 @@ void AiThread::setAi(const StateInfo &g)
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AiThread::setAi(const StateInfo &g, Depth d, int tl)
|
void AiThread::setAi(Position *p, Depth d, int tl)
|
||||||
{
|
{
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
this->state = &g;
|
this->position = p;
|
||||||
ai.setState(g);
|
ai.setPosition(p);
|
||||||
depth = d;
|
depth = d;
|
||||||
timeLimit = tl;
|
timeLimit = tl;
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
|
@ -217,7 +217,7 @@ void AiThread::run()
|
||||||
while (!isInterruptionRequested()) {
|
while (!isInterruptionRequested()) {
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
|
|
||||||
sideId = Player::toId(state->position->sideToMove);
|
sideId = Player::toId(position->sideToMove);
|
||||||
|
|
||||||
if (sideId != playerId) {
|
if (sideId != playerId) {
|
||||||
pauseCondition.wait(&mutex);
|
pauseCondition.wait(&mutex);
|
||||||
|
@ -225,7 +225,7 @@ void AiThread::run()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ai.setState(*state);
|
ai.setPosition(position);
|
||||||
emit searchStarted();
|
emit searchStarted();
|
||||||
mutex.unlock();
|
mutex.unlock();
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,8 @@ protected:
|
||||||
void run() override;
|
void run() override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void setAi(const StateInfo &state);
|
void setAi(Position *p);
|
||||||
void setAi(const StateInfo &state, Depth depth, int time);
|
void setAi(Position *p, Depth depth, int time);
|
||||||
|
|
||||||
Server *getServer()
|
Server *getServer()
|
||||||
{
|
{
|
||||||
|
@ -92,7 +92,7 @@ private:
|
||||||
QWaitCondition pauseCondition;
|
QWaitCondition pauseCondition;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const StateInfo *state;
|
Position *position;
|
||||||
|
|
||||||
public: // TODO: Change to private
|
public: // TODO: Change to private
|
||||||
AIAlgorithm ai;
|
AIAlgorithm ai;
|
||||||
|
|
|
@ -29,16 +29,6 @@
|
||||||
|
|
||||||
string tips;
|
string tips;
|
||||||
|
|
||||||
StateInfo::StateInfo()
|
|
||||||
{
|
|
||||||
if (position != nullptr) {
|
|
||||||
delete position;
|
|
||||||
}
|
|
||||||
|
|
||||||
position = new Position();
|
|
||||||
//memset(position, 0, sizeof(Position));
|
|
||||||
}
|
|
||||||
|
|
||||||
Position::Position()
|
Position::Position()
|
||||||
{
|
{
|
||||||
constructKey();
|
constructKey();
|
||||||
|
@ -51,51 +41,11 @@ Position::Position()
|
||||||
cmdlist.reserve(256);
|
cmdlist.reserve(256);
|
||||||
}
|
}
|
||||||
|
|
||||||
StateInfo::~StateInfo()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Position::~Position()
|
Position::~Position()
|
||||||
{
|
{
|
||||||
cmdlist.clear();
|
cmdlist.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
StateInfo::StateInfo(const StateInfo &state)
|
|
||||||
{
|
|
||||||
if (position != nullptr) {
|
|
||||||
delete position;
|
|
||||||
position = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
position = new Position();
|
|
||||||
|
|
||||||
*this = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
StateInfo::StateInfo(StateInfo &state)
|
|
||||||
{
|
|
||||||
if (position != nullptr) {
|
|
||||||
delete position;
|
|
||||||
position = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
position = new Position();
|
|
||||||
|
|
||||||
*this = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
StateInfo &StateInfo::operator= (const StateInfo &state)
|
|
||||||
{
|
|
||||||
memcpy(position, state.position, sizeof(Position));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
StateInfo &StateInfo::operator= (StateInfo &state)
|
|
||||||
{
|
|
||||||
memcpy(position, state.position, sizeof(Position));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Position::countPiecesOnBoard()
|
int Position::countPiecesOnBoard()
|
||||||
{
|
{
|
||||||
nPiecesOnBoard[BLACK] = nPiecesOnBoard[WHITE] = 0;
|
nPiecesOnBoard[BLACK] = nPiecesOnBoard[WHITE] = 0;
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class AIAlgorithm;
|
class AIAlgorithm;
|
||||||
class StateInfo;
|
|
||||||
class Node;
|
class Node;
|
||||||
|
|
||||||
extern string tips;
|
extern string tips;
|
||||||
|
@ -238,22 +237,4 @@ private:
|
||||||
time_t elapsedSeconds[COLOR_NB];
|
time_t elapsedSeconds[COLOR_NB];
|
||||||
};
|
};
|
||||||
|
|
||||||
class StateInfo
|
|
||||||
{
|
|
||||||
friend class AIAlgorithm;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
StateInfo();
|
|
||||||
virtual ~StateInfo();
|
|
||||||
|
|
||||||
StateInfo(StateInfo &);
|
|
||||||
StateInfo(const StateInfo &);
|
|
||||||
|
|
||||||
StateInfo &operator=(const StateInfo &);
|
|
||||||
StateInfo &operator=(StateInfo &);
|
|
||||||
|
|
||||||
Position *position { nullptr };
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* POSITION_H */
|
#endif /* POSITION_H */
|
||||||
|
|
|
@ -72,6 +72,10 @@ GameController::GameController(
|
||||||
scene.setBackgroundBrush(QColor(239, 239, 239));
|
scene.setBackgroundBrush(QColor(239, 239, 239));
|
||||||
#endif /* MOBILE_APP_UI */
|
#endif /* MOBILE_APP_UI */
|
||||||
|
|
||||||
|
if (position == nullptr) {
|
||||||
|
position = new Position();
|
||||||
|
}
|
||||||
|
|
||||||
resetAiPlayers();
|
resetAiPlayers();
|
||||||
createAiThreads();
|
createAiThreads();
|
||||||
|
|
||||||
|
@ -148,8 +152,8 @@ extern deque<int> openingBookDequeBak;
|
||||||
|
|
||||||
void GameController::gameStart()
|
void GameController::gameStart()
|
||||||
{
|
{
|
||||||
state.position->start();
|
position->start();
|
||||||
st = state;
|
tmppos = position;;
|
||||||
|
|
||||||
// 每隔100毫秒调用一次定时器处理函数
|
// 每隔100毫秒调用一次定时器处理函数
|
||||||
if (timeID == 0) {
|
if (timeID == 0) {
|
||||||
|
@ -177,8 +181,8 @@ void GameController::gameReset()
|
||||||
timeID = 0;
|
timeID = 0;
|
||||||
|
|
||||||
// 重置游戏
|
// 重置游戏
|
||||||
state.position->reset();
|
position->reset();
|
||||||
st = state;
|
tmppos = position;
|
||||||
|
|
||||||
// 停掉线程
|
// 停掉线程
|
||||||
if (!gameOptions.getAutoRestart()) {
|
if (!gameOptions.getAutoRestart()) {
|
||||||
|
@ -247,7 +251,7 @@ void GameController::gameReset()
|
||||||
// 更新棋谱
|
// 更新棋谱
|
||||||
manualListModel.removeRows(0, manualListModel.rowCount());
|
manualListModel.removeRows(0, manualListModel.rowCount());
|
||||||
manualListModel.insertRow(0);
|
manualListModel.insertRow(0);
|
||||||
manualListModel.setData(manualListModel.index(0), state.position->getCmdLine());
|
manualListModel.setData(manualListModel.index(0), position->getCmdLine());
|
||||||
currentRow = 0;
|
currentRow = 0;
|
||||||
|
|
||||||
// 发出信号通知主窗口更新LCD显示
|
// 发出信号通知主窗口更新LCD显示
|
||||||
|
@ -256,22 +260,22 @@ void GameController::gameReset()
|
||||||
emit time2Changed(qtime.toString("hh:mm:ss"));
|
emit time2Changed(qtime.toString("hh:mm:ss"));
|
||||||
|
|
||||||
// 发信号更新状态栏
|
// 发信号更新状态栏
|
||||||
message = QString::fromStdString(state.position->getTips());
|
message = QString::fromStdString(position->getTips());
|
||||||
emit statusBarChanged(message);
|
emit statusBarChanged(message);
|
||||||
|
|
||||||
// 更新比分 LCD 显示
|
// 更新比分 LCD 显示
|
||||||
emit nGamesPlayedChanged(QString::number(state.position->nPlayed, 10));
|
emit nGamesPlayedChanged(QString::number(position->nPlayed, 10));
|
||||||
emit score1Changed(QString::number(state.position->score[BLACK], 10));
|
emit score1Changed(QString::number(position->score[BLACK], 10));
|
||||||
emit score2Changed(QString::number(state.position->score[WHITE], 10));
|
emit score2Changed(QString::number(position->score[WHITE], 10));
|
||||||
emit scoreDrawChanged(QString::number(state.position->score_draw, 10));
|
emit scoreDrawChanged(QString::number(position->score_draw, 10));
|
||||||
|
|
||||||
// 更新胜率 LCD 显示
|
// 更新胜率 LCD 显示
|
||||||
state.position->nPlayed = state.position->score[BLACK] + state.position->score[WHITE] + state.position->score_draw;
|
position->nPlayed = position->score[BLACK] + position->score[WHITE] + position->score_draw;
|
||||||
int winningRate_1 = 0, winningRate_2 = 0, winningRate_draw = 0;
|
int winningRate_1 = 0, winningRate_2 = 0, winningRate_draw = 0;
|
||||||
if (state.position->nPlayed != 0) {
|
if (position->nPlayed != 0) {
|
||||||
winningRate_1 = state.position->score[BLACK] * 10000 / state.position->nPlayed;
|
winningRate_1 = position->score[BLACK] * 10000 / position->nPlayed;
|
||||||
winningRate_2 = state.position->score[WHITE] * 10000 / state.position->nPlayed;
|
winningRate_2 = position->score[WHITE] * 10000 / position->nPlayed;
|
||||||
winningRate_draw = state.position->score_draw * 10000 / state.position->nPlayed;
|
winningRate_draw = position->score_draw * 10000 / position->nPlayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit winningRate1Changed(QString::number(winningRate_1, 10));
|
emit winningRate1Changed(QString::number(winningRate_1, 10));
|
||||||
|
@ -326,8 +330,8 @@ void GameController::setRule(int ruleNo, Step stepLimited /*= -1*/, int timeLimi
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置模型规则,重置游戏
|
// 设置模型规则,重置游戏
|
||||||
state.position->setPosition(&RULES[ruleNo]);
|
position->setPosition(&RULES[ruleNo]);
|
||||||
st = state;
|
tmppos = position;
|
||||||
|
|
||||||
// 重置游戏
|
// 重置游戏
|
||||||
gameReset();
|
gameReset();
|
||||||
|
@ -338,7 +342,7 @@ void GameController::setEngine(int id, bool arg)
|
||||||
isAiPlayer[id] = arg;
|
isAiPlayer[id] = arg;
|
||||||
|
|
||||||
if (arg) {
|
if (arg) {
|
||||||
aiThread[id]->setAi(state);
|
aiThread[id]->setAi(position);
|
||||||
if (aiThread[id]->isRunning())
|
if (aiThread[id]->isRunning())
|
||||||
aiThread[id]->resume();
|
aiThread[id]->resume();
|
||||||
else
|
else
|
||||||
|
@ -362,8 +366,8 @@ void GameController::setAiDepthTime(Depth depth1, int time1, Depth depth2, int t
|
||||||
{
|
{
|
||||||
stopAndWaitAiThreads();
|
stopAndWaitAiThreads();
|
||||||
|
|
||||||
aiThread[BLACK]->setAi(state, depth1, time1);
|
aiThread[BLACK]->setAi(position, depth1, time1);
|
||||||
aiThread[WHITE]->setAi(state, depth2, time2);
|
aiThread[WHITE]->setAi(position, depth2, time2);
|
||||||
|
|
||||||
startAiThreads();
|
startAiThreads();
|
||||||
}
|
}
|
||||||
|
@ -555,13 +559,13 @@ void GameController::flip()
|
||||||
#ifndef TRAINING_MODE
|
#ifndef TRAINING_MODE
|
||||||
stopAndWaitAiThreads();
|
stopAndWaitAiThreads();
|
||||||
|
|
||||||
state.position->board.mirror(state.position->cmdlist, state.position->cmdline, state.position->move, state.position->currentSquare);
|
position->board.mirror(position->cmdlist, position->cmdline, position->move, position->currentSquare);
|
||||||
state.position->board.rotate(180, state.position->cmdlist, state.position->cmdline, state.position->move, state.position->currentSquare);
|
position->board.rotate(180, position->cmdlist, position->cmdline, position->move, position->currentSquare);
|
||||||
st = state;
|
tmppos = position;;
|
||||||
|
|
||||||
// 更新棋谱
|
// 更新棋谱
|
||||||
int row = 0;
|
int row = 0;
|
||||||
for (const auto &str : *(state.position->getCmdList())) {
|
for (const auto &str : *(position->getCmdList())) {
|
||||||
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +575,7 @@ void GameController::flip()
|
||||||
else
|
else
|
||||||
phaseChange(currentRow, true);
|
phaseChange(currentRow, true);
|
||||||
|
|
||||||
threadsSetAi(state);
|
threadsSetAi(position);
|
||||||
startAiThreads();
|
startAiThreads();
|
||||||
#endif // TRAINING_MODE
|
#endif // TRAINING_MODE
|
||||||
}
|
}
|
||||||
|
@ -582,13 +586,13 @@ void GameController::mirror()
|
||||||
#ifndef TRAINING_MODE
|
#ifndef TRAINING_MODE
|
||||||
stopAndWaitAiThreads();
|
stopAndWaitAiThreads();
|
||||||
|
|
||||||
state.position->board.mirror(state.position->cmdlist, state.position->cmdline, state.position->move, state.position->currentSquare);
|
position->board.mirror(position->cmdlist, position->cmdline, position->move, position->currentSquare);
|
||||||
st = state;
|
tmppos = position;
|
||||||
|
|
||||||
// 更新棋谱
|
// 更新棋谱
|
||||||
int row = 0;
|
int row = 0;
|
||||||
|
|
||||||
for (const auto &str : *(state.position->getCmdList())) {
|
for (const auto &str : *(position->getCmdList())) {
|
||||||
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +604,7 @@ void GameController::mirror()
|
||||||
else
|
else
|
||||||
phaseChange(currentRow, true);
|
phaseChange(currentRow, true);
|
||||||
|
|
||||||
threadsSetAi(state);
|
threadsSetAi(position);
|
||||||
startAiThreads();
|
startAiThreads();
|
||||||
#endif // TRAINING_MODE
|
#endif // TRAINING_MODE
|
||||||
}
|
}
|
||||||
|
@ -611,13 +615,13 @@ void GameController::turnRight()
|
||||||
#ifndef TRAINING_MODE
|
#ifndef TRAINING_MODE
|
||||||
stopAndWaitAiThreads();
|
stopAndWaitAiThreads();
|
||||||
|
|
||||||
state.position->board.rotate(-90, state.position->cmdlist, state.position->cmdline, state.position->move, state.position->currentSquare);
|
position->board.rotate(-90, position->cmdlist, position->cmdline, position->move, position->currentSquare);
|
||||||
st = state;
|
tmppos = position;
|
||||||
|
|
||||||
// 更新棋谱
|
// 更新棋谱
|
||||||
int row = 0;
|
int row = 0;
|
||||||
|
|
||||||
for (const auto &str : *(state.position->getCmdList())) {
|
for (const auto &str : *(position->getCmdList())) {
|
||||||
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,7 +631,7 @@ void GameController::turnRight()
|
||||||
else
|
else
|
||||||
phaseChange(currentRow, true);
|
phaseChange(currentRow, true);
|
||||||
|
|
||||||
threadsSetAi(state);
|
threadsSetAi(position);
|
||||||
startAiThreads();
|
startAiThreads();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -638,19 +642,19 @@ void GameController::turnLeft()
|
||||||
#ifndef TRAINING_MODE
|
#ifndef TRAINING_MODE
|
||||||
stopAndWaitAiThreads();
|
stopAndWaitAiThreads();
|
||||||
|
|
||||||
state.position->board.rotate(90, state.position->cmdlist, state.position->cmdline, state.position->move, state.position->currentSquare);
|
position->board.rotate(90, position->cmdlist, position->cmdline, position->move, position->currentSquare);
|
||||||
st = state;
|
tmppos = position;
|
||||||
|
|
||||||
// 更新棋谱
|
// 更新棋谱
|
||||||
int row = 0;
|
int row = 0;
|
||||||
for (const auto &str : *(state.position->getCmdList())) {
|
for (const auto &str : *(position->getCmdList())) {
|
||||||
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
manualListModel.setData(manualListModel.index(row++), str.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 刷新显示
|
// 刷新显示
|
||||||
updateScence();
|
updateScence();
|
||||||
|
|
||||||
threadsSetAi(state);
|
threadsSetAi(position);
|
||||||
startAiThreads();
|
startAiThreads();
|
||||||
#endif // TRAINING_MODE
|
#endif // TRAINING_MODE
|
||||||
}
|
}
|
||||||
|
@ -661,9 +665,9 @@ void GameController::timerEvent(QTimerEvent *event)
|
||||||
static QTime qt1, qt2;
|
static QTime qt1, qt2;
|
||||||
|
|
||||||
// 玩家的已用时间
|
// 玩家的已用时间
|
||||||
state.position->update();
|
position->update();
|
||||||
remainingTime[BLACK] = state.position->getElapsedTime(BLACK);
|
remainingTime[BLACK] = position->getElapsedTime(BLACK);
|
||||||
remainingTime[WHITE] = state.position->getElapsedTime(WHITE);
|
remainingTime[WHITE] = position->getElapsedTime(WHITE);
|
||||||
|
|
||||||
// 如果规则要求计时,则time1和time2表示倒计时
|
// 如果规则要求计时,则time1和time2表示倒计时
|
||||||
if (timeLimit > 0) {
|
if (timeLimit > 0) {
|
||||||
|
@ -679,7 +683,7 @@ void GameController::timerEvent(QTimerEvent *event)
|
||||||
emit time2Changed(qt2.toString("hh:mm:ss"));
|
emit time2Changed(qt2.toString("hh:mm:ss"));
|
||||||
|
|
||||||
// 如果胜负已分
|
// 如果胜负已分
|
||||||
player_t winner = state.position->getWinner();
|
player_t winner = position->getWinner();
|
||||||
if (winner != PLAYER_NOBODY) {
|
if (winner != PLAYER_NOBODY) {
|
||||||
// 停止计时
|
// 停止计时
|
||||||
killTimer(timeID);
|
killTimer(timeID);
|
||||||
|
@ -689,7 +693,7 @@ void GameController::timerEvent(QTimerEvent *event)
|
||||||
|
|
||||||
#ifndef TRAINING_MODE
|
#ifndef TRAINING_MODE
|
||||||
// 发信号更新状态栏
|
// 发信号更新状态栏
|
||||||
message = QString::fromStdString(state.position->getTips());
|
message = QString::fromStdString(position->getTips());
|
||||||
emit statusBarChanged(message);
|
emit statusBarChanged(message);
|
||||||
|
|
||||||
// 弹框
|
// 弹框
|
||||||
|
@ -727,7 +731,7 @@ void GameController::timerEvent(QTimerEvent *event)
|
||||||
|
|
||||||
bool GameController::isAIsTurn()
|
bool GameController::isAIsTurn()
|
||||||
{
|
{
|
||||||
return isAiPlayer[state.position->sideId];
|
return isAiPlayer[position->sideId];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关键槽函数,根据QGraphicsScene的信号和状态来执行选子、落子或去子
|
// 关键槽函数,根据QGraphicsScene的信号和状态来执行选子、落子或去子
|
||||||
|
@ -763,17 +767,17 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
|
|
||||||
if (QMessageBox::Ok == msgBox.exec()) {
|
if (QMessageBox::Ok == msgBox.exec()) {
|
||||||
#endif /* !MOBILE_APP_UI */
|
#endif /* !MOBILE_APP_UI */
|
||||||
state = st;
|
position = tmppos;
|
||||||
manualListModel.removeRows(currentRow + 1, manualListModel.rowCount() - currentRow - 1);
|
manualListModel.removeRows(currentRow + 1, manualListModel.rowCount() - currentRow - 1);
|
||||||
|
|
||||||
// 如果再决出胜负后悔棋,则重新启动计时
|
// 如果再决出胜负后悔棋,则重新启动计时
|
||||||
if (state.position->getWinner() == PLAYER_NOBODY) {
|
if (position->getWinner() == PLAYER_NOBODY) {
|
||||||
|
|
||||||
// 重新启动计时
|
// 重新启动计时
|
||||||
timeID = startTimer(100);
|
timeID = startTimer(100);
|
||||||
|
|
||||||
// 发信号更新状态栏
|
// 发信号更新状态栏
|
||||||
message = QString::fromStdString(state.position->getTips());
|
message = QString::fromStdString(position->getTips());
|
||||||
emit statusBarChanged(message);
|
emit statusBarChanged(message);
|
||||||
#ifndef MOBILE_APP_UI
|
#ifndef MOBILE_APP_UI
|
||||||
}
|
}
|
||||||
|
@ -784,7 +788,7 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果未开局则开局
|
// 如果未开局则开局
|
||||||
if (state.position->getPhase() == PHASE_READY)
|
if (position->getPhase() == PHASE_READY)
|
||||||
gameStart();
|
gameStart();
|
||||||
|
|
||||||
// 判断执行选子、落子或去子
|
// 判断执行选子、落子或去子
|
||||||
|
@ -792,15 +796,15 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
PieceItem *piece = nullptr;
|
PieceItem *piece = nullptr;
|
||||||
QGraphicsItem *item = scene.itemAt(pos, QTransform());
|
QGraphicsItem *item = scene.itemAt(pos, QTransform());
|
||||||
|
|
||||||
switch (state.position->getAction()) {
|
switch (position->getAction()) {
|
||||||
case ACTION_PLACE:
|
case ACTION_PLACE:
|
||||||
if (state.position->_placePiece(file, rank)) {
|
if (position->_placePiece(file, rank)) {
|
||||||
if (state.position->getAction() == ACTION_REMOVE) {
|
if (position->getAction() == ACTION_REMOVE) {
|
||||||
// 播放成三音效
|
// 播放成三音效
|
||||||
playSound(GAME_SOUND_MILL, state.position->getSideToMove());
|
playSound(GAME_SOUND_MILL, position->getSideToMove());
|
||||||
} else {
|
} else {
|
||||||
// 播放移动棋子音效
|
// 播放移动棋子音效
|
||||||
playSound(GAME_SOUND_DROG, state.position->getSideToMove());
|
playSound(GAME_SOUND_DROG, position->getSideToMove());
|
||||||
}
|
}
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
|
@ -813,24 +817,24 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
piece = qgraphicsitem_cast<PieceItem *>(item);
|
piece = qgraphicsitem_cast<PieceItem *>(item);
|
||||||
if (!piece)
|
if (!piece)
|
||||||
break;
|
break;
|
||||||
if (state.position->selectPiece(file, rank)) {
|
if (position->selectPiece(file, rank)) {
|
||||||
// 播放选子音效
|
// 播放选子音效
|
||||||
playSound(GAME_SOUND_SELECT, state.position->getSideToMove());
|
playSound(GAME_SOUND_SELECT, position->getSideToMove());
|
||||||
result = true;
|
result = true;
|
||||||
} else {
|
} else {
|
||||||
// 播放禁止音效
|
// 播放禁止音效
|
||||||
playSound(GAME_SOUND_BANNED, state.position->getSideToMove());
|
playSound(GAME_SOUND_BANNED, position->getSideToMove());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ACTION_REMOVE:
|
case ACTION_REMOVE:
|
||||||
if (state.position->_removePiece(file, rank)) {
|
if (position->_removePiece(file, rank)) {
|
||||||
// 播放音效
|
// 播放音效
|
||||||
playSound(GAME_SOUND_REMOVE, state.position->getSideToMove());
|
playSound(GAME_SOUND_REMOVE, position->getSideToMove());
|
||||||
result = true;
|
result = true;
|
||||||
} else {
|
} else {
|
||||||
// 播放禁止音效
|
// 播放禁止音效
|
||||||
playSound(GAME_SOUND_BANNED, state.position->getSideToMove());
|
playSound(GAME_SOUND_BANNED, position->getSideToMove());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -841,7 +845,7 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
// 发信号更新状态栏
|
// 发信号更新状态栏
|
||||||
message = QString::fromStdString(state.position->getTips());
|
message = QString::fromStdString(position->getTips());
|
||||||
emit statusBarChanged(message);
|
emit statusBarChanged(message);
|
||||||
|
|
||||||
// 将新增的棋谱行插入到ListModel
|
// 将新增的棋谱行插入到ListModel
|
||||||
|
@ -849,7 +853,7 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
// 输出命令行
|
// 输出命令行
|
||||||
for (const auto & i : *(state.position->getCmdList())) {
|
for (const auto & i : *(position->getCmdList())) {
|
||||||
// 跳过已添加的,因标准list容器没有下标
|
// 跳过已添加的,因标准list容器没有下标
|
||||||
if (k++ <= currentRow)
|
if (k++ <= currentRow)
|
||||||
continue;
|
continue;
|
||||||
|
@ -859,7 +863,7 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
|
|
||||||
// 播放胜利或失败音效
|
// 播放胜利或失败音效
|
||||||
#ifndef DONOT_PLAY_WIN_SOUND
|
#ifndef DONOT_PLAY_WIN_SOUND
|
||||||
player_t winner = state.position->getWinner();
|
player_t winner = position->getWinner();
|
||||||
if (winner != PLAYER_NOBODY &&
|
if (winner != PLAYER_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);
|
||||||
|
@ -867,8 +871,8 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
|
|
||||||
// AI设置
|
// AI设置
|
||||||
// 如果还未决出胜负
|
// 如果还未决出胜负
|
||||||
if (state.position->getWinner() == PLAYER_NOBODY) {
|
if (position->getWinner() == PLAYER_NOBODY) {
|
||||||
resumeAiThreads(state.position->sideToMove);
|
resumeAiThreads(position->sideToMove);
|
||||||
}
|
}
|
||||||
// 如果已经决出胜负
|
// 如果已经决出胜负
|
||||||
else {
|
else {
|
||||||
|
@ -886,7 +890,7 @@ bool GameController::actionPiece(QPointF pos)
|
||||||
|
|
||||||
bool GameController::giveUp()
|
bool GameController::giveUp()
|
||||||
{
|
{
|
||||||
bool result = state.position->giveup(state.position->sideToMove);
|
bool result = position->giveup(position->sideToMove);
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -899,7 +903,7 @@ bool GameController::giveUp()
|
||||||
int k = 0;
|
int k = 0;
|
||||||
|
|
||||||
// 输出命令行
|
// 输出命令行
|
||||||
for (const auto & i : *(state.position->getCmdList())) {
|
for (const auto & i : *(position->getCmdList())) {
|
||||||
// 跳过已添加的,因标准list容器没有下标
|
// 跳过已添加的,因标准list容器没有下标
|
||||||
if (k++ <= currentRow)
|
if (k++ <= currentRow)
|
||||||
continue;
|
continue;
|
||||||
|
@ -907,8 +911,8 @@ bool GameController::giveUp()
|
||||||
manualListModel.setData(manualListModel.index(currentRow), i.c_str());
|
manualListModel.setData(manualListModel.index(currentRow), i.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.position->getWinner() != PLAYER_NOBODY)
|
if (position->getWinner() != PLAYER_NOBODY)
|
||||||
playSound(GAME_SOUND_GIVE_UP, state.position->getSideToMove());
|
playSound(GAME_SOUND_GIVE_UP, position->getSideToMove());
|
||||||
|
|
||||||
#endif // TRAINING_MODE
|
#endif // TRAINING_MODE
|
||||||
|
|
||||||
|
@ -933,7 +937,7 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
|
||||||
// 声音
|
// 声音
|
||||||
sound_t soundType = GAME_SOUND_NONE;
|
sound_t soundType = GAME_SOUND_NONE;
|
||||||
|
|
||||||
switch (state.position->getAction()) {
|
switch (position->getAction()) {
|
||||||
case ACTION_SELECT:
|
case ACTION_SELECT:
|
||||||
case ACTION_PLACE:
|
case ACTION_PLACE:
|
||||||
soundType = GAME_SOUND_DROG;
|
soundType = GAME_SOUND_DROG;
|
||||||
|
@ -947,45 +951,45 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// 如果未开局则开局
|
// 如果未开局则开局
|
||||||
if (state.position->getPhase() == PHASE_READY) {
|
if (position->getPhase() == PHASE_READY) {
|
||||||
gameStart();
|
gameStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.position->command(cmd.toStdString().c_str()))
|
if (!position->command(cmd.toStdString().c_str()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
#ifndef TRAINING_MODE
|
#ifndef TRAINING_MODE
|
||||||
if (soundType == GAME_SOUND_DROG && state.position->getAction() == ACTION_REMOVE) {
|
if (soundType == GAME_SOUND_DROG && position->getAction() == ACTION_REMOVE) {
|
||||||
soundType = GAME_SOUND_MILL;
|
soundType = GAME_SOUND_MILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update) {
|
if (update) {
|
||||||
playSound(soundType, state.position->getSideToMove());
|
playSound(soundType, position->getSideToMove());
|
||||||
updateScence(state);
|
updateScence(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 发信号更新状态栏
|
// 发信号更新状态栏
|
||||||
message = QString::fromStdString(state.position->getTips());
|
message = QString::fromStdString(position->getTips());
|
||||||
emit statusBarChanged(message);
|
emit statusBarChanged(message);
|
||||||
|
|
||||||
// 对于新开局
|
// 对于新开局
|
||||||
if (state.position->getCmdList()->size() <= 1) {
|
if (position->getCmdList()->size() <= 1) {
|
||||||
manualListModel.removeRows(0, manualListModel.rowCount());
|
manualListModel.removeRows(0, manualListModel.rowCount());
|
||||||
manualListModel.insertRow(0);
|
manualListModel.insertRow(0);
|
||||||
manualListModel.setData(manualListModel.index(0), state.position->getCmdLine());
|
manualListModel.setData(manualListModel.index(0), position->getCmdLine());
|
||||||
currentRow = 0;
|
currentRow = 0;
|
||||||
}
|
}
|
||||||
// 对于当前局
|
// 对于当前局
|
||||||
else {
|
else {
|
||||||
currentRow = manualListModel.rowCount() - 1;
|
currentRow = manualListModel.rowCount() - 1;
|
||||||
// 跳过已添加行,迭代器不支持+运算符,只能一个个++
|
// 跳过已添加行,迭代器不支持+运算符,只能一个个++
|
||||||
auto i = (state.position->getCmdList()->begin());
|
auto i = (position->getCmdList()->begin());
|
||||||
for (int r = 0; i != (state.position->getCmdList())->end(); i++) {
|
for (int r = 0; i != (position->getCmdList())->end(); i++) {
|
||||||
if (r++ > currentRow)
|
if (r++ > currentRow)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// 将新增的棋谱行插入到ListModel
|
// 将新增的棋谱行插入到ListModel
|
||||||
while (i != state.position->getCmdList()->end()) {
|
while (i != position->getCmdList()->end()) {
|
||||||
manualListModel.insertRow(++currentRow);
|
manualListModel.insertRow(++currentRow);
|
||||||
manualListModel.setData(manualListModel.index(currentRow), (*i++).c_str());
|
manualListModel.setData(manualListModel.index(currentRow), (*i++).c_str());
|
||||||
}
|
}
|
||||||
|
@ -993,7 +997,7 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
|
||||||
|
|
||||||
// 播放胜利或失败音效
|
// 播放胜利或失败音效
|
||||||
#ifndef DONOT_PLAY_WIN_SOUND
|
#ifndef DONOT_PLAY_WIN_SOUND
|
||||||
player_t winner = state.position->getWinner();
|
player_t winner = position->getWinner();
|
||||||
if (winner != PLAYER_NOBODY &&
|
if (winner != PLAYER_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);
|
||||||
|
@ -1003,8 +1007,8 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
|
||||||
|
|
||||||
// AI设置
|
// AI设置
|
||||||
// 如果还未决出胜负
|
// 如果还未决出胜负
|
||||||
if (state.position->getWinner() == PLAYER_NOBODY) {
|
if (position->getWinner() == PLAYER_NOBODY) {
|
||||||
resumeAiThreads(state.position->sideToMove);
|
resumeAiThreads(position->sideToMove);
|
||||||
}
|
}
|
||||||
// 如果已经决出胜负
|
// 如果已经决出胜负
|
||||||
else {
|
else {
|
||||||
|
@ -1076,7 +1080,7 @@ bool GameController::command(const QString &cmd, bool update /* = true */)
|
||||||
|
|
||||||
#ifdef MESSAGEBOX_ENABLE
|
#ifdef MESSAGEBOX_ENABLE
|
||||||
// 弹框
|
// 弹框
|
||||||
message = QString::fromStdString(state.position->getTips());
|
message = QString::fromStdString(position->getTips());
|
||||||
QMessageBox::about(NULL, "游戏结果", message);
|
QMessageBox::about(NULL, "游戏结果", message);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -1112,14 +1116,14 @@ bool GameController::phaseChange(int row, bool forceUpdate)
|
||||||
|
|
||||||
for (int i = 0; i <= row; i++) {
|
for (int i = 0; i <= row; i++) {
|
||||||
loggerDebug("%s\n", mlist.at(i).toStdString().c_str());
|
loggerDebug("%s\n", mlist.at(i).toStdString().c_str());
|
||||||
st.position->command(mlist.at(i).toStdString().c_str());
|
tmppos->command(mlist.at(i).toStdString().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
// 下面这步关键,会让悔棋者承担时间损失
|
// 下面这步关键,会让悔棋者承担时间损失
|
||||||
st.position->setStartTime(static_cast<int>(state.position->getStartTimeb()));
|
tmppos->setStartTime(static_cast<int>(position->getStartTimeb()));
|
||||||
|
|
||||||
// 刷新棋局场景
|
// 刷新棋局场景
|
||||||
updateScence(st);
|
updateScence(tmppos);
|
||||||
#endif // TRAINING_MODE
|
#endif // TRAINING_MODE
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -1128,16 +1132,16 @@ bool GameController::phaseChange(int row, bool forceUpdate)
|
||||||
bool GameController::updateScence()
|
bool GameController::updateScence()
|
||||||
{
|
{
|
||||||
#ifndef TRAINING_MODE
|
#ifndef TRAINING_MODE
|
||||||
return updateScence(state);
|
return updateScence(position);
|
||||||
#else
|
#else
|
||||||
return true;
|
return true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GameController::updateScence(StateInfo &g)
|
bool GameController::updateScence(Position *p)
|
||||||
{
|
{
|
||||||
#ifndef TRAINING_MODE
|
#ifndef TRAINING_MODE
|
||||||
const Location *board = g.position->getBoardLocations();
|
const Location *board = p->getBoardLocations();
|
||||||
QPointF pos;
|
QPointF pos;
|
||||||
|
|
||||||
// game类中的棋子代码
|
// game类中的棋子代码
|
||||||
|
@ -1191,10 +1195,10 @@ bool GameController::updateScence(StateInfo &g)
|
||||||
if (j == (Board::N_RANKS) * (Board::N_FILES + 1)) {
|
if (j == (Board::N_RANKS) * (Board::N_FILES + 1)) {
|
||||||
// 判断是被吃掉的子,还是未安放的子
|
// 判断是被吃掉的子,还是未安放的子
|
||||||
if (key & B_STONE) {
|
if (key & B_STONE) {
|
||||||
pos = (key - 0x11 < nTotalPieces / 2 - g.position->getPiecesInHandCount(BLACK)) ?
|
pos = (key - 0x11 < nTotalPieces / 2 - p->getPiecesInHandCount(BLACK)) ?
|
||||||
scene.pos_p2_g : scene.pos_p1;
|
scene.pos_p2_g : scene.pos_p1;
|
||||||
} else {
|
} else {
|
||||||
pos = (key - 0x21 < nTotalPieces / 2 - g.position->getPiecesInHandCount(WHITE)) ?
|
pos = (key - 0x21 < nTotalPieces / 2 - p->getPiecesInHandCount(WHITE)) ?
|
||||||
scene.pos_p1_g : scene.pos_p2;
|
scene.pos_p1_g : scene.pos_p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1203,7 +1207,7 @@ bool GameController::updateScence(StateInfo &g)
|
||||||
deletedPiece = piece;
|
deletedPiece = piece;
|
||||||
|
|
||||||
#ifdef GAME_PLACING_SHOW_REMOVED_PIECES
|
#ifdef GAME_PLACING_SHOW_REMOVED_PIECES
|
||||||
if (state.position->getPhase() == PHASE_MOVING) {
|
if (position->getPhase() == PHASE_MOVING) {
|
||||||
#endif
|
#endif
|
||||||
QPropertyAnimation *animation = new QPropertyAnimation(piece, "pos");
|
QPropertyAnimation *animation = new QPropertyAnimation(piece, "pos");
|
||||||
animation->setDuration(durationTime);
|
animation->setDuration(durationTime);
|
||||||
|
@ -1221,7 +1225,7 @@ bool GameController::updateScence(StateInfo &g)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加摆棋阶段禁子点
|
// 添加摆棋阶段禁子点
|
||||||
if (rule.hasBannedLocations && g.position->getPhase() == PHASE_PLACING) {
|
if (rule.hasBannedLocations && p->getPhase() == PHASE_PLACING) {
|
||||||
for (int j = SQ_BEGIN; j < SQ_END; j++) {
|
for (int j = SQ_BEGIN; j < SQ_END; j++) {
|
||||||
if (board[j] == BAN_STONE) {
|
if (board[j] == BAN_STONE) {
|
||||||
pos = scene.polar2pos(File(j / Board::N_RANKS), Rank(j % Board::N_RANKS + 1));
|
pos = scene.polar2pos(File(j / Board::N_RANKS), Rank(j % Board::N_RANKS + 1));
|
||||||
|
@ -1240,7 +1244,7 @@ bool GameController::updateScence(StateInfo &g)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 走棋阶段清除禁子点
|
// 走棋阶段清除禁子点
|
||||||
if (rule.hasBannedLocations && g.position->getPhase() != PHASE_PLACING) {
|
if (rule.hasBannedLocations && p->getPhase() != PHASE_PLACING) {
|
||||||
while (nTotalPieces < static_cast<int>(pieceList.size())) {
|
while (nTotalPieces < static_cast<int>(pieceList.size())) {
|
||||||
delete pieceList.at(pieceList.size() - 1);
|
delete pieceList.at(pieceList.size() - 1);
|
||||||
pieceList.pop_back();
|
pieceList.pop_back();
|
||||||
|
@ -1248,9 +1252,9 @@ bool GameController::updateScence(StateInfo &g)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选中当前棋子
|
// 选中当前棋子
|
||||||
int ipos = g.position->getCurrentSquare();
|
int ipos = p->getCurrentSquare();
|
||||||
if (ipos) {
|
if (ipos) {
|
||||||
key = board[g.position->getCurrentSquare()];
|
key = board[p->getCurrentSquare()];
|
||||||
ipos = key & B_STONE ? (key - B_STONE_1) * 2 : (key - W_STONE_1) * 2 + 1;
|
ipos = key & B_STONE ? (key - B_STONE_1) * 2 : (key - W_STONE_1) * 2 + 1;
|
||||||
if (ipos >= 0 && ipos < nTotalPieces) {
|
if (ipos >= 0 && ipos < nTotalPieces) {
|
||||||
currentPiece = pieceList.at(static_cast<size_t>(ipos));
|
currentPiece = pieceList.at(static_cast<size_t>(ipos));
|
||||||
|
@ -1266,17 +1270,17 @@ bool GameController::updateScence(StateInfo &g)
|
||||||
animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
|
animationGroup->start(QAbstractAnimation::DeleteWhenStopped);
|
||||||
|
|
||||||
// 更新比分 LCD 显示
|
// 更新比分 LCD 显示
|
||||||
emit score1Changed(QString::number(g.position->score[BLACK], 10));
|
emit score1Changed(QString::number(p->score[BLACK], 10));
|
||||||
emit score2Changed(QString::number(g.position->score[WHITE], 10));
|
emit score2Changed(QString::number(p->score[WHITE], 10));
|
||||||
emit scoreDrawChanged(QString::number(g.position->score_draw, 10));
|
emit scoreDrawChanged(QString::number(p->score_draw, 10));
|
||||||
|
|
||||||
// 更新胜率 LCD 显示
|
// 更新胜率 LCD 显示
|
||||||
state.position->nPlayed = state.position->score[BLACK] + state.position->score[WHITE] + state.position->score_draw;
|
position->nPlayed = position->score[BLACK] + position->score[WHITE] + position->score_draw;
|
||||||
int winningRate_1 = 0, winningRate_2 = 0, winningRate_draw = 0;
|
int winningRate_1 = 0, winningRate_2 = 0, winningRate_draw = 0;
|
||||||
if (state.position->nPlayed != 0) {
|
if (position->nPlayed != 0) {
|
||||||
winningRate_1 = state.position->score[BLACK] * 10000 / state.position->nPlayed;
|
winningRate_1 = position->score[BLACK] * 10000 / position->nPlayed;
|
||||||
winningRate_2 = state.position->score[WHITE] * 10000 / state.position->nPlayed;
|
winningRate_2 = position->score[WHITE] * 10000 / position->nPlayed;
|
||||||
winningRate_draw = state.position->score_draw * 10000 / state.position->nPlayed;
|
winningRate_draw = position->score_draw * 10000 / position->nPlayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
emit winningRate1Changed(QString::number(winningRate_1, 10));
|
emit winningRate1Changed(QString::number(winningRate_1, 10));
|
||||||
|
@ -1302,7 +1306,7 @@ void GameController::showTestWindow()
|
||||||
|
|
||||||
void GameController::humanGiveUp()
|
void GameController::humanGiveUp()
|
||||||
{
|
{
|
||||||
if (state.position->getWinner() == PLAYER_NOBODY) {
|
if (position->getWinner() == PLAYER_NOBODY) {
|
||||||
giveUp();
|
giveUp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1353,16 +1357,16 @@ void GameController::saveScore()
|
||||||
|
|
||||||
textStream << "" << endl;
|
textStream << "" << endl;
|
||||||
|
|
||||||
state.position->nPlayed = state.position->score[BLACK] + state.position->score[WHITE] + state.position->score_draw;
|
position->nPlayed = position->score[BLACK] + position->score[WHITE] + position->score_draw;
|
||||||
|
|
||||||
if (state.position->nPlayed == 0) {
|
if (position->nPlayed == 0) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
textStream << "Sum\t" + QString::number(state.position->nPlayed) << endl;
|
textStream << "Sum\t" + QString::number(position->nPlayed) << endl;
|
||||||
textStream << "Black\t" + QString::number(state.position->score[BLACK]) + "\t" + QString::number(state.position->score[BLACK] * 10000 / state.position->nPlayed) << endl;
|
textStream << "Black\t" + QString::number(position->score[BLACK]) + "\t" + QString::number(position->score[BLACK] * 10000 / position->nPlayed) << endl;
|
||||||
textStream << "White\t" + QString::number(state.position->score[WHITE]) + "\t" + QString::number(state.position->score[WHITE] * 10000 / state.position->nPlayed) << endl;
|
textStream << "White\t" + QString::number(position->score[WHITE]) + "\t" + QString::number(position->score[WHITE] * 10000 / position->nPlayed) << endl;
|
||||||
textStream << "Draw\t" + QString::number(state.position->score_draw) + "\t" + QString::number(state.position->score_draw * 10000 / state.position->nPlayed) << endl;
|
textStream << "Draw\t" + QString::number(position->score_draw) + "\t" + QString::number(position->score_draw * 10000 / position->nPlayed) << endl;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
file.flush();
|
file.flush();
|
||||||
|
|
|
@ -131,9 +131,9 @@ public:
|
||||||
|
|
||||||
void humanGiveUp();
|
void humanGiveUp();
|
||||||
|
|
||||||
StateInfo getState()
|
Position *getPosition()
|
||||||
{
|
{
|
||||||
return state;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
@ -237,10 +237,10 @@ public slots:
|
||||||
|
|
||||||
bool isAIsTurn();
|
bool isAIsTurn();
|
||||||
|
|
||||||
void threadsSetAi(const StateInfo &g)
|
void threadsSetAi(Position *p)
|
||||||
{
|
{
|
||||||
aiThread[BLACK]->setAi(g);
|
aiThread[BLACK]->setAi(p);
|
||||||
aiThread[WHITE]->setAi(g);
|
aiThread[WHITE]->setAi(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resetAiPlayers()
|
void resetAiPlayers()
|
||||||
|
@ -329,7 +329,7 @@ public slots:
|
||||||
|
|
||||||
// 更新棋局显示,每步后执行才能刷新局面
|
// 更新棋局显示,每步后执行才能刷新局面
|
||||||
bool updateScence();
|
bool updateScence();
|
||||||
bool updateScence(StateInfo &game);
|
bool updateScence(Position *position);
|
||||||
|
|
||||||
// 显示网络配置窗口
|
// 显示网络配置窗口
|
||||||
void showNetworkWindow();
|
void showNetworkWindow();
|
||||||
|
@ -351,10 +351,10 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// 棋对象的数据模型
|
// 棋对象的数据模型
|
||||||
StateInfo state;
|
Position *position {nullptr};
|
||||||
|
|
||||||
// 棋对象的数据模型(临时)
|
// 棋对象的数据模型(临时)
|
||||||
StateInfo st;
|
Position *tmppos;
|
||||||
|
|
||||||
// 测试
|
// 测试
|
||||||
Test *gameTest;
|
Test *gameTest;
|
||||||
|
|
|
@ -608,7 +608,7 @@ void MillGameWindow::on_actionNew_N_triggered()
|
||||||
QString strDate = QDateTime::currentDateTime().toString("yyyy-MM-dd");
|
QString strDate = QDateTime::currentDateTime().toString("yyyy-MM-dd");
|
||||||
QString whoWin;
|
QString whoWin;
|
||||||
|
|
||||||
switch (gameController->getState().position->getWinner()) {
|
switch (gameController->getPosition()->getWinner()) {
|
||||||
case PLAYER_BLACK:
|
case PLAYER_BLACK:
|
||||||
whoWin = "Black-Win";
|
whoWin = "Black-Win";
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue