完善镜像、翻转、旋转等局面变换;

修正时间纪录bug。
This commit is contained in:
liuweilhy 2018-12-15 00:03:07 +08:00
parent 82b39b02ac
commit a71536f825
6 changed files with 410 additions and 92 deletions

View File

@ -159,9 +159,9 @@ void GameController::gameReset()
}
// 更新棋谱
manualListModel.removeRows(0, manualListModel.rowCount());
currentRow = 0;
manualListModel.insertRow(0);
manualListModel.setData(manualListModel.index(0), chess.getCmdLine());
currentRow = 0;
// 发出信号通知主窗口更新LCD显示
QTime qtime = QTime(0, 0, 0, 0).addMSecs(time1);
emit time1Changed(qtime.toString("mm:ss.zzz"));
@ -277,34 +277,140 @@ void GameController::playSound(const QString &soundPath)
// 上下翻转
void GameController::flip()
{
if (isEngine1) {
ai1.stop();
ai1.wait();
}
if (isEngine2) {
ai2.stop();
ai2.wait();
}
chess.mirror();
chess.rotate(180);
chessTemp = chess;
updateScence();
// 更新棋谱
int row = 0;
for (auto str : *(chess.getCmdList())) {
manualListModel.setData(manualListModel.index(row++), str.c_str());
}
// 刷新显示
if (currentRow == row - 1)
updateScence();
else
phaseChange(currentRow, true);
if (isEngine1) {
ai1.setAi(chess);
ai1.start();
}
if (isEngine2) {
ai2.setAi(chess);
ai2.start();
}
}
// 左右镜像
void GameController::mirror()
{
if (isEngine1) {
ai1.stop();
ai1.wait();
}
if (isEngine2) {
ai2.stop();
ai2.wait();
}
chess.mirror();
chessTemp = chess;
updateScence();
// 更新棋谱
int row = 0;
for (auto str : *(chess.getCmdList())) {
manualListModel.setData(manualListModel.index(row++), str.c_str());
}
qDebug() << "list: " << row;
// 刷新显示
if (currentRow == row - 1)
updateScence();
else
phaseChange(currentRow, true);
if (isEngine1) {
ai1.setAi(chess);
ai1.start();
}
if (isEngine2) {
ai2.setAi(chess);
ai2.start();
}
}
// 视图须时针旋转90°
void GameController::turnRight()
{
chess.rotate(90);
if (isEngine1) {
ai1.stop();
ai1.wait();
}
if (isEngine2) {
ai2.stop();
ai2.wait();
}
chess.rotate(-90);
chessTemp = chess;
updateScence();
// 更新棋谱
int row = 0;
for (auto str : *(chess.getCmdList())) {
manualListModel.setData(manualListModel.index(row++), str.c_str());
}
// 刷新显示
if (currentRow == row - 1)
updateScence();
else
phaseChange(currentRow, true);
if (isEngine1) {
ai1.setAi(chess);
ai1.start();
}
if (isEngine2) {
ai2.setAi(chess);
ai2.start();
}
}
// 视图逆时针旋转90°
void GameController::turnLeft()
{
chess.rotate(270);
if (isEngine1) {
ai1.stop();
ai1.wait();
}
if (isEngine2) {
ai2.stop();
ai2.wait();
}
chess.rotate(90);
chessTemp = chess;
// 更新棋谱
int row = 0;
for (auto str : *(chess.getCmdList())) {
manualListModel.setData(manualListModel.index(row++), str.c_str());
}
// 刷新显示
updateScence();
if (isEngine1) {
ai1.setAi(chess);
ai1.start();
}
if (isEngine2) {
ai2.setAi(chess);
ai2.start();
}
}
@ -554,8 +660,9 @@ bool GameController::command(const QString &cmd, bool update /*= true*/)
}
// 如果未开局则开局
if (chess.getPhase() == NineChess::GAME_NOTSTARTED)
if (chess.getPhase() == NineChess::GAME_NOTSTARTED) {
gameStart();
}
if (!chess.command(cmd.toStdString().c_str()))
return false;
@ -573,16 +680,27 @@ bool GameController::command(const QString &cmd, bool update /*= true*/)
message = QString::fromStdString(chess.getTip());
emit statusBarChanged(message);
// 将新增的棋谱行插入到ListModel
currentRow = manualListModel.rowCount() - 1;
int k = 0;
// 输出命令行
for (auto i = (chess.getCmdList())->begin(); i != (chess.getCmdList())->end(); ++i) {
// 跳过已添加的因标准list容器没有下标
if (k++ <= currentRow)
continue;
manualListModel.insertRow(++currentRow);
manualListModel.setData(manualListModel.index(currentRow), (*i).c_str());
// 对于新开局
if (chess.getCmdList()->size() <= 1) {
manualListModel.removeRows(0, manualListModel.rowCount());
manualListModel.insertRow(0);
manualListModel.setData(manualListModel.index(0), chess.getCmdLine());
currentRow = 0;
}
// 对于当前局
else {
currentRow = manualListModel.rowCount() - 1;
// 跳过已添加行,迭代器不支持+运算符,只能一个个++
auto i = (chess.getCmdList()->begin());
for (int r = 0; i != (chess.getCmdList())->end(); i++) {
if (r++ > currentRow)
break;
}
// 将新增的棋谱行插入到ListModel
while (i != chess.getCmdList()->end()) {
manualListModel.insertRow(++currentRow);
manualListModel.setData(manualListModel.index(currentRow), (*i++).c_str());
}
}
// 播放胜利或失败音效
@ -617,10 +735,10 @@ bool GameController::command(const QString &cmd, bool update /*= true*/)
}
// 浏览历史局面通过command函数刷新局面显示
bool GameController::phaseChange(int row)
bool GameController::phaseChange(int row, bool forceUpdate)
{
// 如果row是当前浏览的棋谱行则不需要刷新
if (currentRow == row)
if (currentRow == row && !forceUpdate)
return false;
// 需要刷新
@ -778,8 +896,11 @@ bool GameController::updateScence(NineChess &chess)
int ipos = chess.getCurrentPos();
if (ipos) {
key = board[chess.getCurrentPos()];
currentPiece = pieceList.at(key & 0x10 ? (key - 0x11)*2 : (key - 0x21)*2 + 1);
currentPiece->setSelected(true);
ipos = key & 0x10 ? (key - 0x11) * 2 : (key - 0x21) * 2 + 1;
if (ipos >= 0 && ipos < n) {
currentPiece = pieceList.at(ipos);
currentPiece->setSelected(true);
}
}
animationGroup->start(QAbstractAnimation::DeleteWhenStopped);

View File

@ -83,7 +83,7 @@ public slots:
// 棋谱的命令行执行
bool command(const QString &cmd, bool update = true);
// 历史局面及局面改变
bool phaseChange(int row);
bool phaseChange(int row, bool forceUpdate = false);
// 更新棋局显示,每步后执行才能刷新局面
bool updateScence();
bool updateScence(NineChess &chess);

View File

@ -11,6 +11,7 @@
#define MANUALLISTVIEW
#include <QListView>
#include <QMouseEvent>
#include <QDebug>
class ManualListView : public QListView
@ -18,7 +19,7 @@ class ManualListView : public QListView
Q_OBJECT
public:
ManualListView(QWidget * parent = nullptr) : QListView (parent) {
ManualListView(QWidget * parent = nullptr) : QListView (parent), newEmptyRow(false) {
Q_UNUSED(parent)
}
QSize sizeHint() const {
@ -34,7 +35,14 @@ signals:
protected slots:
// 屏蔽掉双击编辑功能
void mouseDoubleClickEvent(QMouseEvent *event) { Q_UNUSED(event) }
void mouseDoubleClickEvent(QMouseEvent *mouseEvent) {
//屏蔽双击事件
mouseEvent->accept();
}
void rowsInserted(const QModelIndex &parent, int start, int end) {
newEmptyRow = true;
}
/* 本来重载rowsInserted函数用于在插入新行后自动选中最后一行
Model的insertRow执行后rowsInserted会被立即执行
@ -58,9 +66,10 @@ protected slots:
if (model()) {
// 判断
QModelIndex index = model()->index(model()->rowCount() - 1, 0);
if (index == bottomRight) {
if (index == bottomRight && newEmptyRow) {
setCurrentIndex(index);
scrollToBottom();
QAbstractItemView::scrollToBottom();
newEmptyRow = false;
}
}
}
@ -71,6 +80,10 @@ protected slots:
QListView::currentChanged(current, previous);
emit currentChangedSignal(current, previous);
}
private:
// 添加了新空行的标识
bool newEmptyRow;
};
#endif // MANUALLISTVIEW

View File

@ -566,7 +566,7 @@ bool NineChess::place(int c, int p, long time_p /* = -1*/)
board[pos] = piece;
move_ = pos;
player_ms = update(time_p);
sprintf(cmdline, "(%1u,%1u) %02u:%02u.%03u", c, p, player_ms / 60000, player_ms / 1000, player_ms % 1000);
sprintf(cmdline, "(%1u,%1u) %02u:%02u.%03u", c, p, player_ms / 60000, (player_ms % 60000) / 1000, player_ms % 1000);
cmdlist.push_back(string(cmdline));
currentPos = pos;
data.step++;
@ -636,7 +636,7 @@ bool NineChess::place(int c, int p, long time_p /* = -1*/)
move_ = (currentPos << 8) + pos;
player_ms = update(time_p);
sprintf(cmdline, "(%1u,%1u)->(%1u,%1u) %02u:%02u.%03u", currentPos / SEAT, currentPos % SEAT + 1,
c, p, player_ms / 60000, player_ms / 1000, player_ms % 1000);
c, p, player_ms / 60000, (player_ms % 60000) / 1000, player_ms % 1000);
cmdlist.push_back(string(cmdline));
board[pos] = board[currentPos];
board[currentPos] = '\x00';
@ -707,7 +707,7 @@ bool NineChess::capture(int c, int p, long time_p /* = -1*/)
data.player1_Remain--;
move_ = -pos;
player_ms = update(time_p);
sprintf(cmdline, "-(%1u,%1u) %02u:%02u.%03u", c, p, player_ms / 60000, player_ms / 1000, player_ms % 1000);
sprintf(cmdline, "-(%1u,%1u) %02u:%02u.%03u", c, p, player_ms / 60000, (player_ms % 60000) / 1000, player_ms % 1000);
cmdlist.push_back(string(cmdline));
currentPos = 0;
data.num_NeedRemove--;
@ -1622,10 +1622,12 @@ void NineChess::mirror(bool cmdChange /*= true*/)
move_ = (p1 << 8) | p2;
}
i = currentPos / SEAT;
j = currentPos % SEAT;
j = (SEAT - j) % SEAT;
currentPos = i * SEAT + j;
if (currentPos != 0) {
i = currentPos / SEAT;
j = currentPos % SEAT;
j = (SEAT - j) % SEAT;
currentPos = i * SEAT + j;
}
if (rule.canRepeated) {
for (auto mill = data.millList.begin(); mill != data.millList.end(); mill++) {
@ -1655,7 +1657,56 @@ void NineChess::mirror(bool cmdChange /*= true*/)
// 命令行解析
if (cmdChange) {
;
int c1, p1, c2, p2;
int args = 0;
int mm = 0, ss = 0, mss = 0;
long tm = -1;
args = sscanf(cmdline, "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
if (args >= 4) {
p1 = (SEAT - p1 + 1) % SEAT;
p2 = (SEAT - p2 + 1) % SEAT;
cmdline[3] = '1' + (char)p1;
cmdline[10] = '1' + (char)p2;
}
else {
args = sscanf(cmdline, "-(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
p1 = (SEAT - p1 + 1) % SEAT;
cmdline[4] = '1' + (char)p1;
}
else {
args = sscanf(cmdline, "(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
p1 = (SEAT - p1 + 1) % SEAT;
cmdline[3] = '1' + (char)p1;
}
}
}
for (auto itor = cmdlist.begin(); itor != cmdlist.end(); itor++) {
args = sscanf((*itor).c_str(), "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
if (args >= 4) {
p1 = (SEAT - p1 + 1) % SEAT;
p2 = (SEAT - p2 + 1) % SEAT;
(*itor)[3] = '1' + (char)p1;
(*itor)[10] = '1' + (char)p2;
}
else {
args = sscanf((*itor).c_str(), "-(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
p1 = (SEAT - p1 + 1) % SEAT;
(*itor)[4] = '1' + (char)p1;
}
else {
args = sscanf((*itor).c_str(), "(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
p1 = (SEAT - p1 + 1) % SEAT;
(*itor)[3] = '1' + (char)p1;
}
}
}
}
}
}
@ -1700,13 +1751,15 @@ void NineChess::turn(bool cmdChange /*= true*/)
move_ = (p1 << 8) | p2;
}
i = currentPos / SEAT;
j = currentPos % SEAT;
if (i == 1)
i = RING;
else if (i == RING)
i = 1;
currentPos = i * SEAT + j;
if (currentPos != 0) {
i = currentPos / SEAT;
j = currentPos % SEAT;
if (i == 1)
i = RING;
else if (i == RING)
i = 1;
currentPos = i * SEAT + j;
}
if (rule.canRepeated) {
for (auto mill = data.millList.begin(); mill != data.millList.end(); mill++) {
@ -1745,7 +1798,80 @@ void NineChess::turn(bool cmdChange /*= true*/)
// 命令行解析
if (cmdChange) {
;
int c1, p1, c2, p2;
int args = 0;
int mm = 0, ss = 0, mss = 0;
long tm = -1;
args = sscanf(cmdline, "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
if (args >= 4) {
if (c1 == 1)
c1 = RING;
else if (c1 == RING)
c1 = 1;
if (c2 == 1)
c2 = RING;
else if (c2 == RING)
c2 = 1;
cmdline[1] = '0' + (char)c1;
cmdline[8] = '0' + (char)c2;
}
else {
args = sscanf(cmdline, "-(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
if (c1 == 1)
c1 = RING;
else if (c1 == RING)
c1 = 1;
cmdline[2] = '0' + (char)c1;
}
else {
args = sscanf(cmdline, "(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
if (c1 == 1)
c1 = RING;
else if (c1 == RING)
c1 = 1;
cmdline[1] = '0' + (char)c1;
}
}
}
for (auto itor = cmdlist.begin(); itor != cmdlist.end(); itor++) {
args = sscanf((*itor).c_str(), "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
if (args >= 4) {
if (c1 == 1)
c1 = RING;
else if (c1 == RING)
c1 = 1;
if (c2 == 1)
c2 = RING;
else if (c2 == RING)
c2 = 1;
(*itor)[1] = '0' + (char)c1;
(*itor)[8] = '0' + (char)c2;
}
else {
args = sscanf((*itor).c_str(), "-(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
if (c1 == 1)
c1 = RING;
else if (c1 == RING)
c1 = 1;
(*itor)[2] = '0' + (char)c1;
}
else {
args = sscanf((*itor).c_str(), "(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
if (c1 == 1)
c1 = RING;
else if (c1 == RING)
c1 = 1;
(*itor)[1] = '0' + (char)c1;
}
}
}
}
}
}
@ -1756,28 +1882,53 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
if (degrees < 0)
degrees += 360;
if (degrees != 90 || degrees != 180 || degrees != 270)
if (degrees == 0 || degrees % 90)
return;
else
degrees /= 45;
char ch;
char ch1, ch2;
int i, j;
for (i = 0; i < SEAT; i++) {
ch = board[SEAT + i];
board[SEAT + i] = board[SEAT*RING + i];
board[SEAT*RING + i] = ch;
if (degrees == 2) {
for (i = 1; i <= RING; i++) {
ch1 = board[i*SEAT];
ch2 = board[i*SEAT + 1];
for (j = 0; j < SEAT - 2; j++) {
board[i*SEAT + j] = board[i*SEAT + j + 2];
}
board[i*SEAT + 6] = ch1;
board[i*SEAT + 7] = ch2;
}
}
else if (degrees == 6) {
for (i = 1; i <= RING; i++) {
ch1 = board[i*SEAT + 7];
ch2 = board[i*SEAT + 6];
for (j = SEAT - 1; j >= 2 ; j--) {
board[i*SEAT + j] = board[i*SEAT + j - 2];
}
board[i*SEAT + 1] = ch1;
board[i*SEAT] = ch2;
}
}
else if (degrees == 4) {
for (i = 1; i <= RING; i++) {
for (j = 0; j < SEAT / 2; j++) {
ch1 = board[i*SEAT + j];
board[i*SEAT + j] = board[i*SEAT + j + 4];
board[i*SEAT + j + 4] = ch1;
}
}
}
else
return;
int16_t p1, p2, p3;
if (move_ < 0) {
i = (-move_) / SEAT;
j = (-move_) % SEAT;
if (i == 1)
i = RING;
else if (i == RING)
i = 1;
j = (j + SEAT - degrees) % SEAT;
move_ = -(i * SEAT + j);
}
else {
@ -1785,28 +1936,21 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
p2 = move_ & 0x00ff;
i = p1 / SEAT;
j = p1 % SEAT;
if (i == 1)
i = RING;
else if (i == RING)
i = 1;
j = (j + SEAT - degrees) % SEAT;
p1 = i * SEAT + j;
i = p2 / SEAT;
j = p2 % SEAT;
if (i == 1)
i = RING;
else if (i == RING)
i = 1;
j = (j + SEAT - degrees) % SEAT;
p2 = i * SEAT + j;
move_ = (p1 << 8) | p2;
}
i = currentPos / SEAT;
j = currentPos % SEAT;
if (i == 1)
i = RING;
else if (i == RING)
i = 1;
currentPos = i * SEAT + j;
if (currentPos != 0) {
i = currentPos / SEAT;
j = currentPos % SEAT;
j = (j + SEAT - degrees) % SEAT;
currentPos = i * SEAT + j;
}
if (rule.canRepeated) {
for (auto mill = data.millList.begin(); mill != data.millList.end(); mill++) {
@ -1816,26 +1960,17 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
i = p1 / SEAT;
j = p1 % SEAT;
if (i == 1)
i = RING;
else if (i == RING)
i = 1;
j = (j + SEAT - degrees) % SEAT;
p1 = i * SEAT + j;
i = p2 / SEAT;
j = p2 % SEAT;
if (i == 1)
i = RING;
else if (i == RING)
i = 1;
j = (j + SEAT - degrees) % SEAT;
p2 = i * SEAT + j;
i = p3 / SEAT;
j = p3 % SEAT;
if (i == 1)
i = RING;
else if (i == RING)
i = 1;
j = (j + SEAT - degrees) % SEAT;
p3 = i * SEAT + j;
*mill &= 0xffffff00ff00ff00;
@ -1845,6 +1980,55 @@ void NineChess::rotate(int degrees, bool cmdChange /*= true*/)
// 命令行解析
if (cmdChange) {
;
int c1, p1, c2, p2;
int args = 0;
int mm = 0, ss = 0, mss = 0;
long tm = -1;
args = sscanf(cmdline, "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
if (args >= 4) {
p1 = (p1 - 1 + SEAT - degrees) % SEAT;
p2 = (p2 - 1 + SEAT - degrees) % SEAT;
cmdline[3] = '1' + (char)p1;
cmdline[10] = '1' + (char)p2;
}
else {
args = sscanf(cmdline, "-(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
p1 = (p1 - 1 + SEAT - degrees) % SEAT;
cmdline[4] = '1' + (char)p1;
}
else {
args = sscanf(cmdline, "(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
p1 = (p1 - 1 + SEAT - degrees) % SEAT;
cmdline[3] = '1' + (char)p1;
}
}
}
for (auto itor = cmdlist.begin(); itor != cmdlist.end(); itor++) {
args = sscanf((*itor).c_str(), "(%1u,%1u)->(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &c2, &p2, &mm, &ss, &mss);
if (args >= 4) {
p1 = (p1 - 1 + SEAT - degrees) % SEAT;
p2 = (p2 - 1 + SEAT - degrees) % SEAT;
(*itor)[3] = '1' + (char)p1;
(*itor)[10] = '1' + (char)p2;
}
else {
args = sscanf((*itor).c_str(), "-(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
p1 = (p1 - 1 + SEAT - degrees) % SEAT;
(*itor)[4] = '1' + (char)p1;
}
else {
args = sscanf((*itor).c_str(), "(%1u,%1u) %2u:%2u.%3u", &c1, &p1, &mm, &ss, &mss);
if (args >= 2) {
p1 = (p1 - 1 + SEAT - degrees) % SEAT;
(*itor)[3] = '1' + (char)p1;
}
}
}
}
}
}

View File

@ -237,7 +237,7 @@ public:
void mirror(bool cmdChange = true);
// 局面内外翻转
void turn(bool cmdChange = true);
// 局面时针旋转
// 局面时针旋转
void rotate(int degrees, bool cmdChange = true);
protected:

View File

@ -45,25 +45,25 @@ r3 s000 t00
(2,5)->(2,6) 00:37.406
(3,7)->(3,8) 00:58.193
(3,5)->(2,5) 00:39.694
(3,8)->(3,7) 01:61.938
(3,8)->(3,7) 01:01.938
(1,5)->(1,4) 00:41.361
(3,7)->(3,8) 01:63.645
(3,7)->(3,8) 01:03.645
(2,3)->(2,4) 00:43.490
-(3,2) 00:46.140
(3,3)->(3,2) 01:70.759
(3,3)->(3,2) 01:10.759
-(1,4) 01:72.136
(2,2)->(2,3) 00:47.966
(3,2)->(3,3) 01:73.383
(3,2)->(3,3) 01:13.383
(2,3)->(2,2) 00:50.108
(3,1)->(3,2) 01:75.424
-(2,2) 01:76.448
(3,1)->(3,2) 01:15.424
-(2,2) 01:16.448
(2,4)->(2,3) 00:55.468
(3,8)->(3,1) 01:78.611
(3,8)->(3,1) 01:18.611
(2,3)->(2,2) 00:57.257
-(3,1) 00:58.015
(3,3)->(2,3) 01:84.964
(3,3)->(2,3) 01:24.964
(2,8)->(2,7) 00:59.896
(2,3)->(3,3) 01:86.208
(2,1)->(2,8) 01:61.493
-(3,2) 01:62.658
(2,3)->(3,3) 01:26.208
(2,1)->(2,8) 01:01.493
-(3,2) 01:02.658
Player2 win!