📄 boardhandler.cpp
字号:
/** boardhandler.cpp*/#include "qgo.h"#include "boardhandler.h"#include "stonehandler.h"#include "stone.h"#include "board.h"#include "sgfparser.h"#include "move.h"#include "interfacehandler.h"#include "matrix.h"#include "textview.h"#include "normaltools_gui.h"#include "setting.h"#include "qnewgamedlg.h"#include <qapplication.h>#include <qclipboard.h> #include <qlabel.h>#include <qmessagebox.h>#include <qptrstack.h>#define MARK_TERRITORY_VISITED 99#define MARK_TERRITORY_DAME 999#define MARK_SEKI 10class Setting;BoardHandler::BoardHandler(Board *b): board(b){ CHECK_PTR(board); // Create a StoneHandler instance stoneHandler = new StoneHandler(this); CHECK_PTR(stoneHandler); // Create a SGFParser instance sgfParser = new SGFParser(this); CHECK_PTR(sgfParser); // Create a variation tree tree = new Tree(board->getBoardSize()); CHECK_PTR(tree); currentMove = 0; lastValidMove = NULL; gameMode = modeNormal; markType = markNone; capturesBlack = capturesWhite = 0; markedDead = false; // Set game data to default gameData = new GameData(); clipboardNode = NULL; nodeResults = NULL; gtp = NULL; // Assume we display events (incoming move when observing) display_incoming_move = true ; local_stone_sound = setting->readBoolEntry("SOUND_STONE");}BoardHandler::~BoardHandler(){ delete stoneHandler; delete sgfParser; if (clipboardNode != NULL) Tree::traverseClear(clipboardNode); delete tree;// delete gameData; if (nodeResults) delete nodeResults; if (gtp) delete gtp;}void BoardHandler::clearData(){ tree->init(board->getBoardSize()); lastValidMove = NULL; currentMove = 0; gameMode = modeNormal; markType = markNone; stoneHandler->clearData(); board->getInterfaceHandler()->clearData(); capturesBlack = capturesWhite = 0; markedDead = false; if (nodeResults != NULL) nodeResults->clear();}void BoardHandler::prepareBoard(){ // Clear up trash and reset the board to move 0 stoneHandler->clearData(); currentMove = 0; tree->setToFirstMove(); if (tree->getCurrent() == NULL) qFatal(" *** Oops! Bad things happened reading the sgf file! ***"); gameMode = modeNormal; markType = markNone; board->hideAllMarks(); updateMove(tree->getCurrent()); board->getInterfaceHandler()->setSliderMax(tree->mainBranchSize()-1); lastValidMove = NULL;}void BoardHandler::prepareComputerBoard() //added eb 12{ gameMode = modeComputer; tree->setCurrent(tree->findLastMoveInMainBranch()); updateMove(tree->getCurrent()); board->getInterfaceHandler()->setSliderMax(tree->mainBranchSize()-1); lastValidMove = tree->getCurrent(); board->getInterfaceHandler()->disableToolbarButtons(); stoneHandler->checkAllPositions();} //end add eb 12void BoardHandler::setMode(GameMode mode){ // Leaving score mode if (gameMode == modeScore && mode != modeScore) leaveScoreMode(); gameMode = mode;}void BoardHandler::initGame(GameData *d, bool sgf){ CHECK_PTR(d); // delete gameData; gameData = new GameData(d); // We have handicap? Then add the necessary stones. // Dont do this when reading sgfs, as they add those stones // with AB. if (d->handicap > 0 && !sgf) { setHandicap(d->handicap); stoneHandler->checkAllPositions(); } board->getInterfaceHandler()->normalTools->komi->setText(QString::number(d->komi)); board->getInterfaceHandler()->normalTools->handicap->setText(QString::number(d->handicap)); if (d->byoTime >= 0 && d->byoTime < 10000) { if (gameMode == modeNormal) { if (d->timeSystem == canadian) board->getInterfaceHandler()->normalTools->byoyomi->setText(QString::number(d->byoTime/60) + "/" + QString::number(d->byoStones)); else if (d->timeSystem == byoyomi) board->getInterfaceHandler()->normalTools->byoyomi->setText(QString::number(d->byoPeriods) + "x" + QString::number(d->byoTime) + "s"); else board->getInterfaceHandler()->normalTools->byoyomi->setText("0"); } else board->getInterfaceHandler()->normalTools->byoyomi->setText(QString::number(d->byoTime)); } else { board->getInterfaceHandler()->normalTools->byoyomi->setText("-"); board->getInterfaceHandler()->normalTools->TextLabel_free->setText("-"); return; } if (d->freegame == FREE) board->getInterfaceHandler()->normalTools->TextLabel_free->setText(QApplication::tr("free")); else if (d->freegame == RATED) board->getInterfaceHandler()->normalTools->TextLabel_free->setText(QApplication::tr("rated")); else board->getInterfaceHandler()->normalTools->TextLabel_free->setText(QApplication::tr("teach"));}int BoardHandler::hasStone(int x, int y){ return stoneHandler->hasStone(x, y);}void BoardHandler::addStone(StoneColor c, int x, int y, bool sound){ bool shown = false; // TODO DEBUG#ifndef NO_DEBUG if (gameMode == modeScore) qWarning("addStone in score mode ???? - Something went wrong.");#endif if ((hasStone(x, y) == 1) && display_incoming_move) { // In edit mode, clicking on a present stone hides it. if (gameMode == modeEdit) { removeStone(x, y, true); // hide the stone board->getInterfaceHandler()->setMoveData(currentMove, getBlackTurn(), getNumBrothers(), getNumSons(), hasParent(), hasPrevBrother(), hasNextBrother()); board->updateCanvas(); } return; } Move *mr = tree->getCurrent(), //added eb 8 *remember = mr; // Remember current when we are browsing through an observing game CHECK_PTR(mr); bool do_not_show = false; if (tree->getCurrent() != NULL && lastValidMove != NULL && tree->getCurrent() != lastValidMove && gameMode == modeObserve) { do_not_show=true; tree->setCurrent(lastValidMove); currentMove = lastValidMove->getMoveNumber(); } //end add eb 8 if (display_incoming_move == do_not_show) //SL added eb 9 qDebug ("Pb : we are observing a game - display_incoming_move and do_not_show disagree"); if ((tree->getCurrent() != NULL && lastValidMove != NULL && tree->getCurrent() != lastValidMove) || (gameMode == modeNormal && tree->getCurrent()->getGameMode() == modeEdit) || lastValidMove == NULL) { stoneHandler->checkAllPositions(); } if (x < 1 || x > board->getBoardSize() || y < 1 || y > board->getBoardSize()) qWarning("BoardHandler::addStone() - Invalid position: %d/%d", x, y); Stone *s = board->addStoneSprite(c, x, y, shown); if (s == NULL) return; CHECK_PTR(s); // qDebug("Game Mode = %s", gameMode == modeNormal ? "NORMAL" : "EDIT"); // Remember captures from move before adding the stone capturesBlack = tree->getCurrent()->getCapturesBlack(); capturesWhite = tree->getCurrent()->getCapturesWhite(); // Normal mode, increase move counter and add the stone as new node if (gameMode == modeNormal || gameMode == modeObserve || gameMode == modeMatch || gameMode == modeTeach || gameMode == modeComputer) { currentMove++; if (setting->readIntEntry("VAR_GHOSTS")) board->removeGhosts(); addMove(c, x, y); if (sound && local_stone_sound) setting->qgo->playClick(); if (!do_not_show) board->updateLastMove(c,x,y); } // Edit mode... else if (gameMode == modeEdit) { // ...we are currently in a normal mode node, so add the edited version as variation, // but dont remove the marks. // If this is our root move in an -empty- tree, dont add a node, then we edit root. if (tree->getCurrent()->getGameMode() == modeNormal && // Its normal mode? !(tree->getCurrent() == tree->getRoot() && // Its root? tree->count() == 1)) // Its an empty tree? addMove(c,x,y, false); //SL add eb 8 // ...we are currently already in a node that was created in edit mode, so continue // editing this node and dont add a new variation. // If its root in an empty tree, and if its the first editing move, change move data. Else do nothing. else if (currentMove == 0 && tree->getCurrent()->getGameMode() != modeEdit) { tree->getCurrent()->setGameMode(modeEdit); editMove(c,x,y); //SL add eb 8 } } // If we are in edit mode, dont check for captures (sgf defines) // qDebug("CAP BLACK %d, CAP WHITE %d", capturesBlack, capturesWhite); stoneHandler->toggleWorking(true); updateCurrentMatrix(c, x, y); //SL added eb 8 -> moved here because we nned an updated matrix to check liberties in 'addstone' // if (!stoneHandler->addStone(s, !shown, gameMode == modeNormal || gameMode == modeObserve || gameMode == modeMatch || gameMode == modeTeach) &&/* * It might be advisable to process a CHECK_PTR on tree->getcurrent-> getmatrix * because we don't do it afterwards in addstone and beyond because it is so expensive ... */ // We want to check wether there was a stone of the same color 2 moves before // This check will be used at the next step bool koStone = false; if (currentMove > 1) koStone = ((StoneColor)tree->getCurrent()->parent->parent->getMatrix()->at(x-1, y-1) == c); if (!stoneHandler->addStone(s, !shown, gameMode == modeNormal || gameMode == modeObserve || gameMode == modeMatch || gameMode == modeTeach || gameMode == modeComputer, tree->getCurrent()->getMatrix(), koStone) && //SL add eb 8 (gameMode == modeNormal || gameMode == modeObserve || gameMode == modeMatch || gameMode == modeTeach || gameMode == modeComputer)) { // Suicide move QApplication::beep(); deleteNode(); stoneHandler->toggleWorking(false); return; } stoneHandler->toggleWorking(false); //updateCurrentMatrix(c, x, y); // Update captures tree->getCurrent()->setCaptures(capturesBlack, capturesWhite); /* qDebug("BoardHandler::addStone - setting captures to B %d, W %d", tree->getCurrent()->getCapturesBlack(), tree->getCurrent()->getCapturesWhite()); */ if (do_not_show) //added eb 8 { tree->setCurrent(remember); //s->hide(); stoneHandler->updateAll(remember->getMatrix());//SL added eb 10 } //end add eb 8 // Display data in GUI board->getInterfaceHandler()->setMoveData(currentMove, getBlackTurn(), getNumBrothers(), getNumSons(), hasParent(), hasPrevBrother(), hasNextBrother(), gameMode == modeNormal || gameMode == modeObserve || gameMode == modeMatch || gameMode == modeTeach || gameMode == modeComputer ? x : 0, gameMode == modeNormal || gameMode == modeObserve || gameMode == modeMatch || gameMode == modeTeach || gameMode == modeComputer ? y : 0); if (gameMode == modeNormal) board->getInterfaceHandler()->clearComment(); board->getInterfaceHandler()->setCaptures(capturesBlack, capturesWhite); board->updateCanvas(); board->setModified();}void BoardHandler::addStoneSGF(StoneColor c, int x, int y, bool new_node){ bool shown = false; /* qDebug("BoardHandler::addStoneSGF(StoneColor c, int x, int y) - %d %d/%d %d", c, x, y, gameMode); */ if (hasStone(x, y) == 1) { // In edit mode, this overwrites an existing stone with another color. // This is different to the normal interface, when reading sgf files. if (gameMode == modeEdit && tree->getCurrent() != NULL && tree->getCurrent()->getMatrix()->at(x-1, y-1) != c) { if (!stoneHandler->removeStone(x, y, true)) qWarning(" *** BoardHandler::addStoneSGF() Failed to remove stone! *** "); // updateCurrentMatrix(stoneNone, x, y); } } if ((tree->getCurrent()->parent != NULL && lastValidMove != NULL && gameMode == modeNormal && tree->getCurrent()->parent != lastValidMove) || (gameMode == modeNormal && tree->getCurrent()->parent->getGameMode() == modeEdit) || (gameData->handicap > 0 && currentMove == 1) || lastValidMove == NULL) stoneHandler->checkAllPositions(); if ((x < 1 || x > board->getBoardSize() || y < 1 || y > board->getBoardSize()) && x != 20 && y != 20) qWarning("BoardHandler::addStoneSGF() - Invalid position: %d/%d", x, y); Stone *s = board->addStoneSprite(c, x, y, shown); if (s == NULL) return; // qDebug("Game Mode = %s", gameMode == modeNormal ? "NORMAL" : "EDIT"); // Remember captures from move before adding the stone if (tree->getCurrent()->parent != NULL) { capturesBlack = tree->getCurrent()->parent->getCapturesBlack(); capturesWhite = tree->getCurrent()->parent->getCapturesWhite(); } else capturesBlack = capturesWhite = 0; if (gameMode == modeNormal || gameMode == modeObserve || gameMode == modeTeach) { currentMove++; // This is a hack to force the first move to be #1. For example, sgf2misc starts with move 0. if (currentMove == 1) tree->getCurrent()->setMoveNumber(currentMove); } else if(gameMode == modeEdit) tree->getCurrent()->setMoveNumber(0); if (new_node) { // Set move data editMove(s->getColor(), s->posX(), s->posY()); // Update move game mode if (gameMode != tree->getCurrent()->getGameMode()) tree->getCurrent()->setGameMode(gameMode); } // If we are in edit mode, dont check for captures (sgf defines) stoneHandler->toggleWorking(true); stoneHandler->addStone(s, !shown, gameMode == modeNormal, NULL); stoneHandler->toggleWorking(false); updateCurrentMatrix(c, x, y); // Update captures tree->getCurrent()->setCaptures(capturesBlack, capturesWhite); lastValidMove = tree->getCurrent();}bool BoardHandler::removeStone(int x, int y, bool hide, bool new_node){ // qDebug("BoardHandler::removeStone(int x, int y, bool hide)"); // TODO: DEBUG#ifndef NO_DEBUG if (gameMode != modeEdit) qFatal("OOPS");#endif bool res = stoneHandler->removeStone(x, y, hide); if (res) { if (tree->getCurrent()->getGameMode() == modeNormal && currentMove > 0) { if (new_node) // false, when reading sgf addMove(stoneNone, x, y); updateCurrentMatrix(stoneErase, x, y); } else updateCurrentMatrix(stoneErase, x, y); board->checkLastMoveMark(x, y); } board->setModified(); return res;}void BoardHandler::removeDeadStone(int x, int y){ stoneHandler->removeStone(x, y, true); updateCurrentMatrix(stoneNone, x, y);}void BoardHandler::addMove(StoneColor c, int x, int y, bool clearMarks){ // qDebug("BoardHandler::addMove - clearMarks = %d", clearMarks); Matrix *mat = tree->getCurrent()->getMatrix(); CHECK_PTR(mat); Move *m = new Move(c, x, y, currentMove, gameMode, *mat); CHECK_PTR(m); if (tree->hasSon(m)) { // qDebug("*** HAVE THIS SON ALREADY! ***"); delete m; return; } // Remove all marks from this new move. We dont do that when creating // a new variation in edit mode. if (clearMarks) { m->getMatrix()->clearAllMarks(); board->hideAllMarks(); } if (tree->addSon(m) && setting->readIntEntry("VAR_GHOSTS") && getNumBrothers()) updateVariationGhosts(); lastValidMove = m;}void BoardHandler::createMoveSGF(GameMode mode, bool brother){ // qDebug("BoardHandler::createMoveSGF() - %d", mode); Move *m; if (!board->fastLoad) { Matrix *mat = tree->getCurrent()->getMatrix(); m = new Move(stoneBlack, -1, -1, tree->getCurrent()->getMoveNumber()+1, mode, *mat); } else { m = new Move(stoneBlack, -1, -1, tree->getCurrent()->getMoveNumber()+1, mode); } if (!brother && tree->hasSon(m)) { // qDebug("*** HAVE THIS SON ALREADY! ***"); delete m; return; } if (!board->fastLoad && mode == modeNormal) m->getMatrix()->clearAllMarks(); if (!brother) tree->addSon(m); else tree->addBrother(m);}void BoardHandler::editMove(StoneColor c, int x, int y){ // qDebug("BoardHandler::editMove");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -