Cell.cpp 4.0 KB

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