Cell.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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 СanAttack(int) { return true; }
  11. };
  12. Cell::Cell(Unit & character) {
  13. leftUp_ = left_ = leftDown_ = nullptr;
  14. rightUp_ = right_ = rightDown_ = nullptr;
  15. character_ = &character;
  16. clearCell_();
  17. AddedToQuery_ = true;
  18. }
  19. Cell * Cell::getleftUp() {
  20. return leftUp_;
  21. }
  22. void Cell::setleftUp(Cell * t) {
  23. leftUp_ = t;
  24. }
  25. Cell * Cell::getleft() {
  26. return left_;
  27. }
  28. void Cell::setleft(Cell * t) {
  29. left_ = t;
  30. }
  31. Cell * Cell::getleftDown() {
  32. return leftDown_;
  33. }
  34. void Cell::setleftDown(Cell * t) {
  35. leftDown_ = t;
  36. }
  37. Cell * Cell::getrightUp() {
  38. return rightUp_;
  39. }
  40. void Cell::setrightUp(Cell * t) {
  41. rightUp_ = t;
  42. }
  43. Cell * Cell::getright() {
  44. return right_;
  45. }
  46. void Cell::setright(Cell * t) {
  47. right_ = t;
  48. }
  49. Cell * Cell::getrightDown() {
  50. return rightDown_;
  51. }
  52. void Cell::setrightDown(Cell * t) {
  53. rightDown_ = t;
  54. }
  55. Unit * Cell::getCharacter() {
  56. return character_;
  57. }
  58. void Cell::setCharacter(Unit * t) {
  59. character_ = t;
  60. }
  61. bool Cell::getisMoveable() {
  62. return isMoveable_;
  63. }
  64. void Cell::setisMoveable(bool t) {
  65. isMoveable_ = t;
  66. }
  67. bool Cell::getisAttackable() {
  68. return isAttackable_;
  69. }
  70. void Cell::setisAttackable(bool t) {
  71. isAttackable_ = t;
  72. }
  73. int Cell::getDistance() {
  74. return distance_;
  75. }
  76. void Cell::setDistance(int t) {
  77. distance_ = t;
  78. }
  79. bool Cell::isEmpty() {
  80. return character_ == NULL;
  81. }
  82. void Cell::clearCell_() {
  83. setisMoveable(false);
  84. setisAttackable(false);
  85. setDistance(-1);
  86. }
  87. void Cell::clearTable_() {
  88. std::queue<Cell*> q;
  89. q.push(this);
  90. clearCell_();
  91. this->AddedToQuery_ = false;
  92. auto f = [&q](Cell * t) {
  93. if (t && t->AddedToQuery_ == true) {
  94. q.push(t);
  95. t->AddedToQuery_ = false;
  96. }
  97. };
  98. while (!q.empty()) {
  99. Cell * Now = q.front();
  100. q.pop();
  101. Now->clearCell_();
  102. f(Now->getleftUp());
  103. f(Now->getleft());
  104. f(Now->getleftDown());
  105. f(Now->getrightUp());
  106. f(Now->getright());
  107. f(Now->getrightDown());
  108. }
  109. }
  110. void Cell::handleAllMoveableCellsAndUnmoveableCells_(std::queue<Cell*> & Q) {
  111. std::queue<Cell*> q;
  112. q.push(this);
  113. setDistance(0);
  114. auto f = [&q, &Q](Cell * t, Cell * parent) {
  115. if (t && !t->AddedToQuery_) {
  116. t->AddedToQuery_ = true;
  117. if (t->getCharacter() != NULL) {
  118. t->setisMoveable(false);
  119. Q.push(t);
  120. return;
  121. }
  122. q.push(t);
  123. t->setDistance(parent->getDistance() + 1);
  124. }
  125. };
  126. while (!q.empty()) {
  127. Cell * Now = q.front();
  128. Now->setisMoveable(true);
  129. if (getCharacter() != NULL && getCharacter()->СanAttack(Now->getDistance())) {
  130. Now->setisAttackable(true);
  131. }
  132. else {
  133. Now->setisAttackable(false);
  134. }
  135. q.pop();
  136. f(Now->getleftUp(), Now);
  137. f(Now->getleft(), Now);
  138. f(Now->getleftDown(), Now);
  139. f(Now->getrightUp(), Now);
  140. f(Now->getright(), Now);
  141. f(Now->getrightDown(), Now);
  142. }
  143. }
  144. void Cell::handleAllUnmoveableCells_(std::queue<Cell*> & Q) {
  145. auto f = [&Q](Cell * t, Cell * parent) {
  146. if (t && !t->AddedToQuery_) {
  147. t->AddedToQuery_ = true;
  148. Q.push(t);
  149. }
  150. };
  151. while (!Q.empty()) {
  152. Cell * Now = Q.front();
  153. Now->setisMoveable(false);
  154. Now->setisAttackable(false);
  155. Q.pop();
  156. f(Now->getleftUp(), Now);
  157. f(Now->getleft(), Now);
  158. f(Now->getleftDown(), Now);
  159. f(Now->getrightUp(), Now);
  160. f(Now->getright(), Now);
  161. f(Now->getrightDown(), Now);
  162. }
  163. }
  164. void Cell::RecalculateTableWithCenterThisPoint() {
  165. clearTable_();
  166. std::queue<Cell*> qWithoutMoveable;
  167. handleAllMoveableCellsAndUnmoveableCells_(qWithoutMoveable);
  168. handleAllUnmoveableCells_(qWithoutMoveable);
  169. }
  170. std::vector <Cell*> Cell::actualPath(Cell* to) {//std::vector<Cell*> âêëþ÷àåòñÿ â ñåáÿ è this, è end
  171. if (!to || !to->getisMoveable())return std::vector<Cell*>();
  172. auto ret = std::vector<Cell*>(1, to);
  173. while (to != this) {
  174. Cell * parent = NULL;
  175. auto f = [&parent](Cell * TestParent, Cell * Now) {
  176. if (TestParent && TestParent->getDistance() + 1 == Now->getDistance() && TestParent->getisMoveable()) {
  177. parent = TestParent;
  178. }
  179. };
  180. f(to->getleftUp(), to);
  181. f(to->getleft(), to);
  182. f(to->getleftDown(), to);
  183. f(to->getrightUp(), to);
  184. f(to->getright(), to);
  185. f(to->getrightDown(), to);
  186. to = parent;
  187. ret.push_back(to);
  188. }
  189. return ret;
  190. }