Cell.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. #include "Cell.h"
  2. #include <assert.h>
  3. #include <string>
  4. #include <string.h>
  5. //#include "unit.h"
  6. #include <queue>
  7. #include <vector>
  8. class Unit{
  9. public:
  10. bool CanMoveForDistance(int distance){
  11. return true;
  12. }
  13. /*
  14. template<std::string AttackType>
  15. bool CanAttackForDistance(int distance){
  16. return true;
  17. }
  18. bool CanAttackForDistance<"Melee">(int distance){
  19. return true;
  20. }
  21. bool CanAttackForDistance<"Range">(int distance){
  22. return true;
  23. }*/
  24. };
  25. class EffectsForCell{
  26. public:
  27. void OperateOnCell(Cell*){}
  28. };
  29. Cell::Cell(Unit* character) {
  30. leftUp_ = left_ = leftDown_ = nullptr;
  31. rightUp_ = right_ = rightDown_ = nullptr;
  32. character_ = character;
  33. clearCell_();
  34. AddedToQuery_ = true;
  35. }
  36. Cell * Cell::getleftUp() {
  37. return leftUp_;
  38. }
  39. void Cell::setleftUp(Cell * t) {
  40. leftUp_ = t;
  41. }
  42. Cell * Cell::getleft() {
  43. return left_;
  44. }
  45. void Cell::setleft(Cell * t) {
  46. left_ = t;
  47. }
  48. Cell * Cell::getleftDown() {
  49. return leftDown_;
  50. }
  51. void Cell::setleftDown(Cell * t) {
  52. leftDown_ = t;
  53. }
  54. Cell * Cell::getrightUp() {
  55. return rightUp_;
  56. }
  57. void Cell::setrightUp(Cell * t) {
  58. rightUp_ = t;
  59. }
  60. Cell * Cell::getright() {
  61. return right_;
  62. }
  63. void Cell::setright(Cell * t) {
  64. right_ = t;
  65. }
  66. Cell * Cell::getrightDown() {
  67. return rightDown_;
  68. }
  69. void Cell::setrightDown(Cell * t) {
  70. rightDown_ = t;
  71. }
  72. Unit * Cell::getCharacter() {
  73. return character_;
  74. }
  75. void Cell::setCharacter(Unit * t) {
  76. character_ = t;
  77. }
  78. int Cell::getdistance_barrier(){
  79. return distance_barrier_;
  80. }
  81. void Cell::setdistance_barrier(int distance_barrier){
  82. distance_barrier_ = distance_barrier;
  83. }
  84. int Cell::getdistance_through(){
  85. return distance_through_;
  86. }
  87. void Cell::setdistance_through(int distance_through){
  88. distance_through_ = distance_through;
  89. }
  90. bool Cell::getisMoveAble(){
  91. return isMoveAble_;
  92. }
  93. void Cell::setisMoveAble(bool isMoveAble){
  94. isMoveAble_ = isMoveAble;
  95. }
  96. bool Cell::getisMeleeAttackAble(){
  97. return isMeleeAttackAble_;
  98. }
  99. void Cell::setisMeleeAttackAble(bool isMeleeAttackAble){
  100. isMeleeAttackAble_ = isMeleeAttackAble;
  101. }
  102. bool Cell::getisRangeAttackAble(){
  103. return isRangeAttackAble_;
  104. }
  105. void Cell::setisRangeAttackAble(bool isRangeAttackAble){
  106. isRangeAttackAble_ = isRangeAttackAble;
  107. }
  108. bool Cell::isEmpty() {
  109. return character_ == NULL;
  110. }
  111. void Cell::recalculateAllEffectsList(){
  112. for(std::vector<EffectsForCell*>::iterator it = beginIteratorEffectsList();
  113. it != endIteratorEffectsList();++it){
  114. (*it)->OperateOnCell(this);
  115. }
  116. }
  117. void Cell::add(EffectsForCell* effect){
  118. effects_list_.push_back(effect);
  119. }
  120. void Cell::remove(std::vector<EffectsForCell*>::iterator it){
  121. if(beginIteratorEffectsList() <= it && it < endIteratorEffectsList()){
  122. effects_list_.erase(it);
  123. }
  124. }
  125. void Cell::remove(EffectsForCell* effect){
  126. for(std::vector<EffectsForCell*>::iterator it = beginIteratorEffectsList();
  127. it != endIteratorEffectsList();++it){
  128. if((*it) == effect){
  129. remove(it);
  130. return;
  131. }
  132. }
  133. }
  134. std::vector<EffectsForCell*>::iterator Cell::beginIteratorEffectsList(){
  135. return effects_list_.begin();
  136. }
  137. std::vector<EffectsForCell*>::iterator Cell::endIteratorEffectsList(){
  138. return effects_list_.end();
  139. }
  140. void Cell::RecalculateTableWithCenterThisPoint() {
  141. clearTable_();
  142. std::queue<Cell*> qWithoutMoveable;
  143. updateMoveableCells_(qWithoutMoveable);
  144. updateUnMovealeCells_(qWithoutMoveable);
  145. }
  146. std::vector <Cell*> Cell::actualPath(Cell* to) {
  147. if (!to || !to->getisMoveAble())return std::vector<Cell*>();
  148. auto ret = std::vector<Cell*>(1, to);
  149. while (to != this) {
  150. Cell * parent = nullptr;
  151. auto f = [&parent](Cell * TestParent, Cell * Now) {
  152. if (TestParent && TestParent->getdistance_barrier() + 1 == Now->getdistance_barrier()
  153. && TestParent->getisMoveAble()) {
  154. parent = TestParent;
  155. }
  156. };
  157. assert(parent != nullptr);
  158. f(to->getleftUp(), to);
  159. f(to->getleft(), to);
  160. f(to->getleftDown(), to);
  161. f(to->getrightUp(), to);
  162. f(to->getright(), to);
  163. f(to->getrightDown(), to);
  164. to = parent;
  165. ret.push_back(to);
  166. }
  167. return ret;
  168. }
  169. void Cell::clearCell_() {
  170. setdistance_barrier(-1);
  171. setdistance_through(-1);
  172. setisMeleeAttackAble(false);
  173. setisMoveAble(false);
  174. setisRangeAttackAble(false);
  175. }
  176. void Cell::clearTable_() {
  177. std::queue<Cell*> q;
  178. q.push(this);
  179. clearCell_();
  180. setdistance_through(0);
  181. this->AddedToQuery_ = false;
  182. auto f = [&q](Cell * t, Cell * parent) {
  183. if (t && t->AddedToQuery_ == true) {
  184. q.push(t);
  185. t->setdistance_through(
  186. parent->getdistance_through() + 1
  187. );
  188. t->AddedToQuery_ = false;
  189. }
  190. };
  191. while (!q.empty()) {
  192. Cell * Now = q.front();
  193. q.pop();
  194. Now->clearCell_();
  195. f(Now->getleftUp(), Now);
  196. f(Now->getleft(), Now);
  197. f(Now->getleftDown(), Now);
  198. f(Now->getrightUp(), Now);
  199. f(Now->getright(), Now);
  200. f(Now->getrightDown(), Now);
  201. }
  202. }
  203. void Cell::recalcAttackable_(Cell * Now){
  204. if(Now == nullptr)return;
  205. if (!isEmpty() && !Now->isEmpty() &&
  206. getCharacter()->CanAttackForDistance<"Melee">(Now->getdistance_barrier())
  207. ) {
  208. Now->setisMeleeAttackAble(true);
  209. }
  210. if (!isEmpty() && !Now->isEmpty() &&
  211. getCharacter()->CanAttackForDistance<"Range">(Now->getdistance_barrier())
  212. ) {
  213. Now->setisRangeAttackAble(true);
  214. }
  215. }
  216. void Cell::recalcMoveable_(Cell * Now){
  217. if(Now == nullptr || Now->isEmpty() || isEmpty())return;
  218. getCharacter()->CanMoveForDistance()
  219. }
  220. void Cell::updateMoveableCells_(std::queue<Cell*> & Q) {
  221. std::queue<Cell*> q;
  222. q.push(this);
  223. setdistance_barrier(0);
  224. auto f = [&q, &Q](Cell * t, Cell * parent) {
  225. if (t && !t->AddedToQuery_) {
  226. t->AddedToQuery_ = true;
  227. if (t->getCharacter() != NULL) {
  228. Q.push(t);
  229. return;
  230. }
  231. q.push(t);
  232. t->setdistance_barrier(
  233. parent->getdistance_barrier() + 1
  234. );
  235. }
  236. };
  237. while (!q.empty()) {
  238. Cell * Now = q.front();
  239. Now->setisMoveAble();
  240. recalcAttackable_(Now);
  241. q.pop();
  242. f(Now->getleftUp(), Now);
  243. f(Now->getleft(), Now);
  244. f(Now->getleftDown(), Now);
  245. f(Now->getrightUp(), Now);
  246. f(Now->getright(), Now);
  247. f(Now->getrightDown(), Now);
  248. }
  249. }
  250. void Cell::updateUnMovealeCells_(std::queue<Cell*> & Q) {
  251. auto f = [&Q](Cell * t, Cell * parent) {
  252. if (t && !t->AddedToQuery_) {
  253. t->AddedToQuery_ = true;
  254. Q.push(t);
  255. }
  256. };
  257. while (!Q.empty()) {
  258. Cell * Now = Q.front();
  259. Now->setisMoveable(false);
  260. Now->setisAttackable(false);
  261. Q.pop();
  262. f(Now->getleftUp(), Now);
  263. f(Now->getleft(), Now);
  264. f(Now->getleftDown(), Now);
  265. f(Now->getrightUp(), Now);
  266. f(Now->getright(), Now);
  267. f(Now->getrightDown(), Now);
  268. }
  269. }