|
@@ -8,57 +8,60 @@
|
|
|
*/
|
|
|
class Unit {
|
|
|
public:
|
|
|
- bool СanAttack(int) { return true; }
|
|
|
+ bool canAttackForDistance(int) { return true; }
|
|
|
+ bool canAttackUnit(Unit*) { return true; }
|
|
|
};
|
|
|
|
|
|
-Cell::Cell(Unit & character) {
|
|
|
- leftUp_ = left_ = leftDown_ = nullptr;
|
|
|
- rightUp_ = right_ = rightDown_ = nullptr;
|
|
|
- character_ = &character;
|
|
|
+Cell::Cell(Unit * character) {
|
|
|
+ left_up_ = left_ = left_down_ = nullptr;
|
|
|
+ right_up_ = right_ = right_down_ = nullptr;
|
|
|
+ character_ = character;
|
|
|
clearCell_();
|
|
|
AddedToQuery_ = true;
|
|
|
}
|
|
|
|
|
|
-Cell * Cell::getleftUp() {
|
|
|
- return leftUp_;
|
|
|
+Cell::Cell(int i, int j) :i(i), j(j), AddedToQuery_(true) {}
|
|
|
+
|
|
|
+Cell * Cell::getLeftUp() {
|
|
|
+ return left_up_;
|
|
|
}
|
|
|
-void Cell::setleftUp(Cell * t) {
|
|
|
- leftUp_ = t;
|
|
|
+void Cell::setLeftUp(Cell * t) {
|
|
|
+ left_up_ = t;
|
|
|
}
|
|
|
|
|
|
-Cell * Cell::getleft() {
|
|
|
+Cell * Cell::getLeft() {
|
|
|
return left_;
|
|
|
}
|
|
|
-void Cell::setleft(Cell * t) {
|
|
|
+void Cell::setLeft(Cell * t) {
|
|
|
left_ = t;
|
|
|
}
|
|
|
|
|
|
-Cell * Cell::getleftDown() {
|
|
|
- return leftDown_;
|
|
|
+Cell * Cell::getLeftDown() {
|
|
|
+ return left_down_;
|
|
|
}
|
|
|
-void Cell::setleftDown(Cell * t) {
|
|
|
- leftDown_ = t;
|
|
|
+void Cell::setLeftDown(Cell * t) {
|
|
|
+ left_down_ = t;
|
|
|
}
|
|
|
|
|
|
-Cell * Cell::getrightUp() {
|
|
|
- return rightUp_;
|
|
|
+Cell * Cell::getRightUp() {
|
|
|
+ return right_up_;
|
|
|
}
|
|
|
-void Cell::setrightUp(Cell * t) {
|
|
|
- rightUp_ = t;
|
|
|
+void Cell::setRightUp(Cell * t) {
|
|
|
+ right_up_ = t;
|
|
|
}
|
|
|
|
|
|
-Cell * Cell::getright() {
|
|
|
+Cell * Cell::getRight() {
|
|
|
return right_;
|
|
|
}
|
|
|
-void Cell::setright(Cell * t) {
|
|
|
+void Cell::setRight(Cell * t) {
|
|
|
right_ = t;
|
|
|
}
|
|
|
|
|
|
-Cell * Cell::getrightDown() {
|
|
|
- return rightDown_;
|
|
|
+Cell * Cell::getRightDown() {
|
|
|
+ return right_down_;
|
|
|
}
|
|
|
-void Cell::setrightDown(Cell * t) {
|
|
|
- rightDown_ = t;
|
|
|
+void Cell::setRightDown(Cell * t) {
|
|
|
+ right_down_ = t;
|
|
|
}
|
|
|
|
|
|
Unit * Cell::getCharacter() {
|
|
@@ -68,17 +71,17 @@ void Cell::setCharacter(Unit * t) {
|
|
|
character_ = t;
|
|
|
}
|
|
|
|
|
|
-bool Cell::getisMoveable() {
|
|
|
+bool Cell::getIsMoveable() {
|
|
|
return isMoveable_;
|
|
|
}
|
|
|
-void Cell::setisMoveable(bool t) {
|
|
|
+void Cell::setIsMoveable(bool t) {
|
|
|
isMoveable_ = t;
|
|
|
}
|
|
|
|
|
|
-bool Cell::getisAttackable() {
|
|
|
+bool Cell::getIsAttackable() {
|
|
|
return isAttackable_;
|
|
|
}
|
|
|
-void Cell::setisAttackable(bool t) {
|
|
|
+void Cell::setIsAttackable(bool t) {
|
|
|
isAttackable_ = t;
|
|
|
}
|
|
|
|
|
@@ -94,15 +97,17 @@ bool Cell::isEmpty() {
|
|
|
}
|
|
|
|
|
|
void Cell::clearCell_() {
|
|
|
- setisMoveable(false);
|
|
|
- setisAttackable(false);
|
|
|
+ setIsMoveable(false);
|
|
|
setDistance(-1);
|
|
|
}
|
|
|
|
|
|
-void Cell::clearTable_() {
|
|
|
+void Cell::clearTable_(bool NeedClearCell = true) {
|
|
|
std::queue<Cell*> q;
|
|
|
q.push(this);
|
|
|
- clearCell_();
|
|
|
+ setIsAttackable(false);
|
|
|
+ if (NeedClearCell) {
|
|
|
+ clearCell_();
|
|
|
+ }
|
|
|
this->AddedToQuery_ = false;
|
|
|
auto f = [&q](Cell * t) {
|
|
|
if (t && t->AddedToQuery_ == true) {
|
|
@@ -113,13 +118,16 @@ void Cell::clearTable_() {
|
|
|
while (!q.empty()) {
|
|
|
Cell * Now = q.front();
|
|
|
q.pop();
|
|
|
- Now->clearCell_();
|
|
|
- f(Now->getleftUp());
|
|
|
- f(Now->getleft());
|
|
|
- f(Now->getleftDown());
|
|
|
- f(Now->getrightUp());
|
|
|
- f(Now->getright());
|
|
|
- f(Now->getrightDown());
|
|
|
+ Now->setIsAttackable(false);
|
|
|
+ if (NeedClearCell) {
|
|
|
+ Now->clearCell_();
|
|
|
+ }
|
|
|
+ f(Now->getLeftUp());
|
|
|
+ f(Now->getLeft());
|
|
|
+ f(Now->getLeftDown());
|
|
|
+ f(Now->getRightUp());
|
|
|
+ f(Now->getRight());
|
|
|
+ f(Now->getRightDown());
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -127,34 +135,38 @@ void Cell::handleAllMoveableCellsAndUnmoveableCells_(std::queue<Cell*> & Q) {
|
|
|
std::queue<Cell*> q;
|
|
|
q.push(this);
|
|
|
setDistance(0);
|
|
|
+ AddedToQuery_ = true;
|
|
|
+ setIsMoveable(true);
|
|
|
+ setIsAttackable(true);
|
|
|
auto f = [&q, &Q](Cell * t, Cell * parent) {
|
|
|
if (t && !t->AddedToQuery_) {
|
|
|
t->AddedToQuery_ = true;
|
|
|
+ t->setDistance(parent->getDistance() + 1);
|
|
|
if (t->getCharacter() != NULL) {
|
|
|
- t->setisMoveable(false);
|
|
|
+ t->setIsMoveable(false);
|
|
|
Q.push(t);
|
|
|
return;
|
|
|
}
|
|
|
q.push(t);
|
|
|
- t->setDistance(parent->getDistance() + 1);
|
|
|
}
|
|
|
};
|
|
|
while (!q.empty()) {
|
|
|
Cell * Now = q.front();
|
|
|
- Now->setisMoveable(true);
|
|
|
- if (getCharacter() != NULL && getCharacter()->СanAttack(Now->getDistance())) {
|
|
|
- Now->setisAttackable(true);
|
|
|
+ Now->setIsMoveable(true);
|
|
|
+ if (getCharacter() != NULL && getCharacter()->canAttackForDistance(Now->getDistance()) &&
|
|
|
+ (Now->getCharacter() == NULL || getCharacter()->canAttackUnit(Now->getCharacter()))) {
|
|
|
+ Now->setIsAttackable(true);
|
|
|
}
|
|
|
else {
|
|
|
- Now->setisAttackable(false);
|
|
|
+ Now->setIsAttackable(false);
|
|
|
}
|
|
|
q.pop();
|
|
|
- f(Now->getleftUp(), Now);
|
|
|
- f(Now->getleft(), Now);
|
|
|
- f(Now->getleftDown(), Now);
|
|
|
- f(Now->getrightUp(), Now);
|
|
|
- f(Now->getright(), Now);
|
|
|
- f(Now->getrightDown(), Now);
|
|
|
+ f(Now->getLeftUp(), Now);
|
|
|
+ f(Now->getLeft(), Now);
|
|
|
+ f(Now->getLeftDown(), Now);
|
|
|
+ f(Now->getRightUp(), Now);
|
|
|
+ f(Now->getRight(), Now);
|
|
|
+ f(Now->getRightDown(), Now);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -162,46 +174,71 @@ void Cell::handleAllUnmoveableCells_(std::queue<Cell*> & Q) {
|
|
|
auto f = [&Q](Cell * t, Cell * parent) {
|
|
|
if (t && !t->AddedToQuery_) {
|
|
|
t->AddedToQuery_ = true;
|
|
|
+ t->setDistance(parent->getDistance() + 1);
|
|
|
Q.push(t);
|
|
|
}
|
|
|
};
|
|
|
while (!Q.empty()) {
|
|
|
Cell * Now = Q.front();
|
|
|
- Now->setisMoveable(false);
|
|
|
- Now->setisAttackable(false);
|
|
|
+ Now->setIsMoveable(false);
|
|
|
+ Now->setIsAttackable(false);
|
|
|
Q.pop();
|
|
|
- f(Now->getleftUp(), Now);
|
|
|
- f(Now->getleft(), Now);
|
|
|
- f(Now->getleftDown(), Now);
|
|
|
- f(Now->getrightUp(), Now);
|
|
|
- f(Now->getright(), Now);
|
|
|
- f(Now->getrightDown(), Now);
|
|
|
+ f(Now->getLeftUp(), Now);
|
|
|
+ f(Now->getLeft(), Now);
|
|
|
+ f(Now->getLeftDown(), Now);
|
|
|
+ f(Now->getRightUp(), Now);
|
|
|
+ f(Now->getRight(), Now);
|
|
|
+ f(Now->getRightDown(), Now);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void Cell::RecalculateTableWithCenterThisPoint() {
|
|
|
+void Cell::recalculateTableWithCenterThisPoint() {
|
|
|
clearTable_();
|
|
|
std::queue<Cell*> qWithoutMoveable;
|
|
|
handleAllMoveableCellsAndUnmoveableCells_(qWithoutMoveable);
|
|
|
handleAllUnmoveableCells_(qWithoutMoveable);
|
|
|
}
|
|
|
|
|
|
-std::vector <Cell*> Cell::actualPath(Cell* to) {//std::vector<Cell*> âêëþ÷àåòñÿ â ñåáÿ è this, è end
|
|
|
- if (!to || !to->getisMoveable())return std::vector<Cell*>();
|
|
|
+void Cell::buffTableinDistance(int distance) {
|
|
|
+ clearTable_(false);
|
|
|
+ std::queue<Cell*> q;
|
|
|
+ q.push(this);
|
|
|
+ setIsAttackable(true);
|
|
|
+ auto f = [&q, &distance](Cell * Now) {
|
|
|
+ if (Now != NULL && Now->getDistance() <= distance && !Now->AddedToQuery_) {
|
|
|
+ q.push(Now);
|
|
|
+ Now->AddedToQuery_ = true;
|
|
|
+ Now->setIsAttackable(true);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ while (!q.empty()) {
|
|
|
+ Cell * Now = q.front();
|
|
|
+ q.pop();
|
|
|
+ f(Now->getLeftUp());
|
|
|
+ f(Now->getLeft());
|
|
|
+ f(Now->getLeftDown());
|
|
|
+ f(Now->getRightUp());
|
|
|
+ f(Now->getRight());
|
|
|
+ f(Now->getRightDown());
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+std::vector <Cell*> Cell::actualPath(Cell* to) {
|
|
|
+ if (!to || !to->getIsMoveable())return std::vector<Cell*>();
|
|
|
auto ret = std::vector<Cell*>(1, to);
|
|
|
while (to != this) {
|
|
|
Cell * parent = NULL;
|
|
|
auto f = [&parent](Cell * TestParent, Cell * Now) {
|
|
|
- if (TestParent && TestParent->getDistance() + 1 == Now->getDistance() && TestParent->getisMoveable()) {
|
|
|
+ if (TestParent && TestParent->getDistance() + 1 == Now->getDistance() && TestParent->getIsMoveable()) {
|
|
|
parent = TestParent;
|
|
|
}
|
|
|
};
|
|
|
- f(to->getleftUp(), to);
|
|
|
- f(to->getleft(), to);
|
|
|
- f(to->getleftDown(), to);
|
|
|
- f(to->getrightUp(), to);
|
|
|
- f(to->getright(), to);
|
|
|
- f(to->getrightDown(), to);
|
|
|
+ f(to->getLeftUp(), to);
|
|
|
+ f(to->getLeft(), to);
|
|
|
+ f(to->getLeftDown(), to);
|
|
|
+ f(to->getRightUp(), to);
|
|
|
+ f(to->getRight(), to);
|
|
|
+ f(to->getRightDown(), to);
|
|
|
to = parent;
|
|
|
ret.push_back(to);
|
|
|
}
|