copy.cpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include <iostream>
  2. #include <fstream>
  3. #include <math.h>
  4. #include <vector>
  5. #include <algorithm>
  6. using namespace std;
  7. /* int const height = 6, width = 6; */
  8. /* int const height = 6, width = 11; */
  9. int const height = 20, width = 20;
  10. class Kratka {
  11. private:
  12. int wartosc; // zmienna na zaznaczenie scieżki
  13. double g = 0; // odleglosc rozwazanej kratki od punktu startKratkaowego
  14. double f = 0; // odleglosc rozwazanej kratki od punktu koncowego
  15. int x; //położenie na mapie
  16. int y; //położenie na mapie
  17. Kratka *rodzic = nullptr;
  18. public:
  19. void setter(int x, int y, int wartosc){
  20. this -> x = x;
  21. this -> y = y;
  22. this -> wartosc = wartosc;
  23. }
  24. void setX(int x){
  25. this -> x = x;
  26. }
  27. void setY(int y){
  28. this -> y = y;
  29. }
  30. void setWartosc(int wartosc){
  31. this -> wartosc = wartosc;
  32. }
  33. void setF(int f){
  34. this -> f = f;
  35. }
  36. void setRodzic(Kratka* rodzic){
  37. this -> rodzic = rodzic;
  38. }
  39. int getX(){
  40. return this->x;
  41. }
  42. int getY(){
  43. return this->y;
  44. }
  45. int getWartosc(){
  46. return this->wartosc;
  47. }
  48. int getF(){
  49. return this->f;
  50. }
  51. int getG(){
  52. return this->g;
  53. }
  54. Kratka* getRodzic(){
  55. return this->rodzic;
  56. }
  57. // funkcja sprawdzająca czy wywołujący obiekt jest w wektorze
  58. bool czyNaLiscie(vector<Kratka*> lista) {
  59. for (auto elem: lista)
  60. if (elem == this) return true;
  61. return false;
  62. }
  63. // funkcja obliczająca fCost i osadzający tę wartość w wywołującym obiekcie
  64. void fCost(Kratka *celKratka) {
  65. double h_cost = sqrt(pow((this->x - celKratka->x), 2) + pow((this->y - celKratka->y), 2));
  66. this->g = this->rodzic->g + 1;
  67. this->f = h_cost + this->g;
  68. }
  69. bool czyOsiagnieto(Kratka *cel){
  70. if(this == cel){
  71. // kontynuuj dopóki rodzic nie jest NULLEM (wraca spowrotem po sciezce i przypisuje wartosci 1)
  72. while (cel->rodzic) {
  73. cel->wartosc = 1;
  74. cel = cel->rodzic;
  75. }
  76. return true;
  77. }
  78. return false;
  79. }
  80. };
  81. /* wektor o wielkości width, przechowujący elementy o wartości vector<Kratka>(height)*/
  82. vector<vector<Kratka>> grid(width, vector<Kratka>(height));
  83. // wektor wskaźników na instancje klasy Kratka
  84. vector<Kratka*> listaOtwarta;
  85. vector<Kratka*> listaZamknieta;
  86. vector<Kratka> listaOtwartaTest;
  87. vector<Kratka> listaZamknietaTest;
  88. void display() { //wyswietla mapę
  89. cout << endl;
  90. for (int i = 0; i < height; i++) {
  91. for (int j = 0; j < width; j++)
  92. cout << grid[j][i].getWartosc() << " ";
  93. cout << endl;
  94. }
  95. cout << endl;
  96. }
  97. Kratka *fCostMinimalKratka() {
  98. Kratka *min = listaOtwarta[0];
  99. for (auto elem: listaOtwarta)
  100. if (elem->getF() <= min->getF()) min = elem;
  101. return min;
  102. }
  103. vector<Kratka*> wyznaczSomsiadow(Kratka *poz){
  104. /* wektor wskaznikow o domyślych wartościach null */
  105. vector<Kratka*> somsiedzi(4, nullptr);
  106. /* printf("Kratka [%i,%i] ma sąsiadów:\n", poz->x, poz->y); */
  107. /* wyznaczamy potencjalnych sąsiadów o ile nie wypadają poza grid */
  108. if (poz->getY() + 1 < height){
  109. /* printf("Dół [%i,%i]\n", poz->getX(), poz->getY()+1); */
  110. /* referencja zwraca adres */
  111. /* wskaznik somsiedzi[0] teraz nosi wartość adresu kratki gridu */
  112. somsiedzi[0] = &grid[poz->getX()][poz->getY() + 1];
  113. }
  114. /* lewgetY() sąsiad */
  115. if (poz->getX() - 1 >= 0){
  116. printf("Lewo [%i,%i]\n", poz->getX()-1, poz->getY());
  117. somsiedzi[1] = &grid[poz->getX() - 1][poz->getY()];
  118. }
  119. /* górngetY() sąsiad */
  120. if (poz->getY() - 1 >= 0){
  121. printf("Góra [%i,%i]\n", poz->getX(), poz->getY()-1);
  122. somsiedzi[2] = &grid[poz->getX()][poz->getY() - 1];
  123. }
  124. /* prawgetY() sąsiad */
  125. if (poz->getX() + 1 < width){
  126. printf("Prawo [%i,%i]\n", poz->getX()+1, poz->getY());
  127. somsiedzi[3] = &grid[poz->getX() + 1][poz->getY()];
  128. }
  129. return somsiedzi;
  130. }
  131. bool aGwiazdka(int sx, int sy, int cx, int cy) {
  132. Kratka *startKratka = &grid[sx][sy];
  133. Kratka *celKratka = &grid[cx][cy];
  134. listaOtwarta.push_back(startKratka);
  135. listaOtwartaTest.push_back(*startKratka);
  136. while (listaOtwarta.size() > 0) {
  137. Kratka *rozwazanaKratka = fCostMinimalKratka();
  138. /* printf("Kratka [%i,%i] jest obecnie rozważana\n", rozwazanaKratka->x, rozwazanaKratka->y); */
  139. if(rozwazanaKratka->czyOsiagnieto(celKratka)){
  140. startKratka->setWartosc(1);
  141. return true;
  142. }
  143. /* printf("Kratka [%i,%i] zostaje usunięta z listy otwartej i trafia do listy zamknietej\n", rozwazanaKratka->x, rozwazanaKratka->y); */
  144. listaOtwarta.erase(std::remove(listaOtwarta.begin(), listaOtwarta.end(), rozwazanaKratka), listaOtwarta.end());
  145. listaZamknieta.push_back(rozwazanaKratka);
  146. listaZamknietaTest.push_back(*rozwazanaKratka);
  147. /* wektor wskaznikow na obiekty Kratka */
  148. vector<Kratka*> somsiadKratka = wyznaczSomsiadow(rozwazanaKratka);
  149. for (auto elem: somsiadKratka) {
  150. /* jezeli sasiad ma wartosc null (poza mapą) */
  151. if (elem == nullptr || elem->getWartosc() == 5 || elem->czyNaLiscie(listaZamknieta))
  152. continue;
  153. /* gcost +=1 ponieważ jest sąsiadem czyli oddalone o jedną kratkę */
  154. if (rozwazanaKratka->getG() + 1 < elem->getG() || elem->czyNaLiscie(listaOtwarta) == false) {
  155. elem->setRodzic(rozwazanaKratka);
  156. elem->fCost(celKratka);
  157. /* printf("Rodzicem kratki[%i,%i] staje się kratka [%i,%i]\n", elem->x, elem->y, rozwazanaKratka->x, rozwazanaKratka->y); */
  158. if(elem->czyNaLiscie(listaOtwarta) == false){
  159. /* printf("Kratka [%i,%i] trafia do listy otwartej\n", elem->x, elem->y); */
  160. listaOtwarta.push_back(elem);
  161. listaOtwartaTest.push_back(*elem);
  162. }
  163. }
  164. }
  165. }
  166. return false;
  167. }
  168. void loadFile(string name) {
  169. ifstream file(name);
  170. char temp;
  171. for (int y = 0; y < height; y++) {
  172. for (int x = 0; x < width; x++) {
  173. file >> temp;
  174. grid[x][y].setter(x,y, temp - '0');
  175. }
  176. }
  177. file.close();
  178. }
  179. /* void zaznaczOdwiedzone(){ */
  180. /* int o = 2, z = 3; */
  181. /* for(auto elem: listaOtwartaTest) */
  182. /* if(grid[elem.x][elem.y].wartosc != 1) */
  183. /* grid[elem.x][elem.y].wartosc = o; */
  184. /* for(auto elem: listaZamknietaTest) */
  185. /* if(grid[elem.x][elem.y].wartosc != 1) */
  186. /* grid[elem.x][elem.y].wartosc = z; */
  187. /* } */
  188. int main() {
  189. bool wynik;
  190. /* loadFile("grid_video.txt"); */
  191. /* wynik = aGwiazdka(7,4,4,1); */
  192. /* loadFile("grid_small.txt"); */
  193. /* wynik = aGwiazdka(1,2,5,1); */
  194. loadFile("grid.txt");
  195. wynik=aGwiazdka(0,19,19,0);
  196. wynik ? cout << "SCIEŻKA ZNALEZIONA" << endl : cout << "SCIEŻKA NIE ZNALEZIONA" << endl;
  197. /* zaznaczOdwiedzone(); */
  198. display();
  199. return 0;
  200. }