Cell.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. #include "Cell.h"
  2. //#include "unit.h"
  3. #include <queue>
  4. #include <vector>
  5. /*
  6. * Добавьте в Unit эту функцию
  7. */
  8. class Unit {
  9. public:
  10. bool canAttackForDistance(int) { return true; }
  11. bool canAttackUnit(Unit*) { return true; }
  12. };
  13. Cell::Cell(Unit * character) {
  14. left_up_ = left_ = left_down_ = nullptr;
  15. right_up_ = right_ = right_down_ = nullptr;
  16. character_ = character;
  17. clearCell_();
  18. AddedToQuery_ = true;
  19. }
  20. Cell::Cell(int i, int j) :i(i), j(j), AddedToQuery_(true) {}
  21. Cell * Cell::getLeftUp() {
  22. return left_up_;
  23. }
  24. void Cell::setLeftUp(Cell * t) {
  25. left_up_ = t;
  26. }
  27. Cell * Cell::getLeft() {
  28. return left_;
  29. }
  30. void Cell::setLeft(Cell * t) {
  31. left_ = t;
  32. }
  33. Cell * Cell::getLeftDown() {
  34. return left_down_;
  35. }
  36. void Cell::setLeftDown(Cell * t) {
  37. left_down_ = t;
  38. }
  39. Cell * Cell::getRightUp() {
  40. return right_up_;
  41. }
  42. void Cell::setRightUp(Cell * t) {
  43. right_up_ = t;
  44. }
  45. Cell * Cell::getRight() {
  46. return right_;
  47. }
  48. void Cell::setRight(Cell * t) {
  49. right_ = t;
  50. }
  51. Cell * Cell::getRightDown() {
  52. return right_down_;
  53. }
  54. void Cell::setRightDown(Cell * t) {
  55. right_down_ = t;
  56. }
  57. Unit * Cell::getCharacter() {
  58. return character_;
  59. }
  60. void Cell::setCharacter(Unit * t) {
  61. character_ = t;
  62. }
  63. bool Cell::getIsMoveable() {
  64. return isMoveable_;
  65. }
  66. void Cell::setIsMoveable(bool t) {
  67. isMoveable_ = t;
  68. }
  69. bool Cell::getIsAttackable() {
  70. return isAttackable_;
  71. }
  72. void Cell::setIsAttackable(bool t) {
  73. isAttackable_ = t;
  74. }
  75. int Cell::getDistance() {
  76. return distance_;
  77. }
  78. void Cell::setDistance(int t) {
  79. distance_ = t;
  80. }
  81. bool Cell::isEmpty() {
  82. return character_ == NULL;
  83. }
  84. void Cell::clearCell_() {
  85. setIsMoveable(false);
  86. setDistance(-1);
  87. }
  88. void Cell::clearTable_(bool NeedClearCell = true) {
  89. std::queue<Cell*> q;
  90. q.push(this);
  91. setIsAttackable(false);
  92. if (NeedClearCell) {
  93. clearCell_();
  94. }
  95. this->AddedToQuery_ = false;
  96. auto f = [&q](Cell * t) {
  97. if (t && t->AddedToQuery_ == true) {
  98. q.push(t);
  99. t->AddedToQuery_ = false;
  100. }
  101. };
  102. while (!q.empty()) {
  103. Cell * Now = q.front();
  104. q.pop();
  105. Now->setIsAttackable(false);
  106. if (NeedClearCell) {
  107. Now->clearCell_();
  108. }
  109. f(Now->getLeftUp());
  110. f(Now->getLeft());
  111. f(Now->getLeftDown());
  112. f(Now->getRightUp());
  113. f(Now->getRight());
  114. f(Now->getRightDown());
  115. }
  116. }
  117. void Cell::handleAllMoveableCellsAndUnmoveableCells_(std::queue<Cell*> & Q) {
  118. std::queue<Cell*> q;
  119. q.push(this);
  120. setDistance(0);
  121. AddedToQuery_ = true;
  122. setIsMoveable(true);
  123. setIsAttackable(true);
  124. auto f = [&q, &Q](Cell * t, Cell * parent) {
  125. if (t && !t->AddedToQuery_) {
  126. t->AddedToQuery_ = true;
  127. t->setDistance(parent->getDistance() + 1);
  128. if (t->getCharacter() != NULL) {
  129. t->setIsMoveable(false);
  130. Q.push(t);
  131. return;
  132. }
  133. q.push(t);
  134. }
  135. };
  136. while (!q.empty()) {
  137. Cell * Now = q.front();
  138. Now->setIsMoveable(true);
  139. if (getCharacter() != NULL && getCharacter()->canAttackForDistance(Now->getDistance()) &&
  140. (Now->getCharacter() == NULL || getCharacter()->canAttackUnit(Now->getCharacter()))) {
  141. Now->setIsAttackable(true);
  142. }
  143. else {
  144. Now->setIsAttackable(false);
  145. }
  146. q.pop();
  147. f(Now->getLeftUp(), Now);
  148. f(Now->getLeft(), Now);
  149. f(Now->getLeftDown(), Now);
  150. f(Now->getRightUp(), Now);
  151. f(Now->getRight(), Now);
  152. f(Now->getRightDown(), Now);
  153. }
  154. }
  155. void Cell::handleAllUnmoveableCells_(std::queue<Cell*> & Q) {
  156. auto f = [&Q](Cell * t, Cell * parent) {
  157. if (t && !t->AddedToQuery_) {
  158. t->AddedToQuery_ = true;
  159. t->setDistance(parent->getDistance() + 1);
  160. Q.push(t);
  161. }
  162. };
  163. while (!Q.empty()) {
  164. Cell * Now = Q.front();
  165. Now->setIsMoveable(false);
  166. Now->setIsAttackable(false);
  167. Q.pop();
  168. f(Now->getLeftUp(), Now);
  169. f(Now->getLeft(), Now);
  170. f(Now->getLeftDown(), Now);
  171. f(Now->getRightUp(), Now);
  172. f(Now->getRight(), Now);
  173. f(Now->getRightDown(), Now);
  174. }
  175. }
  176. void Cell::recalculateTableWithCenterThisPoint() {
  177. clearTable_();
  178. std::queue<Cell*> qWithoutMoveable;
  179. handleAllMoveableCellsAndUnmoveableCells_(qWithoutMoveable);
  180. handleAllUnmoveableCells_(qWithoutMoveable);
  181. }
  182. void Cell::buffTableinDistance(int distance) {
  183. clearTable_(false);
  184. std::queue<Cell*> q;
  185. q.push(this);
  186. setIsAttackable(true);
  187. auto f = [&q, &distance](Cell * Now) {
  188. if (Now != NULL && Now->getDistance() <= distance && !Now->AddedToQuery_) {
  189. q.push(Now);
  190. Now->AddedToQuery_ = true;
  191. Now->setIsAttackable(true);
  192. }
  193. };
  194. while (!q.empty()) {
  195. Cell * Now = q.front();
  196. q.pop();
  197. f(Now->getLeftUp());
  198. f(Now->getLeft());
  199. f(Now->getLeftDown());
  200. f(Now->getRightUp());
  201. f(Now->getRight());
  202. f(Now->getRightDown());
  203. }
  204. }
  205. std::vector <Cell*> Cell::actualPath(Cell* to) {
  206. if (!to || !to->getIsMoveable())return std::vector<Cell*>();
  207. auto ret = std::vector<Cell*>(1, to);
  208. while (to != this) {
  209. Cell * parent = NULL;
  210. auto f = [&parent](Cell * TestParent, Cell * Now) {
  211. if (TestParent && TestParent->getDistance() + 1 == Now->getDistance() && TestParent->getIsMoveable()) {
  212. parent = TestParent;
  213. }
  214. };
  215. f(to->getLeftUp(), to);
  216. f(to->getLeft(), to);
  217. f(to->getLeftDown(), to);
  218. f(to->getRightUp(), to);
  219. f(to->getRight(), to);
  220. f(to->getRightDown(), to);
  221. to = parent;
  222. ret.push_back(to);
  223. }
  224. return ret;
  225. }