bool StoneHandler:: checkFalseEye(Matrix *m, int x, int y, int col) { int bsize = m->getSize(); // Stone to the North? if (y - 1 >= 0 && m->at(x, y - 1) == col) if (countLibertiesOnMatrix(assembleGroup(getStoneAt(x + 1, y),NULL), m) == 1) //SL added eb 8 return true; // Stone to the west? if (x - 1 >= 0 && m->at(x - 1, y) == col) //SL added eb 8 if (countLibertiesOnMatrix(assembleGroup(getStoneAt(x, y + 1),NULL), m) == 1) return true; // Stone to the south? if (y + 1 < bsize && m->at(x, y + 1) == col) if (countLibertiesOnMatrix(assembleGroup(getStoneAt(x + 1, y + 2),NULL), m) == 1) //SL added eb 8 return true; // Stone to the east? if (x + 1 < bsize && m->at(x + 1, y) == col) if (countLibertiesOnMatrix(assembleGroup(getStoneAt(x + 2, y + 1),NULL), m) == 1) //SL added eb 8 return true; return false; }
bool StoneHandler::markSekiGroup(int x, int y, int &caps, StoneColor &col, bool &seki) { if (hasStone(x, y) != 1) return false; Stone *s = getStoneAt(x, y); CHECK_PTR(s); col = s->getColor(); if (!s->isSeki()) seki = true; Group *g = assembleGroup(s, NULL); //SL added eb 8 CHECK_PTR(g); // Mark stones of this group as seki QListIterator<Stone *> it(*g); while (it.hasNext()) { Stone *s = it.next(); CHECK_PTR(s); if (seki && s->isDead()) caps ++; s->setSeki(seki); if (seki) { s->togglePixmap(boardHandler->board->getImageHandler()->getGhostPixmaps(), false); } else { s->togglePixmap(boardHandler->board->getImageHandler()->getStonePixmaps(), true); } } delete g; return true; }
bool StoneHandler::removeDeadGroup(int x, int y, int &caps, StoneColor &col, bool &dead) { if (hasStone(x, y) != 1) return false; Stone *s = getStoneAt(x, y); CHECK_PTR(s); col = s->getColor(); if (!s->isDead()) dead = true; Group *g = assembleGroup(s, NULL); //SL added eb 8 CHECK_PTR(g); caps = g->count(); // Mark stones of this group as dead or alive again QListIterator<Stone *> it(*g); while (it.hasNext()) { Stone *s = it.next(); CHECK_PTR(s); s->setDead(dead); if (dead) { s->togglePixmap(boardHandler->board->getImageHandler()->getGhostPixmaps(), false); } else { s->togglePixmap(boardHandler->board->getImageHandler()->getStonePixmaps(), true); } } delete g; return true; }
bool StoneHandler::markSekiGroup(int x, int y, int &caps, StoneColor &col, bool &seki) { if (hasStone(x, y) != 1) return false; Stone *s = getStoneAt(x, y); CHECK_PTR(s); col = s->getColor(); if (!s->isSeki()) seki = true; Group *g = assembleGroup(s, NULL); //SL added eb 8 CHECK_PTR(g); // Mark stones of this group as seki QListIterator<Stone> it(*g); for (; it.current(); ++it) { s = it.current(); CHECK_PTR(s); if (seki && s->isDead()) caps ++; s->setSeki(seki); if (seki) { s->setSequence(boardHandler->board->getImageHandler()->getGhostPixmaps()); s->shadow->hide(); } else { s->setSequence(boardHandler->board->getImageHandler()->getStonePixmaps()); s->shadow->show(); } } delete g; return true; }
bool StoneHandler::removeDeadGroup(int x, int y, int &caps, StoneColor &col, bool &dead) { if (hasStone(x, y) != 1) return false; Stone *s = getStoneAt(x, y); CHECK_PTR(s); col = s->getColor(); if (!s->isDead()) dead = true; Group *g = assembleGroup(s, NULL); //SL added eb 8 CHECK_PTR(g); caps = g->count(); // Mark stones of this group as dead or alive again QListIterator<Stone> it(*g); for (; it.current(); ++it) { s = it.current(); CHECK_PTR(s); s->setDead(dead); if (dead) { s->setSequence(boardHandler->board->getImageHandler()->getGhostPixmaps()); s->shadow->hide(); } else { s->setSequence(boardHandler->board->getImageHandler()->getStonePixmaps()); s->shadow->show(); } } delete g; return true; }
//bool StoneHandler::checkPosition(Stone *stone) bool StoneHandler::checkPosition(Stone *stone, Matrix *m, bool koStone) { //CHECK_PTR(stone); // CHECK_PTR(m); // SL added eb 8 if (!stone->isVisible()) return true; Group *active = NULL; // No groups existing? Create one. if (groups->isEmpty()) { Group *g = assembleGroup(stone,m); CHECK_PTR(g); groups->append(g); active = g; } // We already have one or more groups. else { bool flag = false; Group *tmp; for (unsigned int i=0; i<groups->count(); i++) { tmp = groups->at(i); //CHECK_PTR(tmp); // Check if the added stone is attached to an existing group. // If yes, update this group and replace the old one. // If the stone is attached to two groups, remove the second group. // This happens if the added stone connects two groups. if (tmp->isAttachedTo(stone)) { // Group attached to stone if (!flag) { if (!groups->remove(i)) qFatal("StoneHandler::checkPosition(Stone *stone):" "Oops, removing an attached group failed."); active = assembleGroup(stone,m); groups->insert(i, active); flag = true; } // Groups connected, remove one else { if (active != NULL && active == groups->at(i)) active = tmp; if (!groups->remove(i)) qFatal("StoneHandler::checkPosition(Stone *stone): " "Oops, removing a connected group failed."); i--; } } } // The added stone isnt attached to an existing group. Create a new group. if (!flag) { Group *g = assembleGroup(stone,m); CHECK_PTR(g); groups->append(g); active = g; } } // active->debug(); // Now we have to sort the active group as last in the groups QPtrList, // so if this one is out of liberties, we beep and abort the operation. // This prevents suicide moves. groups->append(groups->take(groups->findRef(active))); // Check the liberties of every group. If a group has zero liberties, remove it. for (unsigned int i=0; i<groups->count(); i++) { Group *tmp = groups->at(i); //CHECK_PTR(tmp); tmp->setLiberties(countLiberties(tmp, m)); //SL added eb 8 // qDebug("Group #%d with %d liberties:", i, tmp->getLiberties()); // tmp->debug(); // Oops, zero liberties. if (tmp->getLiberties() == 0) { // Suicide move? if (tmp == active) { if (active->count() == 1) { groups->remove(i); removeStone(stone->posX(), stone->posY(), false); } return false; } //was it a forbidden ko move ? if ((tmp->count() == 1) && koStone && ((countLiberties(active, m) == 0))) { active->debug(); groups->remove(groups->findRef(active)); removeStone(stone->posX(), stone->posY(), false); return false ; } int stoneCounter = 0; // Erase the stones of this group from the stones table. QListIterator<Stone *> it(*tmp); while (it.hasNext()) { Stone *s = it.next(); CHECK_PTR(s); if (workingOnNewMove) boardHandler->updateCurrentMatrix(stoneNone, s->posX(), s->posY()); removeStone(s->posX(), s->posY()); stoneCounter ++; } // Remove the group from the groups list. // qDebug("Oops, a group got killed. Removing killed group #%d", i); if (tmp == active) active = NULL; if (!groups->remove(i)) qFatal("StoneHandler::checkPosition(Stone *stone): " "Oops, removing a killed group failed."); i--; // Tell the boardhandler about the captures boardHandler->setCaptures(stone->getColor(), stoneCounter); } } return true; }