refactor: 将 positon 重命名为 location

因为术语中 position 是 "局面" 的意思, location 才是表示棋盘上的位置.
This commit is contained in:
CalciteM 2019-09-10 00:50:10 +08:00
parent d2c18f2fed
commit 30b37bc4fa
9 changed files with 237 additions and 235 deletions

View File

@ -28,7 +28,7 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, MillGame &gameTemp,
move_t bestMove)
{
const int MOVE_PRIORITY_TABLE_SIZE = Board::N_RINGS * Board::N_SEATS;
int pos = 0;
int location = 0;
size_t newCapacity = 24;
// 留足余量空间避免多次重新分配,此动作本身也占用 CPU/内存 开销
@ -79,18 +79,18 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, MillGame &gameTemp,
// 对于摆子阶段
if (gameTemp.context.stage & (GAME_PLACING | GAME_NOTSTARTED)) {
for (int i : movePriorityTable) {
pos = i;
location = i;
if (gameTemp.board_[pos]) {
if (gameTemp.board_[location]) {
continue;
}
if (gameTemp.context.stage != GAME_NOTSTARTED || node != rootNode) {
ai_ab.addNode(node, 0, pos, bestMove, gameTemp.context.turn);
ai_ab.addNode(node, 0, location, bestMove, gameTemp.context.turn);
} else {
// 若为先手,则抢占星位
if (MillGame::isStarPoint(pos)) {
ai_ab.addNode(node, MillGameAi_ab::INF_VALUE, pos, bestMove, gameTemp.context.turn);
if (MillGame::isStarPoint(location)) {
ai_ab.addNode(node, MillGameAi_ab::INF_VALUE, location, bestMove, gameTemp.context.turn);
}
}
}
@ -99,13 +99,13 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, MillGame &gameTemp,
// 对于移子阶段
if (gameTemp.context.stage & GAME_MOVING) {
int newPos, oldPos;
int newLocation, oldLocation;
// 尽量走理论上较差的位置的棋子
for (int i = MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) {
oldPos = movePriorityTable[i];
oldLocation = movePriorityTable[i];
if (!gameTemp.choose(oldPos)) {
if (!gameTemp.choose(oldLocation)) {
continue;
}
@ -116,17 +116,17 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, MillGame &gameTemp,
// 对于棋盘上还有3个子以上或不允许飞子的情况要求必须在着法表中
for (int moveDirection = MOVE_DIRECTION_CLOCKWISE; moveDirection <= MOVE_DIRECTION_OUTWARD; moveDirection++) {
// 对于原有位置,遍历四个方向的着法,如果棋盘上为空位就加到结点列表中
newPos = moveTable[oldPos][moveDirection];
if (newPos && !gameTemp.board_[newPos]) {
int move = (oldPos << 8) + newPos;
newLocation = moveTable[oldLocation][moveDirection];
if (newLocation && !gameTemp.board_[newLocation]) {
int move = (oldLocation << 8) + newLocation;
ai_ab.addNode(node, 0, move, bestMove, gameTemp.context.turn); // (12%)
}
}
} else {
// 对于棋盘上还有不到3个字但允许飞子的情况不要求在着法表中是空位就行
for (newPos = Board::POS_BEGIN; newPos < Board::POS_END; newPos++) {
if (!gameTemp.board_[newPos]) {
int move = (oldPos << 8) + newPos;
for (newLocation = Board::LOCATION_BEGIN; newLocation < Board::LOCATION_END; newLocation++) {
if (!gameTemp.board_[newLocation]) {
int move = (oldLocation << 8) + newLocation;
ai_ab.addNode(node, 0, move, bestMove, gameTemp.context.turn);
}
}
@ -140,9 +140,9 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, MillGame &gameTemp,
if (gameTemp.context.board.isAllInMills(opponent)) {
// 全成三的情况
for (int i = MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) {
pos = movePriorityTable[i];
if (gameTemp.board_[pos] & opponent) {
ai_ab.addNode(node, 0, -pos, bestMove, gameTemp.context.turn);
location = movePriorityTable[i];
if (gameTemp.board_[location] & opponent) {
ai_ab.addNode(node, 0, -location, bestMove, gameTemp.context.turn);
}
}
break;
@ -150,10 +150,10 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, MillGame &gameTemp,
// 不是全成三的情况
for (int i = MOVE_PRIORITY_TABLE_SIZE - 1; i >= 0; i--) {
pos = movePriorityTable[i];
if (gameTemp.board_[pos] & opponent) {
if (gameTemp.getRule()->allowRemoveMill || !gameTemp.context.board.isInMills(pos)) {
ai_ab.addNode(node, 0, -pos, bestMove, gameTemp.context.turn);
location = movePriorityTable[i];
if (gameTemp.board_[location] & opponent) {
if (gameTemp.getRule()->allowRemoveMill || !gameTemp.context.board.inHowManyMills(location)) {
ai_ab.addNode(node, 0, -location, bestMove, gameTemp.context.turn);
}
}
}
@ -167,7 +167,7 @@ void MoveList::generateLegalMoves(MillGameAi_ab &ai_ab, MillGame &gameTemp,
void MoveList::createMoveTable(MillGame &game)
{
#if 1
const int moveTable_obliqueLine[Board::N_POINTS][N_MOVE_DIRECTIONS] = {
const int moveTable_obliqueLine[Board::N_LOCATIONS][N_MOVE_DIRECTIONS] = {
/* 0 */ {0, 0, 0, 0},
/* 1 */ {0, 0, 0, 0},
/* 2 */ {0, 0, 0, 0},
@ -214,7 +214,7 @@ void MoveList::createMoveTable(MillGame &game)
/* 39 */ {0, 0, 0, 0},
};
const int moveTable_noObliqueLine[Board::N_POINTS][N_MOVE_DIRECTIONS] = {
const int moveTable_noObliqueLine[Board::N_LOCATIONS][N_MOVE_DIRECTIONS] = {
/* 0 */ {0, 0, 0, 0},
/* 1 */ {0, 0, 0, 0},
/* 2 */ {0, 0, 0, 0},
@ -261,7 +261,7 @@ void MoveList::createMoveTable(MillGame &game)
/* 39 */ {0, 0, 0, 0},
};
#else
const int moveTable_obliqueLine[Board::N_POINTS][N_MOVE_DIRECTIONS] = {
const int moveTable_obliqueLine[Board::N_LOCATIONS][N_MOVE_DIRECTIONS] = {
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0},
@ -308,7 +308,7 @@ void MoveList::createMoveTable(MillGame &game)
{0, 0, 0, 0}
};
const int moveTable_noObliqueLine[Board::N_POINTS][N_MOVE_DIRECTIONS] = {
const int moveTable_noObliqueLine[Board::N_LOCATIONS][N_MOVE_DIRECTIONS] = {
/* 0 */ {0, 0, 0, 0},
/* 1 */ {0, 0, 0, 0},
/* 2 */ {0, 0, 0, 0},
@ -364,7 +364,7 @@ void MoveList::createMoveTable(MillGame &game)
#ifdef DEBUG_MODE
int sum = 0;
for (int i = 0; i < Board::N_POINTS; i++) {
for (int i = 0; i < Board::N_LOCATIONS; i++) {
loggerDebug("/* %d */ {", i);
for (int j = 0; j < N_MOVE_DIRECTIONS; j++) {
if (j == N_MOVE_DIRECTIONS - 1)

View File

@ -45,7 +45,7 @@ public:
static void shuffleMovePriorityTable(MillGame &game);
// 着法表 // TODO: Move to private
inline static int moveTable[Board::N_POINTS][N_MOVE_DIRECTIONS] = { {0} };
inline static int moveTable[Board::N_LOCATIONS][N_MOVE_DIRECTIONS] = { {0} };
private:
// 着法顺序表, 后续会被打乱

View File

@ -39,7 +39,7 @@ HashMap<hash_t, MillGameAi_ab::HashValue> bookHashMap(bookHashsize);
vector<hash_t> openingBook;
#endif // BOOK_LEARNING
// 用于检测重复局面
// 用于检测重复局面 (Position)
vector<hash_t> positions;
MillGameAi_ab::MillGameAi_ab()
@ -156,15 +156,15 @@ struct MillGameAi_ab::Node *MillGameAi_ab::addNode(
char cmd[32] = { 0 };
if (move < 0) {
gameTemp.context.board.pos2rs(-move, r, s);
gameTemp.context.board.locationToPolar(-move, r, s);
sprintf(cmd, "-(%1u,%1u)", r, s);
} else if (move & 0x7f00) {
int r1, s1;
gameTemp.context.board.pos2rs(move >> 8, r1, s1);
gameTemp.context.board.pos2rs(move & 0x00ff, r, s);
gameTemp.context.board.locationToPolar(move >> 8, r1, s1);
gameTemp.context.board.locationToPolar(move & 0x00ff, r, s);
sprintf(cmd, "(%1u,%1u)->(%1u,%1u)", r1, s1, r, s);
} else {
gameTemp.context.board.pos2rs(move & 0x007f, r, s);
gameTemp.context.board.locationToPolar(move & 0x007f, r, s);
sprintf(cmd, "(%1u,%1u)", r, s);
}
@ -747,15 +747,15 @@ const char *MillGameAi_ab::move2string(move_t move)
int r, s;
if (move < 0) {
gameTemp.context.board.pos2rs(-move, r, s);
gameTemp.context.board.locationToPolar(-move, r, s);
sprintf(cmdline, "-(%1u,%1u)", r, s);
} else if (move & 0x7f00) {
int r1, s1;
gameTemp.context.board.pos2rs(move >> 8, r1, s1);
gameTemp.context.board.pos2rs(move & 0x00ff, r, s);
gameTemp.context.board.locationToPolar(move >> 8, r1, s1);
gameTemp.context.board.locationToPolar(move & 0x00ff, r, s);
sprintf(cmdline, "(%1u,%1u)->(%1u,%1u)", r1, s1, r, s);
} else {
gameTemp.context.board.pos2rs(move & 0x007f, r, s);
gameTemp.context.board.locationToPolar(move & 0x007f, r, s);
sprintf(cmdline, "(%1u,%1u)", r, s);
}

View File

@ -22,7 +22,7 @@
#include "millgame.h"
static const hash_t zobrist0[Board::N_POINTS][POINT_TYPE_COUNT] = {
static const hash_t zobrist0[Board::N_LOCATIONS][POINT_TYPE_COUNT] = {
#ifdef TRANSPOSITION_TABLE_CUTDOWN
{0x4E421A00, 0x3962FF00, 0x6DB6EE00, 0x219AE100},
{0x1F3DE200, 0xD9AACB00, 0xD5173300, 0xD3F9EA00},

View File

@ -23,7 +23,7 @@
#include "movegen.h"
// 名义上是个数组,实际上相当于一个判断是否在棋盘上的函数
const int Board::onBoard[N_POINTS] = {
const int Board::onBoard[N_LOCATIONS] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@ -32,7 +32,7 @@ const int Board::onBoard[N_POINTS] = {
};
// 成三表
int Board::millTable[N_POINTS][N_DIRECTIONS][N_RINGS - 1] = { {{0}} };
int Board::millTable[N_LOCATIONS][N_DIRECTIONS][N_RINGS - 1] = { {{0}} };
Board::Board()
{
@ -50,7 +50,7 @@ Board &Board::operator= (const Board &other)
if (this == &other)
return *this;
memcpy(this->board_, other.board_, sizeof(this->board_));
memcpy(this->locations, other.locations, sizeof(this->locations));
if (!millList.empty()) {
millList.clear();
@ -67,7 +67,7 @@ Board &Board::operator= (const Board &other)
void Board::createMillTable(const Rule &currentRule)
{
const int millTable_noObliqueLine[Board::N_POINTS][Board::N_DIRECTIONS][2] = {
const int millTable_noObliqueLine[Board::N_LOCATIONS][Board::N_DIRECTIONS][2] = {
/* 0 */ {{0, 0}, {0, 0}, {0, 0}},
/* 1 */ {{0, 0}, {0, 0}, {0, 0}},
/* 2 */ {{0, 0}, {0, 0}, {0, 0}},
@ -114,7 +114,7 @@ void Board::createMillTable(const Rule &currentRule)
/* 39 */ {{0, 0}, {0, 0}, {0, 0}}
};
const int millTable_hasObliqueLines[Board::N_POINTS][Board::N_DIRECTIONS][2] = {
const int millTable_hasObliqueLines[Board::N_LOCATIONS][Board::N_DIRECTIONS][2] = {
/* 0 */ {{0, 0}, {0, 0}, {0, 0}},
/* 1 */ {{0, 0}, {0, 0}, {0, 0}},
/* 2 */ {{0, 0}, {0, 0}, {0, 0}},
@ -168,7 +168,7 @@ void Board::createMillTable(const Rule &currentRule)
}
#ifdef DEBUG_MODE
for (int i = 0; i < N_POINTS; i++) {
for (int i = 0; i < N_LOCATIONS; i++) {
loggerDebug("/* %d */ {", i);
for (int j = 0; j < N_DIRECTIONS; j++) {
loggerDebug("{");
@ -192,57 +192,58 @@ void Board::createMillTable(const Rule &currentRule)
#endif /* DEBUG_MODE */
}
void Board::pos2rs(const int pos, int &r, int &s)
void Board::locationToPolar(const int location, int &r, int &s)
{
//r = pos / N_SEATS;
//s = pos % N_SEATS + 1;
r = pos >> 3;
s = (pos & 0x07) + 1;
//r = location / N_SEATS;
//s = location % N_SEATS + 1;
r = location >> 3;
s = (location & 0x07) + 1;
}
int Board::rs2Pos(int r, int s)
int Board::polarToLocation(int r, int s)
{
if (r < 1 || r > N_RINGS || s < 1 || s > N_SEATS)
if (r < 1 || r > N_RINGS || s < 1 || s > N_SEATS) {
return 0;
}
return r * N_SEATS + s - 1;
}
int Board::isInMills(int pos, bool test)
int Board::inHowManyMills(int location)
{
int n = 0;
int pos1, pos2;
int m = test ? INT32_MAX : board_[pos] & '\x30';
int location1, location2;
for (int i = 0; i < 3; i++) {
pos1 = millTable[pos][i][0];
pos2 = millTable[pos][i][1];
if (m & board_[pos1] & board_[pos2])
for (int d = 0; d < N_DIRECTIONS; d++) {
location1 = millTable[location][d][0];
location2 = millTable[location][d][1];
if ((locations[location] & 0x30) & locations[location1] & locations[location2]) {
n++;
}
}
return n;
}
int Board::addMills(const Rule &currentRule, int pos)
int Board::addMills(const Rule &currentRule, int location)
{
// 成三用一个64位整数了规则如下
// 0x 00 00 00 00 00 00 00 00
// unused unused piece1 pos1 piece2 pos2 piece3 pos3
// unused unused piece1 location1 piece2 location2 piece3 pos3
// piece1、piece2、piece3按照序号从小到大顺序排放
uint64_t mill = 0;
int n = 0;
int p[3], min, temp;
char m = board_[pos] & '\x30';
char m = locations[location] & '\x30';
for (int i = 0; i < 3; i++) {
p[0] = pos;
p[1] = millTable[pos][i][0];
p[2] = millTable[pos][i][1];
p[0] = location;
p[1] = millTable[location][i][0];
p[2] = millTable[location][i][1];
// 如果没有成三
if (!(m & board_[p[1]] & board_[p[2]])) {
if (!(m & locations[p[1]] & locations[p[2]])) {
continue;
}
@ -267,11 +268,11 @@ int Board::addMills(const Rule &currentRule, int pos)
}
// 成三
mill = (static_cast<uint64_t>(board_[p[0]]) << 40)
mill = (static_cast<uint64_t>(locations[p[0]]) << 40)
+ (static_cast<uint64_t>(p[0]) << 32)
+ (static_cast<uint64_t>(board_[p[1]]) << 24)
+ (static_cast<uint64_t>(locations[p[1]]) << 24)
+ (static_cast<uint64_t>(p[1]) << 16)
+ (static_cast<uint64_t>(board_[p[2]]) << 8)
+ (static_cast<uint64_t>(locations[p[2]]) << 8)
+ static_cast<uint64_t>(p[2]);
// 如果允许相同三连反复去子
@ -303,9 +304,9 @@ int Board::addMills(const Rule &currentRule, int pos)
bool Board::isAllInMills(char ch)
{
for (int i = POS_BEGIN; i < POS_END; i++) {
if (board_[i] & ch) {
if (!isInMills(i)) {
for (int i = LOCATION_BEGIN; i < LOCATION_END; i++) {
if (locations[i] & ch) {
if (!inHowManyMills(i)) {
return false;
}
}
@ -329,7 +330,7 @@ bool Board::isAllInMills(enum Player player)
}
// 判断玩家的棋子周围有几个空位
int Board::getSurroundedEmptyPosCount(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, int pos, bool includeFobidden)
int Board::getSurroundedEmptyLocationCount(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, int location, bool includeFobidden)
{
int count = 0;
@ -337,12 +338,12 @@ int Board::getSurroundedEmptyPosCount(enum Player turn, const Rule &currentRule,
(nPiecesOnBoard_1 > currentRule.nPiecesAtLeast || !currentRule.allowFlyWhenRemainThreePieces)) ||
(turn == PLAYER2 &&
(nPiecesOnBoard_2 > currentRule.nPiecesAtLeast || !currentRule.allowFlyWhenRemainThreePieces))) {
int d, movePos;
int d, moveLocation;
for (d = 0; d < N_MOVE_DIRECTIONS; d++) {
movePos = MoveList::moveTable[pos][d];
if (movePos) {
if (board_[movePos] == 0x00 ||
(includeFobidden && board_[movePos] == 0x0F)) {
moveLocation = MoveList::moveTable[location][d];
if (moveLocation) {
if (locations[moveLocation] == 0x00 ||
(includeFobidden && locations[moveLocation] == 0x0F)) {
count++;
}
}
@ -353,17 +354,17 @@ int Board::getSurroundedEmptyPosCount(enum Player turn, const Rule &currentRule,
}
// 判断玩家的棋子是否被围
bool Board::isSurrounded(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, int pos)
bool Board::isSurrounded(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, int location)
{
// 判断pos处的棋子是否被“闷”
// 判断location处的棋子是否被“闷”
if ((turn == PLAYER1 &&
(nPiecesOnBoard_1 > currentRule.nPiecesAtLeast || !currentRule.allowFlyWhenRemainThreePieces)) ||
(turn == PLAYER2 &&
(nPiecesOnBoard_2 > currentRule.nPiecesAtLeast || !currentRule.allowFlyWhenRemainThreePieces))) {
int i, movePos;
int i, moveLocation;
for (i = 0; i < 4; i++) {
movePos = MoveList::moveTable[pos][i];
if (movePos && !board_[movePos])
moveLocation = MoveList::moveTable[location][i];
if (moveLocation && !locations[moveLocation])
break;
}
// 被围住
@ -389,15 +390,15 @@ bool Board::isAllSurrounded(enum Player turn, const Rule &currentRule, int nPiec
}
// 查询整个棋盘
int movePos;
int moveLocation;
for (int i = 1; i < N_SEATS * (N_RINGS + 1); i++) {
if (!(ch & board_[i])) {
if (!(ch & locations[i])) {
continue;
}
for (int d = 0; d < N_MOVE_DIRECTIONS; d++) {
movePos = MoveList::moveTable[i][d];
if (movePos && !board_[movePos])
moveLocation = MoveList::moveTable[i][d];
if (moveLocation && !locations[moveLocation])
return false;
}
}
@ -420,12 +421,12 @@ bool Board::isAllSurrounded(enum Player turn, const Rule &currentRule, int nPiec
enum Player Board::getWhosPiece(int r, int s)
{
int pos = rs2Pos(r, s);
int location = polarToLocation(r, s);
if (board_[pos] & '\x10')
if (locations[location] & '\x10')
return PLAYER1;
if (board_[pos] & '\x20')
if (locations[location] & '\x20')
return PLAYER2;
return PLAYER_NOBODY;
@ -449,9 +450,9 @@ bool Board::getPieceRS(const Player &player, const int &number, int &r, int &s,
else
return false;
for (int i = POS_BEGIN; i < POS_END; i++) {
if (board_[i] == piece) {
pos2rs(i, r, s);
for (int i = LOCATION_BEGIN; i < LOCATION_END; i++) {
if (locations[i] == piece) {
locationToPolar(i, r, s);
return true;
}
}
@ -460,12 +461,12 @@ bool Board::getPieceRS(const Player &player, const int &number, int &r, int &s,
}
// 获取当前棋子
bool Board::getCurrentPiece(Player &player, int &number, int currentPos)
bool Board::getCurrentPiece(Player &player, int &number, int location)
{
if (!onBoard[currentPos])
if (!onBoard[location])
return false;
int p = board_[currentPos];
int p = locations[location];
if (p & 0x10) {
player = PLAYER1;
@ -480,7 +481,7 @@ bool Board::getCurrentPiece(Player &player, int &number, int currentPos)
return true;
}
void Board::mirror(list <string> &cmdlist, char* cmdline, int32_t move_, struct Rule &currentRule, int currentPos, bool cmdChange /*= true*/)
void Board::mirror(list <string> &cmdlist, char* cmdline, int32_t move_, struct Rule &currentRule, int location, bool cmdChange /*= true*/)
{
int ch;
int r, s;
@ -488,10 +489,10 @@ void Board::mirror(list <string> &cmdlist, char* cmdline, int32_t move_, struct
for (r = 1; r <= N_RINGS; r++) {
for (s = 1; s < N_SEATS / 2; s++) {
ch = board_[r * N_SEATS + s];
board_[r * N_SEATS + s] = board_[(r + 1) * N_SEATS - s];
ch = locations[r * N_SEATS + s];
locations[r * N_SEATS + s] = locations[(r + 1) * N_SEATS - s];
//updateHash(i * N_SEATS + j);
board_[(r + 1) * N_SEATS - s] = ch;
locations[(r + 1) * N_SEATS - s] = ch;
//updateHash((i + 1) * N_SEATS - j);
}
}
@ -517,11 +518,11 @@ void Board::mirror(list <string> &cmdlist, char* cmdline, int32_t move_, struct
move_ = static_cast<int16_t>(((llp[0] << 8) | llp[1]));
}
if (currentPos != 0) {
r = currentPos / N_SEATS;
s = currentPos % N_SEATS;
if (location != 0) {
r = location / N_SEATS;
s = location % N_SEATS;
s = (N_SEATS - s) % N_SEATS;
currentPos = r * N_SEATS + s;
location = r * N_SEATS + s;
}
if (currentRule.allowRemovePiecesRepeatedly) {
@ -592,17 +593,17 @@ void Board::mirror(list <string> &cmdlist, char* cmdline, int32_t move_, struct
}
}
void Board::turn(list <string> &cmdlist, char *cmdline, int32_t move_, const Rule &currentRule, int currentPos, bool cmdChange /*= true*/)
void Board::turn(list <string> &cmdlist, char *cmdline, int32_t move_, const Rule &currentRule, int location, bool cmdChange /*= true*/)
{
int ch;
int r, s;
int i;
for (s = 0; s < N_SEATS; s++) {
ch = board_[N_SEATS + s];
board_[N_SEATS + s] = board_[N_SEATS * N_RINGS + s];
ch = locations[N_SEATS + s];
locations[N_SEATS + s] = locations[N_SEATS * N_RINGS + s];
//updateHash(N_SEATS + s);
board_[N_SEATS * N_RINGS + s] = ch;
locations[N_SEATS * N_RINGS + s] = ch;
//updateHash(N_SEATS * N_RINGS + s);
}
@ -637,16 +638,16 @@ void Board::turn(list <string> &cmdlist, char *cmdline, int32_t move_, const Rul
move_ = static_cast<int16_t>(((llp[0] << 8) | llp[1]));
}
if (currentPos != 0) {
r = currentPos / N_SEATS;
s = currentPos % N_SEATS;
if (location != 0) {
r = location / N_SEATS;
s = location % N_SEATS;
if (r == 1)
r = N_RINGS;
else if (r == N_RINGS)
r = 1;
currentPos = r * N_SEATS + s;
location = r * N_SEATS + s;
}
if (currentRule.allowRemovePiecesRepeatedly) {
@ -757,7 +758,7 @@ void Board::turn(list <string> &cmdlist, char *cmdline, int32_t move_, const Rul
}
}
void Board::rotate(int degrees, list <string> &cmdlist, char *cmdline, int32_t move_, const Rule &currentRule, int currentPos, bool cmdChange /*= true*/)
void Board::rotate(int degrees, list <string> &cmdlist, char *cmdline, int32_t move_, const Rule &currentRule, int location, bool cmdChange /*= true*/)
{
// 将degrees转化为0~359之间的数
degrees = degrees % 360;
@ -776,40 +777,40 @@ void Board::rotate(int degrees, list <string> &cmdlist, char *cmdline, int32_t m
if (degrees == 2) {
for (r = 1; r <= N_RINGS; r++) {
ch1 = board_[r * N_SEATS];
ch2 = board_[r * N_SEATS + 1];
ch1 = locations[r * N_SEATS];
ch2 = locations[r * N_SEATS + 1];
for (s = 0; s < N_SEATS - 2; s++) {
board_[r * N_SEATS + s] = board_[r * N_SEATS + s + 2];
locations[r * N_SEATS + s] = locations[r * N_SEATS + s + 2];
}
board_[r * N_SEATS + 6] = ch1;
locations[r * N_SEATS + 6] = ch1;
//updateHash(i * N_SEATS + 6);
board_[r * N_SEATS + 7] = ch2;
locations[r * N_SEATS + 7] = ch2;
//updateHash(i * N_SEATS + 7);
}
} else if (degrees == 6) {
for (r = 1; r <= N_RINGS; r++) {
ch1 = board_[r * N_SEATS + 7];
ch2 = board_[r * N_SEATS + 6];
ch1 = locations[r * N_SEATS + 7];
ch2 = locations[r * N_SEATS + 6];
for (s = N_SEATS - 1; s >= 2; s--) {
board_[r * N_SEATS + s] = board_[r * N_SEATS + s - 2];
locations[r * N_SEATS + s] = locations[r * N_SEATS + s - 2];
//updateHash(i * N_SEATS + j);
}
board_[r * N_SEATS + 1] = ch1;
locations[r * N_SEATS + 1] = ch1;
//updateHash(i * N_SEATS + 1);
board_[r * N_SEATS] = ch2;
locations[r * N_SEATS] = ch2;
//updateHash(i * N_SEATS);
}
} else if (degrees == 4) {
for (r = 1; r <= N_RINGS; r++) {
for (s = 0; s < N_SEATS / 2; s++) {
ch1 = board_[r * N_SEATS + s];
board_[r * N_SEATS + s] = board_[r * N_SEATS + s + 4];
ch1 = locations[r * N_SEATS + s];
locations[r * N_SEATS + s] = locations[r * N_SEATS + s + 4];
//updateHash(i * N_SEATS + j);
board_[r * N_SEATS + s + 4] = ch1;
locations[r * N_SEATS + s + 4] = ch1;
//updateHash(i * N_SEATS + j + 4);
}
}
@ -838,11 +839,11 @@ void Board::rotate(int degrees, list <string> &cmdlist, char *cmdline, int32_t m
move_ = static_cast<int16_t>(((llp[0] << 8) | llp[1]));
}
if (currentPos != 0) {
r = currentPos / N_SEATS;
s = currentPos % N_SEATS;
if (location != 0) {
r = location / N_SEATS;
s = location % N_SEATS;
s = (s + N_SEATS - degrees) % N_SEATS;
currentPos = r * N_SEATS + s;
location = r * N_SEATS + s;
}
if (currentRule.allowRemovePiecesRepeatedly) {

View File

@ -49,18 +49,18 @@ public:
static const int N_DIRECTIONS = 3;
// 棋盘点的个数40
static const int N_POINTS = (Board::N_RINGS + 2) * Board::N_SEATS;
static const int N_LOCATIONS = (Board::N_RINGS + 2) * Board::N_SEATS;
// 遍历棋盘点所用的起始位置,即 [8, 32)
static const int POS_BEGIN = N_SEATS;
static const int POS_END = ((N_RINGS + 1) * N_SEATS);
static const int LOCATION_BEGIN = N_SEATS;
static const int LOCATION_END = ((N_RINGS + 1) * N_SEATS);
// 空棋盘点位,用于判断一个棋子位置是否在棋盘上
static const int onBoard[N_POINTS];
static const int onBoard[N_LOCATIONS];
// 成三表,表示棋盘上各个位置有成三关系的对应位置表
// 这个表跟规则有关,一旦规则改变需要重新修改
static int millTable[N_POINTS][N_DIRECTIONS][N_RINGS - 1];
static int millTable[N_LOCATIONS][N_DIRECTIONS][N_RINGS - 1];
// 生成成三表
void createMillTable(const Rule &currentRule);
@ -74,18 +74,18 @@ public:
// 局面逆时针旋转
void rotate(int degrees, list <string> &cmdlist, char *cmdline, int32_t move_, const Rule &currentRule, int currentPos, bool cmdChange = true);
// 判断棋盘pos处的棋子处于几个“三连”中
int isInMills(int pos, bool test = false);
// 判断棋盘location处的棋子处于几个“三连”中
int inHowManyMills(int location);
// 判断玩家的所有棋子是否都处于“三连”状态
bool isAllInMills(char ch);
bool isAllInMills(enum Player);
// 判断玩家的棋子周围有几个空位
int getSurroundedEmptyPosCount(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, int pos, bool includeFobidden);
int getSurroundedEmptyLocationCount(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, int location, bool includeFobidden);
// 判断玩家的棋子是否被围
bool isSurrounded(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, int pos);
bool isSurrounded(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, int location);
// 判断玩家的棋子是否全部被围
bool isAllSurrounded(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, char ch);
@ -93,7 +93,7 @@ public:
bool isAllSurrounded(enum Player turn, const Rule &currentRule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, enum Player ply);
// 三连加入列表
int addMills(const Rule &currentRule, int pos);
int addMills(const Rule &currentRule, int location);
// 获取位置点棋子的归属人
enum Player getWhosPiece(int r, int s);
@ -104,10 +104,10 @@ public:
bool getCurrentPiece(Player &player, int &number, int currentPos);
// 将棋盘下标形式转化为第r圈第s位r和s下标都从1开始
void pos2rs(int pos, int &r, int &s);
void locationToPolar(int location, int &r, int &s);
// 将第c圈第p位转化为棋盘下标形式r和s下标都从1开始
int rs2Pos(int r, int s);
int polarToLocation(int r, int s);
//private:
@ -120,22 +120,22 @@ public:
(board[i] & 0x10)
(board[i] & 0x20)
*/
int board_[N_POINTS]{};
int locations[N_LOCATIONS]{};
/*
struct Mill {
char piece1; // “三连”中最小的棋子
char pos1; // 最小棋子的位置
char location1; // 最小棋子的位置
char piece2; // 次小的棋子
char pos2; // 次小棋子的位置
char location2; // 次小棋子的位置
char piece3; // 最大的棋子
char pos3; // 最大棋子的位置
char location3; // 最大棋子的位置
};
64
0x 00 00 00 00 00 00 00 00
unused unused piece1 pos1 piece2 pos2 piece3 pos3
unused unused piece1 location1 piece2 location2 piece3 location3
*/
// 三连列表

View File

@ -27,7 +27,7 @@
MillGame::MillGame()
{
// 单独提出 board 等数据,免得每次都写 context.board;
board_ = context.board.board_;
board_ = context.board.locations;
// 创建哈希数据
constructHash();
@ -62,8 +62,8 @@ MillGame &MillGame::operator= (const MillGame &game)
moveStep = game.moveStep;
randomMove_ = game.randomMove_;
giveUpIfMostLose_ = game.giveUpIfMostLose_;
board_ = context.board.board_;
currentPos = game.currentPos;
board_ = context.board.locations;
currentLocation = game.currentLocation;
winner = game.winner;
startTime = game.startTime;
currentTime = game.currentTime;
@ -170,10 +170,10 @@ bool MillGame::setContext(const struct Rule *rule, step_t maxStepsLedToDraw, int
// 当前棋局3×8
if (board == nullptr) {
memset(context.board.board_, 0, sizeof(context.board.board_));
memset(context.board.locations, 0, sizeof(context.board.locations));
context.hash = 0;
} else {
memcpy(context.board.board_, board, sizeof(context.board.board_));
memcpy(context.board.locations, board, sizeof(context.board.locations));
}
// 计算盘面子数
@ -190,12 +190,12 @@ bool MillGame::setContext(const struct Rule *rule, step_t maxStepsLedToDraw, int
for (int r = 1; r < Board::N_RINGS + 2; r++) {
for (int s = 0; s < Board::N_SEATS; s++) {
int pos = r * Board::N_SEATS + s;
if (context.board.board_[pos] & 0x10) {
int location = r * Board::N_SEATS + s;
if (context.board.locations[location] & 0x10) {
context.nPiecesOnBoard_1++;
} else if (context.board.board_[pos] & 0x20) {
} else if (context.board.locations[location] & 0x20) {
context.nPiecesOnBoard_2++;
} else if (context.board.board_[pos] & 0x0F) {
} else if (context.board.locations[location] & 0x0F) {
// 不计算盘面子数
}
}
@ -240,7 +240,7 @@ bool MillGame::setContext(const struct Rule *rule, step_t maxStepsLedToDraw, int
context.board.createMillTable(currentRule);
// 不选中棋子
currentPos = 0;
currentLocation = 0;
// 用时置零
elapsedSeconds_1 = elapsedSeconds_2 = 0;
@ -319,7 +319,7 @@ bool MillGame::reset()
}
// 不选中棋子
currentPos = 0;
currentLocation = 0;
// 用时置零
elapsedSeconds_1 = elapsedSeconds_2 = 0;
@ -374,7 +374,7 @@ bool MillGame::start()
}
}
bool MillGame::place(int pos, int time_p, int8_t rs)
bool MillGame::place(int location, int time_p, int8_t rs)
{
// 如果局面为“结局”返回false
if (context.stage == GAME_OVER)
@ -389,13 +389,13 @@ bool MillGame::place(int pos, int time_p, int8_t rs)
return false;
// 如果落子位置在棋盘外、已有子点或禁点返回false
if (!context.board.onBoard[pos] || board_[pos])
if (!context.board.onBoard[location] || board_[location])
return false;
// 格式转换
int r = 0;
int s = 0;
context.board.pos2rs(pos, r, s);
context.board.locationToPolar(location, r, s);
// 时间的临时变量
int player_ms = -1;
@ -418,11 +418,11 @@ bool MillGame::place(int pos, int time_p, int8_t rs)
context.nPiecesOnBoard_2++;
}
board_[pos] = piece;
board_[location] = piece;
updateHash(pos);
updateHash(location);
move_ = pos;
move_ = location;
if (rs) {
player_ms = update(time_p);
@ -432,9 +432,9 @@ bool MillGame::place(int pos, int time_p, int8_t rs)
currentStep++;
}
currentPos = pos;
currentLocation = location;
n = context.board.addMills(currentRule, currentPos);
n = context.board.addMills(currentRule, currentLocation);
// 开局阶段未成三
if (n == 0) {
@ -494,7 +494,7 @@ bool MillGame::place(int pos, int time_p, int8_t rs)
int i;
for (i = 0; i < 4; i++) {
if (pos == MoveList::moveTable[currentPos][i])
if (location == MoveList::moveTable[currentLocation][i])
break;
}
@ -505,26 +505,26 @@ bool MillGame::place(int pos, int time_p, int8_t rs)
}
// 移子
move_ = (currentPos << 8) + pos;
move_ = (currentLocation << 8) + location;
if (rs) {
player_ms = update(time_p);
sprintf(cmdline, "(%1u,%1u)->(%1u,%1u) %02u:%02u", currentPos / Board::N_SEATS, currentPos % Board::N_SEATS + 1,
sprintf(cmdline, "(%1u,%1u)->(%1u,%1u) %02u:%02u", currentLocation / Board::N_SEATS, currentLocation % Board::N_SEATS + 1,
r, s, player_ms / 60, player_ms % 60);
cmdlist.emplace_back(string(cmdline));
currentStep++;
moveStep++;
}
board_[pos] = board_[currentPos];
board_[location] = board_[currentLocation];
updateHash(pos);
updateHash(location);
board_[currentPos] = '\x00';
board_[currentLocation] = '\x00';
revertHash(currentPos);
revertHash(currentLocation);
currentPos = pos;
n = context.board.addMills(currentRule, currentPos);
currentLocation = location;
n = context.board.addMills(currentRule, currentLocation);
// 中局阶段未成三
if (n == 0) {
@ -558,21 +558,21 @@ out:
bool MillGame::_place(int r, int s, int time_p)
{
// 转换为 pos
int pos = context.board.rs2Pos(r, s);
// 转换为 location
int location = context.board.polarToLocation(r, s);
return place(pos, time_p, true);
return place(location, time_p, true);
}
bool MillGame::_capture(int r, int s, int time_p)
{
// 转换为 pos
int pos = context.board.rs2Pos(r, s);
// 转换为 location
int location = context.board.polarToLocation(r, s);
return capture(pos, time_p, 1);
return capture(location, time_p, 1);
}
bool MillGame::capture(int pos, int time_p, int8_t cp)
bool MillGame::capture(int location, int time_p, int8_t cp)
{
// 如果局面为"未开局"或“结局”返回false
if (context.stage == GAME_NOTSTARTED || context.stage == GAME_OVER)
@ -589,7 +589,7 @@ bool MillGame::capture(int pos, int time_p, int8_t cp)
// 格式转换
int r = 0;
int s = 0;
context.board.pos2rs(pos, r, s);
context.board.locationToPolar(location, r, s);
// 时间的临时变量
int player_ms = -1;
@ -598,23 +598,24 @@ bool MillGame::capture(int pos, int time_p, int8_t cp)
char opponent = context.turn == PLAYER1 ? 0x20 : 0x10;
// 判断去子是不是对手棋
if (!(opponent & board_[pos]))
if (!(opponent & board_[location]))
return false;
// 如果当前子是否处于“三连”之中,且对方还未全部处于“三连”之中
if (!currentRule.allowRemoveMill &&
context.board.isInMills(pos) && !context.board.isAllInMills(opponent)) {
context.board.inHowManyMills(location) &&
!context.board.isAllInMills(opponent)) {
return false;
}
// 去子(设置禁点)
if (currentRule.hasForbiddenPoint && context.stage == GAME_PLACING) {
revertHash(pos);
board_[pos] = '\x0f';
updateHash(pos);
revertHash(location);
board_[location] = '\x0f';
updateHash(location);
} else { // 去子
revertHash(pos);
board_[pos] = '\x00';
revertHash(location);
board_[location] = '\x00';
}
if (context.turn == PLAYER1)
@ -622,7 +623,7 @@ bool MillGame::capture(int pos, int time_p, int8_t cp)
else if (context.turn == PLAYER2)
context.nPiecesOnBoard_1--;
move_ = -pos;
move_ = -location;
if (cp) {
player_ms = update(time_p);
@ -632,9 +633,9 @@ bool MillGame::capture(int pos, int time_p, int8_t cp)
moveStep = 0;
}
currentPos = 0;
currentLocation = 0;
context.nPiecesNeedRemove--;
updateHash(pos);
updateHash(location);
// 去子完成
@ -713,7 +714,7 @@ out:
return true;
}
bool MillGame::choose(int pos)
bool MillGame::choose(int location)
{
// 如果局面不是"中局”返回false
if (context.stage != GAME_MOVING)
@ -726,14 +727,14 @@ bool MillGame::choose(int pos)
char t = context.turn == PLAYER1 ? 0x10 : 0x20;
// 判断选子是否可选
if (board_[pos] & t) {
// 判断pos处的棋子是否被“闷”
if (context.board.isSurrounded(context.turn, currentRule, context.nPiecesOnBoard_1, context.nPiecesOnBoard_2, pos)) {
if (board_[location] & t) {
// 判断location处的棋子是否被“闷”
if (context.board.isSurrounded(context.turn, currentRule, context.nPiecesOnBoard_1, context.nPiecesOnBoard_2, location)) {
return false;
}
// 选子
currentPos = pos;
currentLocation = location;
// 选子完成,进入落子状态
context.action = ACTION_PLACE;
@ -746,7 +747,7 @@ bool MillGame::choose(int pos)
bool MillGame::choose(int r, int s)
{
return choose(context.board.rs2Pos(r, s));
return choose(context.board.polarToLocation(r, s));
}
bool MillGame::giveup(Player loser)
@ -1044,14 +1045,14 @@ bool MillGame::win(bool forceDraw)
// 计算玩家1和玩家2的棋子活动能力之差
int MillGame::getMobilityDiff(enum Player turn, const Rule &rule, int nPiecesOnBoard_1, int nPiecesOnBoard_2, bool includeFobidden)
{
int *board = context.board.board_;
int *board = context.board.locations;
int mobility1 = 0;
int mobility2 = 0;
int diff = 0;
int n = 0;
for (int i = Board::POS_BEGIN; i < Board::POS_END; i++) {
n = context.board.getSurroundedEmptyPosCount(turn, rule, nPiecesOnBoard_1, nPiecesOnBoard_2, i, includeFobidden);
for (int i = Board::LOCATION_BEGIN; i < Board::LOCATION_END; i++) {
n = context.board.getSurroundedEmptyLocationCount(turn, rule, nPiecesOnBoard_1, nPiecesOnBoard_2, i, includeFobidden);
if (board[i] & 0x10) {
mobility1 += n;
@ -1067,15 +1068,15 @@ int MillGame::getMobilityDiff(enum Player turn, const Rule &rule, int nPiecesOnB
void MillGame::cleanForbiddenPoints()
{
int pos = 0;
int location = 0;
for (int r = 1; r <= Board::N_RINGS; r++) {
for (int s = 0; s < Board::N_SEATS; s++) {
pos = r * Board::N_SEATS + s;
location = r * Board::N_SEATS + s;
if (board_[pos] == '\x0f') {
revertHash(pos);
board_[pos] = '\x00';
if (board_[location] == '\x0f') {
revertHash(location);
board_[location] = '\x00';
}
}
}
@ -1178,7 +1179,7 @@ void MillGame::constructHash()
context.hash = 0;
#include "zobrist.h"
memcpy(context.zobrist, zobrist0, sizeof(hash_t) * Board::N_POINTS * POINT_TYPE_COUNT);
memcpy(context.zobrist, zobrist0, sizeof(hash_t) * Board::N_LOCATIONS * POINT_TYPE_COUNT);
}
hash_t MillGame::getHash()
@ -1189,22 +1190,22 @@ hash_t MillGame::getHash()
return context.hash;
}
hash_t MillGame::updateHash(int pos)
hash_t MillGame::updateHash(int location)
{
// PieceType is board_[pos]
// PieceType is board_[location]
// 0b00 表示空白0b01 = 1 表示先手棋子0b10 = 2 表示后手棋子0b11 = 3 表示禁点
int pointType = (board_[pos] & 0x30) >> 4;
int pointType = (board_[location] & 0x30) >> 4;
// 清除或者放置棋子
context.hash ^= context.zobrist[pos][pointType];
context.hash ^= context.zobrist[location][pointType];
return context.hash;
}
hash_t MillGame::revertHash(int pos)
hash_t MillGame::revertHash(int location)
{
return updateHash(pos);
return updateHash(location);
}
hash_t MillGame::updateHashMisc()

View File

@ -45,7 +45,7 @@ public:
hash_t hash{};
// Zobrist 数组
hash_t zobrist[Board::N_POINTS][POINT_TYPE_COUNT]{};
hash_t zobrist[Board::N_LOCATIONS][POINT_TYPE_COUNT]{};
// 局面阶段标识
enum GameStage stage;
@ -148,19 +148,19 @@ public:
// 获取棋盘数据
const int *getBoard() const
{
return context.board.board_;
return context.board.locations;
}
// 获取当前棋子位置点
int getCurrentPos() const
int getCurrentLocation() const
{
return currentPos;
return currentLocation;
}
// 判断位置点是否为星位 (星位是经常会先占的位置)
static bool isStarPoint(int pos)
static bool isStarPoint(int location)
{
return (pos == 17 || pos == 19 || pos == 21 || pos == 23);
return (location == 17 || location == 19 || location == 21 || location == 23);
}
// 获取当前步数
@ -316,14 +316,14 @@ public:
// 下面几个函数没有算法无关判断和无关操作,节约算法时间
bool command(int move);
bool choose(int pos);
bool place(int pos, int time_p = -1, int8_t cp = 0);
bool capture(int pos, int time_p = -1, int8_t cp = 0);
bool choose(int location);
bool place(int location, int time_p = -1, int8_t cp = 0);
bool capture(int location, int time_p = -1, int8_t cp = 0);
// hash 相关
hash_t getHash();
hash_t revertHash(int pos);
hash_t updateHash(int pos);
hash_t revertHash(int location);
hash_t updateHash(int location);
hash_t updateHashMisc();
public: /* TODO: move to private */
@ -347,7 +347,7 @@ public: /* TODO: move to private */
/*
AI会用到
0x 00 00
pos1 pos2
location1 location2
0x00????
0x__??__为移动前的位置??
0xFF????
@ -367,7 +367,7 @@ public: /* TODO: move to private */
int32_t move_{};
// 选中的棋子在board中的位置
int currentPos{};
int currentLocation{};
private:
// 棋局哈希值

View File

@ -398,8 +398,8 @@ void GameController::flip()
ai2.wait();
}
game_.context.board.mirror(game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentPos);
game_.context.board.rotate(180, game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentPos);
game_.context.board.mirror(game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentLocation);
game_.context.board.rotate(180, game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentLocation);
gameTemp = game_;
// 更新棋谱
@ -438,7 +438,7 @@ void GameController::mirror()
ai2.wait();
}
game_.context.board.mirror(game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentPos);
game_.context.board.mirror(game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentLocation);
gameTemp = game_;
// 更新棋谱
@ -480,7 +480,7 @@ void GameController::turnRight()
ai2.wait();
}
game_.context.board.rotate(-90, game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentPos);
game_.context.board.rotate(-90, game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentLocation);
gameTemp = game_;
// 更新棋谱
@ -520,7 +520,7 @@ void GameController::turnLeft()
ai2.wait();
}
game_.context.board.rotate(90, game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentPos);
game_.context.board.rotate(90, game_.cmdlist, game_.cmdline, game_.move_, game_.currentRule, game_.currentLocation);
gameTemp = game_;
// 更新棋谱
@ -1004,7 +1004,7 @@ bool GameController::updateScence(MillGame &game)
int j;
// 遍历棋盘,查找并放置棋盘上的棋子
for (j = Board::POS_BEGIN; j < Board::POS_END; j++) {
for (j = Board::LOCATION_BEGIN; j < Board::LOCATION_END; j++) {
if (board[j] == key) {
pos = scene.rs2pos(j / Board::N_SEATS, j % Board::N_SEATS + 1);
if (piece->pos() != pos) {
@ -1062,7 +1062,7 @@ bool GameController::updateScence(MillGame &game)
// 添加摆棋阶段禁子点
if (game.getRule()->hasForbiddenPoint && game.getStage() == GAME_PLACING) {
for (int j = Board::POS_BEGIN; j < Board::POS_END; j++) {
for (int j = Board::LOCATION_BEGIN; j < Board::LOCATION_END; j++) {
if (board[j] == 0x0F) {
pos = scene.rs2pos(j / Board::N_SEATS, j % Board::N_SEATS + 1);
if (nTotalPieces < pieceList.size()) {
@ -1088,9 +1088,9 @@ bool GameController::updateScence(MillGame &game)
}
// 选中当前棋子
int ipos = game.getCurrentPos();
int ipos = game.getCurrentLocation();
if (ipos) {
key = board[game.getCurrentPos()];
key = board[game.getCurrentLocation()];
ipos = key & 0x10 ? (key - 0x11) * 2 : (key - 0x21) * 2 + 1;
if (ipos >= 0 && ipos < nTotalPieces) {
currentPiece = pieceList.at(ipos);