Advertisement
tslipa

a*2

Nov 10th, 2021 (edited)
737
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.70 KB | None | 0 0
  1. struct state
  2. {
  3.     state *father;
  4.     unsigned short g;
  5.     unsigned short h;
  6.     unsigned short fields[16];
  7. };
  8.  
  9. struct compareWeight
  10. {
  11.     bool operator()(state const *s1, state const *s2)
  12.     {
  13.         return s1->g + s1->h < s2->g + s2->h;
  14.     }
  15. };
  16.  
  17. std::multiset<state*, compareWeight> openStates;
  18.  
  19. std::vector<state*> closedStates;
  20.  
  21. int getManhattanValue(state *currentState)
  22. {
  23.     int result = 0;
  24.     for (int j = 0; j < size; j++)
  25.     {
  26.         if (currentState->fields[j] != 0)
  27.         {
  28.             unsigned short value = (currentState->fields[j] + size - 1) % size;
  29.             unsigned short xGoal = value / side;
  30.             unsigned short yGoal = value % side;
  31.             unsigned short xActual = j / side;
  32.             unsigned short yActual = j % side;
  33.             result += abs(xGoal - xActual) + abs(yGoal - yActual);
  34.         }
  35.     }
  36.     return result;
  37. }
  38.  
  39. getMisplacedTilesValue(state *currentState)
  40. {
  41.     int result = 0;
  42.     for (int j = 0; j < size; j++)
  43.     {
  44.         if (currentState->fields[j] != 0 && currentState->fields[j] != (j + 1) % 16)
  45.         {
  46.             result += 1;
  47.         }
  48.     }
  49.     return result;
  50. }
  51.  
  52.  
  53.  
  54.  
  55. void aStar(int maximumNumberOfMoves, bool isManhattan)
  56. {
  57.     state *initialState = new state;
  58.     getInitialState(initialState, maximumNumberOfMoves);
  59.     initialState->g = 0;
  60.     initialState->h = getManhattanValue(initialState);
  61.     initialState->father = NULL;
  62.  
  63.     openStates.insert(initialState);
  64.  
  65.     std::cout << "Stan poczatkowy:\n";
  66.     for (int i = 0; i < side; i++)
  67.     {
  68.         for (int j = 0; j < side; j++)
  69.         {
  70.             std::cout << initialState->fields[i * side + j] << " ";
  71.         }
  72.         std::cout << "\n";
  73.     }
  74.     std::cout << "\n" << "h = " << initialState->h << "\n";
  75.  
  76.     while (!openStates.empty())
  77.     {
  78.         state* currentState = (state*) (*openStates.begin());
  79.  
  80.         openStates.erase(openStates.begin());
  81.         closedStates.push_back(currentState);
  82.  
  83.         if (isFinalState(currentState))
  84.         {
  85.             std::cout << "\nPrzesuniecia:  ";
  86.             getAndPrintRoute(currentState);
  87.             std::cout << "\nLiczba przesuniec:  " << counter << "\n";
  88.             cleanMemory();
  89.             return;
  90.         }
  91.  
  92.         unsigned short posZero = 0;
  93.  
  94.         for (int i = 0; i < size; i++)
  95.         {
  96.             if (currentState->fields[i] == 0)
  97.             {
  98.                 posZero = i;
  99.                 break;
  100.             }
  101.         }
  102.  
  103.         for (int i = 0; i < 4; i++)
  104.         {
  105.             int newPosZero;
  106.             if (i == 0 && posZero / side != 0)
  107.             {
  108.                 newPosZero = posZero - side;
  109.             }
  110.             else if (i == 1 && posZero / side != side - 1)
  111.             {
  112.                 newPosZero = posZero + side;
  113.             }
  114.             else if (i == 2 && posZero % side != 0)
  115.             {
  116.                 newPosZero = posZero - 1;
  117.             }
  118.             else if (i == 3 && posZero % side != side - 1)
  119.             {
  120.                 newPosZero = posZero + 1;
  121.             }
  122.             else
  123.             {
  124.                 continue;
  125.             }
  126.  
  127.             unsigned short newFields[size];
  128.             for (int j = 0; j < size; j++)
  129.             {
  130.                 newFields[j] = currentState->fields[j];
  131.             }
  132.             std::swap(newFields[posZero], newFields[newPosZero]);
  133.  
  134.             std::vector<state*>::iterator it = closedStates.begin();
  135.  
  136.             bool isInClosed = false;
  137.             while (it != closedStates.end())
  138.             {
  139.                 bool isEqual = true;
  140.                 for (int j = 0; j < size; j++)
  141.                 {
  142.                     if ((*it)->fields[j] != newFields[j])
  143.                     {
  144.                         isEqual = false;
  145.                         break;
  146.                     }
  147.                 }
  148.  
  149.                 if (isEqual)
  150.                 {
  151.                     isInClosed = true;
  152.                     break;
  153.                 }
  154.                 it++;
  155.             }
  156.             if (isInClosed)
  157.             {
  158.                 continue;
  159.             }
  160.  
  161.             state *newState;
  162.             std::multiset<state*>::iterator it2 = openStates.begin();
  163.  
  164.             bool isInOpen = false;
  165.             while (it2 != openStates.end())
  166.             {
  167.                 bool isEqual = true;
  168.                 for (int j = 0; j < size; j++)
  169.                 {
  170.                     if ((*it2)->fields[j] != newFields[j])
  171.                     {
  172.                         isEqual = false;
  173.                         break;
  174.                     }
  175.                 }
  176.  
  177.                 if (isEqual)
  178.                 {
  179.                     isInOpen = true;
  180.                     newState = (state *)&(*it2);
  181.                     break;
  182.                 }
  183.                 it2++;
  184.             }
  185.             if (!isInOpen)
  186.             {
  187.                 newState = new state;
  188.                 for (int j = 0; j < size; j++)
  189.                 {
  190.                     newState->fields[j] = newFields[j];
  191.                 }
  192.                 newState->g = INT16_MAX;
  193.                 newState->h = INT16_MAX;
  194.             }
  195.  
  196.             int newG = currentState->g + 1;
  197.             if (newG < newState->g)
  198.             {
  199.                 newState->g = newG;
  200.                 if (isManhattan)
  201.                 {
  202.                     newState->h = getManhattanValue(newState);
  203.                 }
  204.                 else
  205.                 {
  206.                     newState->h = getMisplacedTilesValue(newState);
  207.                 }
  208.  
  209.                 newState->father = currentState;
  210.             }
  211.  
  212.             if (!isInOpen)
  213.             {
  214.                 openStates.insert(newState);
  215.             }
  216.         }
  217.     }
  218. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement