Advertisement
marrruuuuuuuu

A_star

Jan 18th, 2021
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.37 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <functional>
  4.  
  5. const int N = 10;
  6.  
  7. enum class CellType : unsigned char
  8. {
  9. Empty,
  10. Rock,
  11. Apple,
  12. Bomb,
  13. Unknown
  14. };
  15.  
  16. class Cell final
  17. {
  18. public:
  19. Cell() = default;
  20.  
  21. CellType GetType() const;
  22. void SetType(CellType type);
  23.  
  24. //Robot* GetRobot() const;
  25. // void SetRobot(Robot* entity);
  26.  
  27. private:
  28. //Robot* m_robotOnCell{ nullptr };
  29. CellType m_type{ CellType::Unknown };
  30. };
  31.  
  32.  
  33. class Terrain final
  34. {
  35. using TMap = std::vector<std::vector<Cell>>;
  36. public:
  37. Terrain(TMap&& map);
  38. Terrain();
  39.  
  40. void Resize(size_t x, size_t y);
  41.  
  42. std::size_t GetSizeX() const;
  43. std::size_t GetSizeY() const;
  44.  
  45. Cell& GetCell(size_t x, size_t y);
  46. const Cell& GetCell(size_t x, size_t y) const;
  47.  
  48. const TMap& GetMap() const;
  49. private:
  50. TMap m_map;
  51. };
  52.  
  53.  
  54.  
  55. enum class Direction : unsigned char
  56. {
  57. Left,
  58. Right,
  59. Up,
  60. Down
  61. };
  62.  
  63.  
  64. typedef struct Node{
  65. Node* parent;
  66. std:: pair <int, int> coords;
  67. int g;
  68. int h;
  69. CellType cell;
  70. } Node;
  71.  
  72. Direction toDirection(std::pair<int, int> move){
  73. if ( move.first == 1 && move.second == 0) return Direction::Left;
  74. else if (move.first == -1 && move.second == 0) return Direction::Right;
  75. else if (move.first == 0 && move.second == 1) return Direction::Down;
  76. else if(move.first == 0 && move.second == -1) return Direction::Up;
  77.  
  78. }
  79.  
  80. int heuristic(std::pair<int, int> c1, std::pair<int, int> c2){
  81. return abs(c1.first - c2.first) + abs(c1.second - c2.second);
  82. }
  83.  
  84. Node* findNodeInList(std::vector<Node*> list, std::pair<int, int> coords) {
  85. for (auto &node : list) {
  86. if ((node->coords.first == coords.first) && (node->coords.second == coords.second)) {
  87. return node;
  88. }
  89. }
  90. return nullptr;
  91. }
  92.  
  93. std::vector<std::pair<int,int>> getCellGoodNeighbours(Node curr, std::pair<int, int> dest, Terrain map){
  94. std::vector<std::pair<int,int>> good_neighbours;
  95. Cell c1, c2, c3, c4;
  96. c1 = map.GetCell(curr.coords.first + 1, curr.coords.second);
  97. c2 = map.GetCell(curr.coords.first - 1, curr.coords.second);
  98. c3 = map.GetCell(curr.coords.first, curr.coords.second + 1);
  99. c4 = map.GetCell(curr.coords.first, curr.coords.second - 1);
  100. if ( c1.GetType() != CellType::Bomb && c1.GetType() != CellType::Rock ){
  101. std::pair<int,int> n = curr.coords;
  102. if ( n == dest) {good_neighbours.push_back(dest); return good_neighbours;}
  103. n.first++;
  104. good_neighbours.push_back(n);
  105. }
  106. if ( c2.GetType() != CellType::Bomb && c2.GetType() != CellType::Rock ){
  107. std::pair<int,int> n = curr.coords;
  108. if ( n == dest) {good_neighbours.push_back(dest); return good_neighbours;}
  109. n.first--;
  110. good_neighbours.push_back(n);
  111. }
  112. if ( c3.GetType() != CellType::Bomb && c3.GetType() != CellType::Rock ){
  113. std::pair<int,int> n = curr.coords;
  114. if ( n == dest) {good_neighbours.push_back(dest); return good_neighbours;}
  115. n.second++;
  116. good_neighbours.push_back(n);
  117. }
  118. if ( c4.GetType() != CellType::Bomb && c4.GetType() != CellType::Rock ){
  119. std::pair<int,int> n = curr.coords;
  120. if ( n == dest) {good_neighbours.push_back(dest); return good_neighbours;}
  121. n.second--;
  122. good_neighbours.push_back(n);
  123. }
  124. return good_neighbours;
  125. }
  126.  
  127.  
  128.  
  129. std::vector<Direction> aStarSearch(
  130. Terrain* map,
  131. std::pair<int, int> start,
  132. std::pair<int, int> dest/*,
  133. std::function<bool(std::pair<int, int>)> isRobot*/)
  134. {
  135. std::vector<Node*> open, closed;
  136.  
  137. Node* startNode = new Node {nullptr, start, 0, 0};
  138. open.push_back(startNode);
  139.  
  140. Node* current;
  141.  
  142. while (!open.empty()) {
  143.  
  144. auto currentIt = open.begin();
  145. current = *currentIt;
  146.  
  147. for (auto it = open.begin(); it != open.end(); ++it) {
  148. auto node = *it;
  149. if (node->g + node->h < current->g + current->h || (
  150. node->g + node->h == current->g + current->h &&
  151. node->h < current->h)
  152. ) {
  153. current = node;
  154. currentIt = it;
  155. }
  156. }
  157.  
  158. open.erase(currentIt);
  159. closed.push_back(current);
  160.  
  161. if ((current->coords.first == dest.first) && (current->coords.second == dest.second)){
  162. break;
  163. }
  164.  
  165. auto neighbours = getCellGoodNeighbours(*current, dest, *map);
  166. for (auto& neighbourCoords : neighbours) {
  167.  
  168. if (findNodeInList(closed, neighbourCoords) != nullptr /*|| (
  169. isRobot != nullptr && isRobot(neighbourCoords))*/
  170. ) {
  171. continue;
  172. }
  173.  
  174. Node* successor = findNodeInList(open, neighbourCoords);
  175. if (successor == nullptr) {
  176. successor = new Node {
  177. current,
  178. neighbourCoords,
  179. current->g + 1,
  180. heuristic(neighbourCoords, dest)
  181. };
  182. open.push_back(successor);
  183. }
  184. else if (current->g + 1 < successor->g) {
  185. successor->parent = current;
  186. successor->g = current->g + 1;
  187. }
  188. }
  189. }
  190.  
  191. if ((current->coords.first != dest.first) || (current->coords.second != dest.second)) {
  192. std::cout <<"Last is not equal to destination" << std :: endl;
  193. }
  194.  
  195. std::vector<Direction> way;
  196. while (current->parent != nullptr) {
  197. std::pair<int, int> move;
  198. move.first = current->coords.first - current->parent->coords.first;
  199. move.second = current->coords.second - current->parent->coords.second;
  200. auto dir = toDirection(move);
  201. way.push_back(dir);
  202. current = current->parent;
  203. }
  204.  
  205. return way;
  206. }
  207.  
  208.  
  209.  
  210. int main() {
  211. const int N = 10;
  212. std::vector<std::vector<Node>> map(N, std::vector<Node>(N));
  213.  
  214. std:: cout << " 0 1 2 3 4 5 6 7 8 9" << std:: endl;
  215. for (size_t h = 0; h < 10; h ++){
  216. char c;
  217. c = 'A' + h;
  218. std::cout << c ;
  219. for (size_t w = 0; w < 10; w++){
  220. map[h][w].cell = CellType::Empty;
  221. //std::cout << " " << map[h][w]<< " ";
  222. }
  223. std::cout << std::endl;
  224. }
  225. std::cout << std::endl;
  226.  
  227. return 0;
  228. }
  229.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement