From 733aa6c52b4c1dbbc4ecb79e2fdb657ceb8fbfdc Mon Sep 17 00:00:00 2001 From: Max-Wilhelm Bruker Date: Thu, 3 Jan 2013 18:16:17 +0100 Subject: [PATCH] Server_CardZone speed optimisation --- common/server_cardzone.cpp | 99 +++++++++++++++++++++----------------- common/server_cardzone.h | 4 +- common/server_player.cpp | 8 +-- 3 files changed, 62 insertions(+), 49 deletions(-) diff --git a/common/server_cardzone.cpp b/common/server_cardzone.cpp index 3ed0234c..00c86991 100644 --- a/common/server_cardzone.cpp +++ b/common/server_cardzone.cpp @@ -55,6 +55,8 @@ int Server_CardZone::removeCard(Server_Card *card) { int index = cards.indexOf(card); cards.removeAt(index); + if (has_coords) + coordinateMap[card->getY()].remove(card->getX()); card->setZone(0); return index; @@ -92,22 +94,25 @@ Server_Card *Server_CardZone::getCard(int id, int *position, bool remove) int Server_CardZone::getFreeGridColumn(int x, int y, const QString &cardName) const { - QMap coordMap; - for (int i = 0; i < cards.size(); ++i) - if (cards[i]->getY() == y) - coordMap.insert(cards[i]->getX(), cards[i]); - + const QMap &coordMap = coordinateMap.value(y); int resultX = 0; if (x == -1) { - for (int i = 0; i < cards.size(); ++i) - if ((cards[i]->getName() == cardName) && !(cards[i]->getX() % 3) && (cards[i]->getY() == y)) { - if (!cards[i]->getAttachedCards().isEmpty()) + QMapIterator cardIterator(coordMap); + while (cardIterator.hasNext()) { + cardIterator.next(); + const int cardX = cardIterator.key(); + if (cardX % 3) + continue; + Server_Card *card = cardIterator.value(); + if (card->getName() == cardName) { + if (!card->getAttachedCards().isEmpty()) continue; - if (!coordMap.value(cards[i]->getX() + 1)) - return cards[i]->getX() + 1; - if (!coordMap.value(cards[i]->getX() + 2)) - return cards[i]->getX() + 2; + if (!coordMap.contains(cardX + 1)) + return cardX + 1; + if (!coordMap.contains(cardX + 2)) + return cardX + 2; } + } } else if (x == -2) { } else { x = (x / 3) * 3; @@ -127,7 +132,7 @@ int Server_CardZone::getFreeGridColumn(int x, int y, const QString &cardName) co } if (x < 0) - while (coordMap.value(resultX)) + while (coordMap.contains(resultX)) resultX += 3; return resultX; @@ -138,12 +143,7 @@ bool Server_CardZone::isColumnStacked(int x, int y) const if (!has_coords) return false; - QMap coordMap; - for (int i = 0; i < cards.size(); ++i) - if (cards[i]->getY() == y) - coordMap.insert(cards[i]->getX(), cards[i]); - - return coordMap.contains((x / 3) * 3 + 1); + return coordinateMap[y].contains((x / 3) * 3 + 1); } bool Server_CardZone::isColumnEmpty(int x, int y) const @@ -151,60 +151,68 @@ bool Server_CardZone::isColumnEmpty(int x, int y) const if (!has_coords) return true; - QMap coordMap; - for (int i = 0; i < cards.size(); ++i) - if (cards[i]->getY() == y) - coordMap.insert(cards[i]->getX(), cards[i]); - - return !coordMap.contains((x / 3) * 3); + return !coordinateMap[y].contains((x / 3) * 3); } -void Server_CardZone::moveCard(GameEventStorage &ges, QMap &coordMap, Server_Card *card, int x, int y) +void Server_CardZone::moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y) { - coordMap.remove(card->getY() * 10000 + card->getX()); + coordinateMap[y].remove(card->getX()); CardToMove *cardToMove = new CardToMove; cardToMove->set_card_id(card->getId()); player->moveCard(ges, this, QList() << cardToMove, this, x, y, false, false); delete cardToMove; - coordMap.insert(y * 10000 + x, card); + coordinateMap[y].insert(x, card); } void Server_CardZone::fixFreeSpaces(GameEventStorage &ges) { - QMap coordMap; - QSet placesToLook; - for (int i = 0; i < cards.size(); ++i) { - coordMap.insert(cards[i]->getY() * 10000 + cards[i]->getX(), cards[i]); - placesToLook.insert(cards[i]->getY() * 10000 + (cards[i]->getX() / 3) * 3); - } + if (!has_coords) + return; - QSetIterator placeIterator(placesToLook); + QSet > placesToLook; + for (int i = 0; i < cards.size(); ++i) + placesToLook.insert(QPair((cards[i]->getX() / 3) * 3, cards[i]->getY())); + + QSetIterator > placeIterator(placesToLook); while (placeIterator.hasNext()) { - int foo = placeIterator.next(); - int y = foo / 10000; - int baseX = foo - y * 10000; + const QPair &foo = placeIterator.next(); + int baseX = foo.first; + int y = foo.second; - if (!coordMap.contains(y * 10000 + baseX)) { - if (coordMap.contains(y * 10000 + baseX + 1)) - moveCard(ges, coordMap, coordMap.value(y * 10000 + baseX + 1), baseX, y); - else if (coordMap.contains(y * 10000 + baseX + 2)) { - moveCard(ges, coordMap, coordMap.value(y * 10000 + baseX + 2), baseX, y); + if (!coordinateMap[y].contains(baseX)) { + if (coordinateMap[y].contains(baseX + 1)) + moveCardInRow(ges, coordinateMap[y].value(baseX + 1), baseX, y); + else if (coordinateMap[y].contains(baseX + 2)) { + moveCardInRow(ges, coordinateMap[y].value(baseX + 2), baseX, y); continue; } else continue; } - if (!coordMap.contains(y * 10000 + baseX + 1) && coordMap.contains(y * 10000 + baseX + 2)) - moveCard(ges, coordMap, coordMap.value(y * 10000 + baseX + 2), baseX + 1, y); + if (!coordinateMap[y].contains(baseX + 1) && coordinateMap[y].contains(baseX + 2)) + moveCardInRow(ges, coordinateMap[y].value(baseX + 2), baseX + 1, y); } } +void Server_CardZone::updateCardCoordinates(Server_Card *card, int oldX, int oldY) +{ + if (!has_coords) + return; + + if (oldX != -1) + coordinateMap[oldY].remove(oldX); + if (card->getX() != -1) + coordinateMap[card->getY()].insert(card->getX(), card); +} + void Server_CardZone::insertCard(Server_Card *card, int x, int y) { if (hasCoords()) { card->setCoords(x, y); cards.append(card); + if (x != -1) + coordinateMap[y].insert(x, card); } else { card->setCoords(0, 0); if (x == -1) @@ -220,6 +228,7 @@ void Server_CardZone::clear() for (int i = 0; i < cards.size(); i++) delete cards.at(i); cards.clear(); + coordinateMap.clear(); playersWithWritePermission.clear(); } diff --git a/common/server_cardzone.h b/common/server_cardzone.h index 2178427f..45c75adf 100644 --- a/common/server_cardzone.h +++ b/common/server_cardzone.h @@ -41,6 +41,7 @@ private: QSet playersWithWritePermission; bool alwaysRevealTopCard; QList cards; + QMap > coordinateMap; // y -> (x -> card) public: Server_CardZone(Server_Player *_player, const QString &_name, bool _has_coords, ServerInfo_Zone::ZoneType _type); ~Server_CardZone(); @@ -61,8 +62,9 @@ public: bool isColumnEmpty(int x, int y) const; bool isColumnStacked(int x, int y) const; void fixFreeSpaces(GameEventStorage &ges); - void moveCard(GameEventStorage &ges, QMap &coordMap, Server_Card *card, int x, int y); + void moveCardInRow(GameEventStorage &ges, Server_Card *card, int x, int y); void insertCard(Server_Card *card, int x, int y); + void updateCardCoordinates(Server_Card *card, int oldX, int oldY); void shuffle(); void clear(); void addWritePermission(int playerId); diff --git a/common/server_player.cpp b/common/server_player.cpp index 1cdb17c0..016de023 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -1024,6 +1024,11 @@ Response::ResponseCode Server_Player::cmdAttachCard(const Command_AttachCard &cm for (int i = 0; i < attachedList.size(); ++i) attachedList[i]->getZone()->getPlayer()->unattachCard(ges, attachedList[i]); + card->setParentCard(targetCard); + const int oldX = card->getX(); + card->setCoords(-1, card->getY()); + startzone->updateCardCoordinates(card, oldX, card->getY()); + if (targetzone->isColumnStacked(targetCard->getX(), targetCard->getY())) { CardToMove *cardToMove = new CardToMove; cardToMove->set_card_id(targetCard->getId()); @@ -1031,9 +1036,6 @@ Response::ResponseCode Server_Player::cmdAttachCard(const Command_AttachCard &cm delete cardToMove; } - card->setParentCard(targetCard); - card->setCoords(-1, card->getY()); - Event_AttachCard event; event.set_start_zone(startzone->getName().toStdString()); event.set_card_id(card->getId());