main.cpp 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. public:
  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. // funkcja sprawdzająca czy wywołujący obiekt jest w wektorze
  19. bool czyNaLiscie(vector<Kratka*> lista) {
  20. for (auto elem: lista)
  21. if (elem == this) return true;
  22. return false;
  23. }
  24. // funkcja obliczająca fCost i osadzający tę wartość w wywołującym obiekcie
  25. void fCost(Kratka *celKratka) {
  26. double h_cost = sqrt(pow((this->x - celKratka->x), 2) + pow((this->y - celKratka->y), 2));
  27. this->g = this->rodzic->g + 1;
  28. this->f = h_cost + this->g;
  29. }
  30. bool czyOsiagnieto(Kratka *cel){
  31. if(this == cel){
  32. // kontynuuj dopóki rodzic nie jest NULLEM (wraca spowrotem po sciezce i przypisuje wartosci 1)
  33. while (cel->rodzic) {
  34. cel->wartosc = 1;
  35. cel = cel->rodzic;
  36. }
  37. return true;
  38. }
  39. return false;
  40. }
  41. };
  42. /* wektor o wielkości width, przechowujący elementy o wartości vector<Kratka>(height)*/
  43. vector<vector<Kratka>> grid(width, vector<Kratka>(height));
  44. // wektor wskaźników na instancje klasy Kratka
  45. vector<Kratka*> listaOtwarta;
  46. vector<Kratka*> listaZamknieta;
  47. vector<Kratka> listaOtwartaTest;
  48. vector<Kratka> listaZamknietaTest;
  49. void display() { //wyswietla mapę
  50. cout << endl;
  51. for (int i = 0; i < height; i++) {
  52. for (int j = 0; j < width; j++)
  53. cout << grid[j][i].wartosc << " ";
  54. cout << endl;
  55. }
  56. cout << endl;
  57. }
  58. Kratka *fCostMinimalKratka() {
  59. Kratka *min = listaOtwarta[0];
  60. for (auto elem: listaOtwarta)
  61. if (elem->f <= min->f) min = elem;
  62. return min;
  63. }
  64. vector<Kratka*> wyznaczSomsiadow(Kratka *poz){
  65. /* wektor wskaznikow o domyślych wartościach null */
  66. vector<Kratka*> somsiedzi(4, nullptr);
  67. printf("Kratka [%i,%i] ma sąsiadów:\n", poz->x, poz->y);
  68. /* wyznaczamy potencjalnych sąsiadów o ile nie wypadają poza grid */
  69. if (poz->y + 1 < height){
  70. printf("Dół [%i,%i]\n", poz->x, poz->y+1);
  71. /* referencja zwraca adres */
  72. /* wskaznik somsiedzi[0] teraz nosi wartość adresu kratki gridu */
  73. somsiedzi[0] = &grid[poz->x][poz->y + 1];
  74. }
  75. /* lewy sąsiad */
  76. if (poz->x - 1 >= 0){
  77. printf("Lewo [%i,%i]\n", poz->x-1, poz->y);
  78. somsiedzi[1] = &grid[poz->x - 1][poz->y];
  79. }
  80. /* górny sąsiad */
  81. if (poz->y - 1 >= 0){
  82. printf("Góra [%i,%i]\n", poz->x, poz->y-1);
  83. somsiedzi[2] = &grid[poz->x][poz->y - 1];
  84. }
  85. /* prawy sąsiad */
  86. if (poz->x + 1 < width){
  87. printf("Prawo [%i,%i]\n", poz->x+1, poz->y);
  88. somsiedzi[3] = &grid[poz->x + 1][poz->y];
  89. }
  90. return somsiedzi;
  91. }
  92. bool aGwiazdka(int sx, int sy, int cx, int cy) {
  93. Kratka *startKratka = &grid[sx][sy];
  94. Kratka *celKratka = &grid[cx][cy];
  95. listaOtwarta.push_back(startKratka);
  96. listaOtwartaTest.push_back(*startKratka);
  97. while (listaOtwarta.size() > 0) {
  98. Kratka *rozwazanaKratka = fCostMinimalKratka();
  99. printf("Kratka [%i,%i] jest obecnie rozważana\n", rozwazanaKratka->x, rozwazanaKratka->y);
  100. if(rozwazanaKratka->czyOsiagnieto(celKratka)){
  101. startKratka->wartosc = 1;
  102. return true;
  103. }
  104. printf("Kratka [%i,%i] zostaje usunięta z listy otwartej i trafia do listy zamknietej\n", rozwazanaKratka->x, rozwazanaKratka->y);
  105. listaOtwarta.erase(std::remove(listaOtwarta.begin(), listaOtwarta.end(), rozwazanaKratka), listaOtwarta.end());
  106. listaZamknieta.push_back(rozwazanaKratka);
  107. listaZamknietaTest.push_back(*rozwazanaKratka);
  108. /* wektor wskaznikow na obiekty Kratka */
  109. vector<Kratka*> somsiadKratka = wyznaczSomsiadow(rozwazanaKratka);
  110. for (auto elem: somsiadKratka) {
  111. /* jezeli sasiad ma wartosc null (poza mapą) */
  112. if (elem == nullptr || elem->wartosc == 5 || elem->czyNaLiscie(listaZamknieta))
  113. continue;
  114. /* gcost +=1 ponieważ jest sąsiadem czyli oddalone o jedną kratkę */
  115. if (rozwazanaKratka->g + 1 < elem->g || elem->czyNaLiscie(listaOtwarta) == false) {
  116. elem->rodzic = rozwazanaKratka;
  117. elem->fCost(celKratka);
  118. printf("Rodzicem kratki[%i,%i] staje się kratka [%i,%i]\n", elem->x, elem->y, rozwazanaKratka->x, rozwazanaKratka->y);
  119. if(elem->czyNaLiscie(listaOtwarta) == false){
  120. printf("Kratka [%i,%i] trafia do listy otwartej\n", elem->x, elem->y);
  121. listaOtwarta.push_back(elem);
  122. listaOtwartaTest.push_back(*elem);
  123. }
  124. }
  125. }
  126. }
  127. return false;
  128. }
  129. void loadFile(string name) {
  130. ifstream file(name);
  131. char temp;
  132. for (int y = 0; y < height; y++) {
  133. for (int x = 0; x < width; x++) {
  134. file >> temp;
  135. grid[x][y].wartosc = temp - '0';
  136. grid[x][y].x = x;
  137. grid[x][y].y = y;
  138. }
  139. }
  140. file.close();
  141. }
  142. void zaznaczOdwiedzone(){
  143. int o = 2, z = 3;
  144. for(auto elem: listaOtwartaTest)
  145. if(grid[elem.x][elem.y].wartosc != 1)
  146. grid[elem.x][elem.y].wartosc = o;
  147. for(auto elem: listaZamknietaTest)
  148. if(grid[elem.x][elem.y].wartosc != 1)
  149. grid[elem.x][elem.y].wartosc = z;
  150. }
  151. int main() {
  152. bool wynik;
  153. /* loadFile("grid_video.txt"); */
  154. /* wynik = aGwiazdka(7,4,4,1); */
  155. /* loadFile("grid_small.txt"); */
  156. /* wynik = aGwiazdka(1,2,5,1); */
  157. loadFile("grid.txt");
  158. wynik=aGwiazdka(0,19,19,0);
  159. wynik ? cout << "SCIEŻKA ZNALEZIONA" << endl : cout << "SCIEŻKA NIE ZNALEZIONA" << endl;
  160. /* a > b ? a : b; */
  161. /* zaznaczOdwiedzone(); */
  162. display();
  163. return 0;
  164. }