Cell.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. #include "Cell.h"
  2. #include <queue>
  3. #include <vector>
  4. //***************
  5. //Äàéòå ìíå êëàññ Þíèò
  6. //Ìíå áëÿòü âñå ýòî ïðîâåðèòü íàäî
  7. //Ñëàâà Ñèøàðï
  8. //***************
  9. struct Unit {
  10. bool canAttack(int distance) {
  11. return true;
  12. }
  13. };
  14. Cell::Cell(Unit & character) {
  15. upLeft_ = up_ = upRight_ = nullptr;
  16. downLeft_ = down_ = downRight_ = nullptr;
  17. character_ = &character;
  18. clearCell_();
  19. AddedToQuery_ = true;
  20. }
  21. Cell * Cell::getUpLeft() {
  22. return upLeft_;
  23. }
  24. void Cell::setUpLeft(Cell * t) {
  25. upLeft_ = t;
  26. }
  27. Cell * Cell::getUp() {
  28. return up_;
  29. }
  30. void Cell::setUp(Cell * t) {
  31. up_ = t;
  32. }
  33. Cell * Cell::getUpRight() {
  34. return upRight_;
  35. }
  36. void Cell::setUpRight(Cell * t) {
  37. upRight_ = t;
  38. }
  39. Cell * Cell::getDownLeft() {
  40. return downLeft_;
  41. }
  42. void Cell::setDownLeft(Cell * t) {
  43. downLeft_ = t;
  44. }
  45. Cell * Cell::getDown() {
  46. return down_;
  47. }
  48. void Cell::setDown(Cell * t) {
  49. down_ = t;
  50. }
  51. Cell * Cell::getDownRight() {
  52. return downRight_;
  53. }
  54. void Cell::setDownRight(Cell * t) {
  55. downRight_ = 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. setisAttackable(false);
  87. setDistance(-1);
  88. }
  89. void Cell::clearTable_() {
  90. std::queue<Cell*> q;
  91. q.push(this);
  92. clearCell_();
  93. this->AddedToQuery_ = false;
  94. auto f = [&q](Cell * t) {
  95. if (t && t->AddedToQuery_ == true) {
  96. q.push(t);
  97. t->AddedToQuery_ = false;
  98. }
  99. };
  100. while (!q.empty()) {
  101. Cell * Now = q.front();
  102. q.pop();
  103. Now->clearCell_();
  104. f(Now->getUpLeft());
  105. f(Now->getUp());
  106. f(Now->getUpRight());
  107. f(Now->getDownLeft());
  108. f(Now->getDown());
  109. f(Now->getDownRight());
  110. }
  111. }
  112. void Cell::handleAllMoveableCellsAndUnmoveableCells_(std::queue<Cell*> & Q) {
  113. std::queue<Cell*> q;
  114. q.push(this);
  115. setDistance(0);
  116. while (!q.empty()) {
  117. Cell * Now = q.front();
  118. Now->setisMoveable(true);
  119. if (getCharacter() != NULL && getCharacter()->canAttack(Now->getDistance())) {
  120. Now->setisAttackable(true);
  121. }
  122. else {
  123. Now->setisAttackable(false);
  124. }
  125. q.pop();
  126. auto f = [&q, &Q](Cell * t, Cell * parent) {
  127. if (t && !t->AddedToQuery_) {
  128. t->AddedToQuery_ = true;
  129. if (t->getCharacter() != NULL) {
  130. t->setisMoveable(false);
  131. Q.push(t);
  132. return;
  133. }
  134. q.push(t);
  135. t->setDistance(parent->getDistance() + 1);
  136. }
  137. };
  138. f(Now->getUpLeft(), Now);
  139. f(Now->getUp(), Now);
  140. f(Now->getUpRight(), Now);
  141. f(Now->getDownLeft(), Now);
  142. f(Now->getDown(), Now);
  143. f(Now->getDownRight(), Now);
  144. }
  145. }
  146. void Cell::handleAllUnmoveableCells_(std::queue<Cell*> & Q) {
  147. while (!Q.empty()) {
  148. Cell * Now = Q.front();
  149. Now->setisMoveable(false);
  150. Now->setisAttackable(false);
  151. Q.pop();
  152. auto f = [&Q](Cell * t, Cell * parent) {
  153. if (t && !t->AddedToQuery_) {
  154. t->AddedToQuery_ = true;
  155. Q.push(t);
  156. }
  157. };
  158. f(Now->getUpLeft(), Now);
  159. f(Now->getUp(), Now);
  160. f(Now->getUpRight(), Now);
  161. f(Now->getDownLeft(), Now);
  162. f(Now->getDown(), Now);
  163. f(Now->getDownRight(), Now);
  164. }
  165. }
  166. void Cell::RecalculateTableWithCenterThisPoint() {
  167. clearTable_();
  168. std::queue<Cell*> qWithoutMoveable;
  169. handleAllMoveableCellsAndUnmoveableCells_(qWithoutMoveable);
  170. handleAllUnmoveableCells_(qWithoutMoveable);
  171. }
  172. std::vector <Cell*> Cell::actualPath(Cell* to) {//std::vector<Cell*> âêëþ÷àåòñÿ â ñåáÿ è this, è end
  173. if (!to || !to->getisMoveable())return std::vector<Cell*>();
  174. auto ret = std::vector<Cell*>(1, to);
  175. while (to != this) {
  176. Cell * parent = NULL;
  177. auto f = [&parent](Cell * TestParent, Cell * Now) {
  178. if (TestParent && TestParent->getDistance() + 1 == Now->getDistance() && TestParent->getisMoveable()) {
  179. parent = TestParent;
  180. }
  181. };
  182. f(to->getUpLeft(), to);
  183. f(to->getUp(), to);
  184. f(to->getUpRight(), to);
  185. f(to->getDownLeft(), to);
  186. f(to->getDown(), to);
  187. f(to->getDownRight(), to);
  188. to = parent;
  189. ret.push_back(to);
  190. }
  191. return ret;
  192. }