📄 boardhandler.cpp
字号:
{ remember = m->parent; // Remember son of parent if its not the move to be deleted. // Then check for the brothers and fix the pointer connections, if we // delete a node with brothers. (It gets ugly now...) // YUCK! I hope this works. if (remember->son == m) // This son is our move to be deleted? { if (remember->son->brother != NULL) // This son has a brother? remSon = remember->son->brother; // Reset pointer } else // No, the son is not our move { remSon = remember->son; Move *tmp = remSon, *oldTmp = tmp; do { // Loop through all brothers until we find our move if (tmp == m) { if (m->brother != NULL) // Our move has a brother? oldTmp->brother = m->brother; // Then set the previous move brother else // to brother of our move oldTmp->brother = NULL; // No brother found. break; } oldTmp = tmp; } while ((tmp = tmp->brother) != NULL); } } else if (tree->hasPrevBrother()) { remember = tree->previousVariation(); if (m->brother != NULL) remember->brother = m->brother; else remember->brother = NULL; } else if (tree->hasNextBrother()) { remember = tree->nextVariation(); // Urgs, remember is now root. tree->setRoot(remember); } else { // Oops, first and only move. We delete everything tree->init(board->getBoardSize()); board->hideAllStones(); board->hideAllMarks(); board->updateCanvas(); lastValidMove = NULL; stoneHandler->clearData(); updateMove(tree->getCurrent()); return; } if (m->son != NULL) Tree::traverseClear(m->son); // Traverse the tree after our move (to avoid brothers) delete m; // Delete our move tree->setCurrent(remember); // Set current move to previous move remember->son = remSon; // Reset son pointer remember->marker = NULL; // Forget marker updateMove(tree->getCurrent(), !display_incoming_move); board->setModified();}// TODO: Merge with deleteNode() abovevoid BoardHandler::cutNode(){ CHECK_PTR(tree); Move *m = tree->getCurrent(), *remember = NULL, *remSon = NULL; CHECK_PTR(m); if (m->parent != NULL) { remember = m->parent; // Remember son of parent if its not the move to be deleted. // Then check for the brothers and fix the pointer connections, if we // delete a node with brothers. (It gets ugly now...) // YUCK! I hope this works. if (remember->son == m) // This son is our move to be deleted? { if (remember->son->brother != NULL) // This son has a brother? remSon = remember->son->brother; // Reset pointer } else // No, the son is not our move { remSon = remember->son; Move *tmp = remSon, *oldTmp = tmp; do { // Loop through all brothers until we find our move if (tmp == m) { if (m->brother != NULL) // Our move has a brother? oldTmp->brother = m->brother; // Then set the previous move brother else // to brother of our move oldTmp->brother = NULL; // No brother found. break; } oldTmp = tmp; } while ((tmp = tmp->brother) != NULL); } } else if (tree->hasPrevBrother()) { remember = tree->previousVariation(); if (m->brother != NULL) remember->brother = m->brother; else remember->brother = NULL; } else if (tree->hasNextBrother()) { remember = tree->nextVariation(); // Urgs, remember is now root. tree->setRoot(remember); } else { // Oops, first and only move. clipboardNode = m; tree->setRoot(new Move(board->getBoardSize())); tree->setCurrent(tree->getRoot()); lastValidMove = NULL; stoneHandler->clearData(); updateMove(tree->getCurrent()); board->getInterfaceHandler()->setClipboard(true); return; } delete clipboardNode; clipboardNode = m; // Remember this node clipboardNode->brother = NULL; // But without brother clipboardNode->marker = NULL; // And without marker tree->setCurrent(remember); // Set current move to previous move remember->son = remSon; // Reset son pointer remember->marker = NULL; // Forget marker updateMove(tree->getCurrent()); board->getInterfaceHandler()->setClipboard(true); board->setModified();}void BoardHandler::pasteNode(bool brother){ if (clipboardNode == NULL) return; Move *m = tree->getCurrent(); CHECK_PTR(m); // Paste as brother if (brother) { while (m->brother != NULL) m = m->brother; clipboardNode->parent = m->parent; m->brother = clipboardNode; } // Paste as son else { if (m->son != NULL) // Current move already has a son { m = m->son; while (m->brother != NULL) m = m->brother; clipboardNode->parent = m->parent; m->brother = clipboardNode; } else { clipboardNode->parent = m; m->son = clipboardNode; } } tree->setCurrent(clipboardNode); clipboardNode = NULL; updateMove(tree->getCurrent()); board->getInterfaceHandler()->setClipboard(false); board->setModified();}void BoardHandler::clearNode(bool brother){ // Matrix *mat = new Matrix(board->getBoardSize()); // CHECK_PTR(mat); Matrix mat(board->getBoardSize()); createNode(mat, brother);}void BoardHandler::duplicateNode(){ // Matrix *mat = tree->getCurrent()->getMatrix(); // CHECK_PTR(mat); Matrix mat(*(tree->getCurrent()->getMatrix())); createNode(mat, true);}void BoardHandler::createNode(const Matrix &mat, bool brother, bool setEditMode){ if (setEditMode) board->getInterfaceHandler()->setEditMode(); Move *m = new Move(stoneNone, -1, -1, currentMove, modeEdit, mat); CHECK_PTR(m); // Remove all marks from this new move. board->hideAllMarks(); board->removeLastMoveMark(); bool res = false; if (brother) res = tree->addBrother(m); else res = tree->addSon(m); if (res && setting->readIntEntry("VAR_GHOSTS") && getNumBrothers()) updateVariationGhosts(); lastValidMove = m; int brothers = getNumBrothers(); // Update the ghosts indicating variations if (brothers && setting->readIntEntry("VAR_GHOSTS")) updateVariationGhosts(); board->getInterfaceHandler()->showEditGroup(); board->getInterfaceHandler()->clearComment(); board->getInterfaceHandler()->setMoveData(currentMove, getBlackTurn(), brothers, getNumSons(), hasParent(), hasPrevBrother(), hasNextBrother()); stoneHandler->updateAll(tree->getCurrent()->getMatrix()); board->updateCanvas(); board->setModified();}bool BoardHandler::swapVariations(){ if (gameMode == modeScore) return false; CHECK_PTR(tree); Move *m = tree->getCurrent(), *parent = NULL, *prev = NULL, *next = NULL, *newSon = NULL; if (!tree->hasPrevBrother()) { qWarning(" *** BoardHandler::swapVariations() - No prev brother. Aborting... ***"); return false; } parent = m->parent; prev = tree->previousVariation(); next = m->brother; // Check if our move has further prev-prev nodes. If yes, we don't change parents son if (!tree->hasPrevBrother(prev)) newSon = m; else tree->previousVariation()->brother = m; // Do the swap m->brother = prev; prev->brother = next; if (newSon != NULL) { if (parent != NULL) parent->son = m; else tree->setRoot(m); } tree->setCurrent(m); updateMove(m); return true;}void BoardHandler::doPass(bool sgf){ if (lastValidMove == NULL) { stoneHandler->checkAllPositions(); } StoneColor c = getBlackTurn() ? stoneBlack : stoneWhite; currentMove++; if (setting->readIntEntry("VAR_GHOSTS") && !sgf) board->removeGhosts(); if (!sgf) addMove(c, 20, 20); else // Sgf reading { if (hasParent()) c = tree->getCurrent()->parent->getColor() == stoneBlack ? stoneWhite : stoneBlack; else c = stoneBlack; if (!board->fastLoad) editMove(c, 20, 20); } if (hasParent()) tree->getCurrent()->setCaptures(tree->getCurrent()->parent->getCapturesBlack(), tree->getCurrent()->parent->getCapturesWhite()); if (!sgf) { board->getInterfaceHandler()->setMoveData(currentMove, getBlackTurn(), getNumBrothers(), getNumSons(), hasParent(), hasPrevBrother(), hasNextBrother(), 20, 20); if (board->get_isLocalGame()) board->getInterfaceHandler()->clearComment(); board->updateLastMove(c, 20, 20); board->updateCanvas(); } board->setModified();}#ifndef NO_DEBUGvoid BoardHandler::debug(){ if (tree->getCurrent()->getMatrix() == NULL) qWarning("CURRENT MATRIX IS NULL"); else { qDebug("X = %d, Y = %d, MODE = %d", tree->getCurrent()->getX(), tree->getCurrent()->getY(), tree->getCurrent()->getGameMode()); qDebug("CAPTURES Black: %d White: %d", tree->getCurrent()->getCapturesBlack(), tree->getCurrent()->getCapturesWhite()); tree->getCurrent()->getMatrix()->debug(); }}#endifbool BoardHandler::getBlackTurn(){ if (tree->getCurrent()->getPLinfo()) // color of next stone is same as current return tree->getCurrent()->getPLnextMove() == stoneBlack; if (currentMove == 0) { // Handicap, so white starts if (gameData->handicap >= 2) return false; return true; } // Normal mode if (tree->getCurrent()->getGameMode() == modeNormal || tree->getCurrent()->getGameMode() == modeObserve || tree->getCurrent()->getGameMode() == modeMatch || tree->getCurrent()->getGameMode() == modeTeach || tree->getCurrent()->getGameMode() == modeComputer) { // change color return tree->getCurrent()->getColor() == stoneWhite; } // Edit mode. Return color of parent move. else if (tree->getCurrent()->parent != NULL) return tree->getCurrent()->parent->getColor() == stoneWhite; // Crap happened. 50% chance this is correct .) qWarning("Oops, crap happened in BoardHandler::getBlackTurn() !"); return true;}bool BoardHandler::loadSGF(const QString &fileName, const QString &filter, bool fastLoad){ // Load the sgf file if (!sgfParser->parse(fileName, filter, fastLoad)) return false; prepareBoard(); return true;}bool BoardHandler::openComputerSession(QNewGameDlg *dlg,const QString &fileName, const QString &filter,const QString &computer_path) //added eb 12{ // now we start the dialog gtp = new QGtp() ; if (gtp->openGtpSession(computer_path,dlg->getSize(),dlg->getKomi(),dlg->getHandicap(),dlg->getLevelBlack())==FAIL) { // if gnugo fails// QString mesg = QString(QObject::tr("Error opening program: %1\n")).arg(gtp->getLastMessage()); QMessageBox msg(QObject::tr("Error"), //mesg, QString(QObject::tr("Error opening program: %1")).arg(gtp->getLastMessage()), QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Default, QMessageBox::NoButton, QMessageBox::NoButton); msg.setActiveWindow(); msg.raise(); msg.exec(); return false ; } //if (dlg->getHandicap()) // setHandicap(dlg->getHandicap()); if (!(fileName.isNull() || fileName.isEmpty())) if (!sgfParser->parse(fileName, filter, false)) return false; else gtp->loadsgf(fileName); prepareComputerBoard(); return true;} //end add eb 12bool BoardHandler::saveBoard(const QString &fileName){ CHECK_PTR(tree); return sgfParser->doWrite(fileName, tree);}void BoardHandler::updateComment(QString text){ if (tree->getCurrent() == NULL) return; QString comment; if (board->get_isLocalGame()) { // local game: comment field is input field containing only string of current node if (!text) comment = board->getInterfaceHandler()->getComment(); else return; } else { // online game: comment field shows all kibitzes since the beginning if (!text) return; else if (!text.contains('\n')) { comment = tree->getCurrent()->getComment(); if (comment) comment += '\n'; comment += text; } // show current line board->getInterfaceHandler()->displayComment(text); } tree->getCurrent()->setComment(comment);}void BoardHandler::editMark(int x, int y, MarkType t, const QString &txt){ CHECK_PTR(tree->getCurrent()->getMatrix()); if (t == markNone) tree->getCurrent()->getMatrix()->removeMark(x, y); else tree->getCurrent()->getMatrix()->insertMark(x, y, t); if ((t == markText || t == markNumber) && !txt.isNull() && !txt.isEmpty()) tree->getCurrent()->getMatrix()->setMarkText(x, y, txt); board->setModified();}void BoardHandler::updateCurrentMatrix(StoneColor c, int x, int y){ // Passing? if (x == 20 && y == 20) return; if (x < 1 || x > board->getBoardSize() || y < 1 || y > board->getBoardSize()) { qWarning(" *** BoardHandler::updateCurrentMatrix() - Invalid move given: %d/%d at move %d ***", x, y, tree->getCurrent()->getMoveNumber()); return; } CHECK_PTR(tree->getCurrent()->getMatrix()); if (c == stoneNone) tree->getCurrent()->getMatrix()->removeStone(x, y); else if (c == stoneErase) tree->getCurrent()->getMatrix()->eraseStone(x, y); else tree->getCurrent()->getMatrix()->insertStone(x, y, c, gameMode);}void BoardHandler::exportASCII(){ TextView dlg(board, "textview", true); dlg.setMatrix(tree->getCurrent()->getMatrix(), setting->charset); dlg.exec();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -