Advertisement
radmickey

Untitled

Feb 7th, 2023
895
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.65 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <algorithm>
  4. #include <vector>
  5. #include <unordered_set>
  6. #include <unordered_map>
  7. #include <stack>
  8. #include <deque>
  9. #include <cmath>
  10.  
  11. using namespace std;
  12.  
  13. void lTRIMALLL(std::string &s) {
  14.     s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
  15.         return !std::isspace(ch);
  16.     }));
  17. }
  18.  
  19. void rTRIMALLL(std::string &s) {
  20.     s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
  21.         return !std::isspace(ch);
  22.     }).base(), s.end());
  23. }
  24.  
  25. void TRIMALLL(std::string &s) {
  26.     rTRIMALLL(s);
  27.     lTRIMALLL(s);
  28. }
  29.  
  30. vector<string> split(string& s, const string& delimiter) {
  31.     vector<string> result;
  32.     size_t pos = 0;
  33.     std::string token;
  34.     while ((pos = s.find(delimiter)) != std::string::npos) {
  35.         token = s.substr(0, pos);
  36.         TRIMALLL(token);
  37.         result.push_back(token);
  38.         s.erase(0, pos + delimiter.length());
  39.     }
  40.  
  41.     result.push_back(s);
  42.  
  43.     return result;
  44. }
  45.  
  46. struct Robot;
  47. int robotCheck(int x, int y, const vector<Robot*>& r);
  48.  
  49. struct Robot {
  50.     int X, Y, hp, lastRound;
  51.     char direction;
  52.     bool d = false, onTheBoard = true;
  53.     string dStatus = "ACTIVE";
  54.     vector<pair<int, string>> actions;
  55.  
  56.     explicit Robot(int x, int y, int hp, char a) {
  57.         X = x;
  58.         Y = y;
  59.         direction = a;
  60.         this->hp = hp;
  61.     }
  62.  
  63.     void turnFull(int round) {
  64.         if (d)
  65.             return;
  66.  
  67.         lastRound = round;
  68.         if (direction == 'L') {
  69.             direction = 'R';
  70.         } else if (direction == 'R') {
  71.             direction = 'L';
  72.         } else if (direction == 'U') {
  73.             direction = 'D';
  74.         } else if (direction == 'D') {
  75.             direction = 'U';
  76.         }
  77.     }
  78.  
  79.     void turnLeft(int round) {
  80.         if (d)
  81.             return;
  82.  
  83.         lastRound = round;
  84.         if (direction == 'L') {
  85.             direction = 'D';
  86.         } else if (direction == 'R') {
  87.             direction = 'U';
  88.         } else if (direction == 'D') {
  89.             direction = 'R';
  90.         } else if (direction == 'U') {
  91.             direction = 'L';
  92.         }
  93.     }
  94.  
  95.     void turnRight(int round) {
  96.         if (d)
  97.             return;
  98.  
  99.         lastRound = round;
  100.         // Поворот на 90 вправо
  101.         if (direction == 'L') {
  102.             direction = 'U';
  103.         } else if (direction == 'R') {
  104.             direction = 'D';
  105.         } else if (direction == 'U') {
  106.             direction = 'R';
  107.         } else if (direction == 'D') {
  108.             direction = 'L';
  109.         }
  110.     }
  111.  
  112.     bool go(char dir, const vector<string>& f, const vector<Robot*>& r, int round) {
  113.         if (d)
  114.             return true;
  115.  
  116.         lastRound = round;
  117.         // Идем вперед
  118.         if (dir == 'L') {
  119.             if (Y - 1 < 0) {
  120.                 dStatus = "FALL";
  121.                 d = true;
  122.                 onTheBoard = false;
  123.                 hp = -1;
  124.                 return true;
  125.             }
  126.             if (f[X][Y - 1] == 'W') {
  127.                 --hp;
  128.                 if (hp <= 0) {
  129.                     dStatus = "COLLISION";
  130.                     d = true;
  131.                 }
  132.                 return false;
  133.             }
  134.  
  135.             int playerIndex = robotCheck(X, Y - 1, r);
  136.             if (playerIndex != -1) {
  137.                 bool flag = r[playerIndex]->go(dir, f, r, round);
  138.                 if (flag) {
  139.                     --Y;
  140.                 }
  141.                 return flag;
  142.             }
  143.  
  144.             --Y;
  145.             return true;
  146.         } else if (dir == 'R') {
  147.             if (Y + 1 >= f[0].size()) {
  148.                 dStatus = "FALL";
  149.                 onTheBoard = false;
  150.                 d = true;
  151.                 hp = -1;
  152.                 return true;
  153.             }
  154.  
  155.             if (f[X][Y + 1] == 'W') {
  156.                 --hp;
  157.                 if (hp <= 0) {
  158.                     d = true;
  159.                     dStatus = "COLLISION";
  160.                 }
  161.                 return false;
  162.             }
  163.             int playerIndex = robotCheck(X, Y + 1, r);
  164.             if (playerIndex != -1) {
  165.                 bool flag = r[playerIndex]->go(dir, f, r, round);
  166.                 if (flag) {
  167.                     ++Y;
  168.                 }
  169.                 return flag;
  170.             }
  171.  
  172.             ++Y;
  173.             return true;
  174.         } else if (dir == 'U') {
  175.             if (X - 1 < 0) {
  176.                 dStatus = "FALL";
  177.                 onTheBoard = false;
  178.                 d = true;
  179.                 hp = -1;
  180.                 return true;
  181.             }
  182.  
  183.             if (f[X - 1][Y] == 'W') {
  184.                 --hp;
  185.                 if (hp <= 0) {
  186.                     d = true;
  187.                     dStatus = "COLLISION";
  188.                 }
  189.                 return false;
  190.             }
  191.             int playerIndex = robotCheck(X - 1, Y, r);
  192.             if (playerIndex != -1) {
  193.                 bool flag = r[playerIndex]->go(dir, f, r, round);
  194.                 if (flag) {
  195.                     --X;
  196.                 }
  197.                 return flag;
  198.             }
  199.  
  200.             --X;
  201.             return true;
  202.         } else if (dir == 'D') {
  203.             if (X + 1 >= f.size()) {
  204.                 dStatus = "FALL";
  205.                 onTheBoard = false;
  206.                 d = true;
  207.                 hp = -1;
  208.                 return true;
  209.             }
  210.  
  211.             if (f[X + 1][Y] == 'W') {
  212.                 --hp;
  213.                 if (hp <= 0) {
  214.                     d = true;
  215.                     dStatus = "COLLISION";
  216.                 }
  217.                 return false;
  218.             }
  219.             int playerIndex = robotCheck(X + 1, Y, r);
  220.             if (playerIndex != -1) {
  221.                 bool flag = r[playerIndex]->go(dir, f, r, round);
  222.                 if (flag) {
  223.                     ++X;
  224.                 }
  225.                 return flag;
  226.             }
  227.  
  228.             ++X;
  229.             return true;
  230.         }
  231.  
  232.         return true;
  233.     }
  234.  
  235.     void moveBackward(char dir, const vector<string>& f, const vector<Robot*>& r, int round) {
  236.         if (d)
  237.             return;
  238.  
  239.         lastRound = round;
  240.         if (dir == 'L')
  241.             go('R', f, r, round);
  242.         else if (dir == 'R')
  243.             go('L', f, r, round);
  244.         else if (dir == 'U')
  245.             go('D', f, r, round);
  246.         else
  247.             go('U', f, r, round);
  248.     }
  249. };
  250.  
  251. int robotCheck(int x, int y, const vector<Robot*>& r) {
  252.     for (int i = 0; i < (int)r.size(); ++i) {
  253.         if (r[i]->X == x && r[i]->Y == y && r[i]->onTheBoard)
  254.             return i;
  255.     }
  256.  
  257.     return -1;
  258. }
  259.  
  260. struct Game {
  261.     string name;
  262.     int fHeight = 0, fWidth = 0;
  263.     int pNumber = 0, MN = 0, rN = 0;
  264.     int cardsOnMove, moveCNT = 0;
  265.     vector<string> f = {};
  266.     vector<Robot*> p = {};
  267.  
  268.     explicit Game(const string& x) {
  269.          name = x;
  270.          string line;
  271. //         cin >> line;
  272.          int hp;
  273.          // Вводим данные поля
  274.          cin >> fHeight >> fWidth;
  275.          for (int i = 0; i < fHeight; ++i) {
  276.              cin >> line;
  277.              f.push_back(line);
  278.          }
  279.          // Вводим данные о каждом роботе
  280.          cin >> pNumber >> hp;
  281.          for (int i = 0; i < pNumber; ++i) {
  282.              int posX, posY;
  283.              char direction;
  284.              cin >> posX >> posY >> direction;
  285.              auto* robot = new Robot(posX - 1, posY - 1, hp, direction);
  286.              p.push_back(robot);
  287.          }
  288.          // Вводим ходы
  289.          // Важно, что в строку задаются действия игрока в определенный ход
  290.          cin >> MN >> cardsOnMove;
  291.          for (int i = 0; i < MN; ++i) {
  292.              cin >> line;
  293.              getline(cin, line);
  294.              for (int j = 0; j < pNumber; ++j) {
  295.                  getline(cin, line);
  296.                  auto firstSplit = split(line, "->");
  297.                  for (auto& item: firstSplit) {
  298.                      TRIMALLL(item);
  299.                      auto secondSplit = split(item, " ");
  300.                      pair<int, string> pair;
  301.                      if (secondSplit.size() == 2)
  302.                         pair = make_pair(stoi(secondSplit[1]), secondSplit[0]);
  303.                      else
  304.                          pair = make_pair(stoi(secondSplit[2]), secondSplit[0] + " " + secondSplit[1]);
  305.                      p[j]->actions.push_back(pair);
  306.                  }
  307.              }
  308.          }
  309.     }
  310.  
  311.     void makeAction() {
  312.          vector<pair<pair<int, string>, int>> curr_ways;
  313.  
  314.          for (int i = 0; i < pNumber; ++i) {
  315.              curr_ways.emplace_back(p[i]->actions[moveCNT], i);
  316.          }
  317.  
  318.          sort(curr_ways.begin(), curr_ways.end());
  319.          for (const auto& way: curr_ways) {
  320.              if (way.first.second == "uturn") {
  321.                  p[way.second]->turnFull(rN);
  322.              } else if (way.first.second == "turn right") {
  323.                  p[way.second]->turnRight(rN);
  324.              } else if (way.first.second == "turn left") {
  325.                  p[way.second]->turnLeft(rN);
  326.              } else if (way.first.second == "move forward") {
  327.                  p[way.second]->go(p[way.second]->direction, f, p, rN);
  328.              } else if (way.first.second == "move backward") {
  329.                  p[way.second]->moveBackward(p[way.second]->direction, f, p, rN);
  330.              }
  331.          }
  332.  
  333.          up();
  334.     }
  335.  
  336.     void shot() {
  337.         for (int i = 0; i < pNumber; ++i) {
  338.             if (p[i]->d)
  339.                 continue;
  340.  
  341.             if (p[i]->direction == 'L') {
  342.                 int j = p[i]->Y - 1;
  343.                 while (j >= 0) {
  344.                     int playerIndex = robotCheck(p[i]->X, j, p);
  345.                     if (playerIndex != -1) {
  346.                         if (p[playerIndex]->d) {
  347.                             break;
  348.                         }
  349.                         --p[playerIndex]->hp;
  350.                         if (p[playerIndex]->hp <= 0) {
  351.                             p[playerIndex]->d = true;
  352.                             p[playerIndex]->dStatus = "LASER";
  353.                         }
  354.                         break;
  355.                     }
  356.                     if (f[p[i]->X][j] == 'W') {
  357.                         break;
  358.                     }
  359.                     --j;
  360.                 }
  361.             } else if (p[i]->direction == 'R') {
  362.                 int j = p[i]->Y + 1;
  363.                 while (j < fWidth) {
  364.                     int playerIndex = robotCheck(p[i]->X, j, p);
  365.                     if (playerIndex != -1) {
  366.                         if (p[playerIndex]->d) {
  367.                             break;
  368.                         }
  369.                         --p[playerIndex]->hp;
  370.                         if (p[playerIndex]->hp <= 0) {
  371.                             p[playerIndex]->d = true;
  372.                             p[playerIndex]->dStatus = "LASER";
  373.                         }
  374.                         break;
  375.                     }
  376.                     if (f[p[i]->X][j] == 'W') {
  377.                         break;
  378.                     }
  379.                     ++j;
  380.                 }
  381.             } else if (p[i]->direction == 'U') {
  382.                 int j = p[i]->X - 1;
  383.                 while (j >= 0) {
  384.                     int playerIndex = robotCheck(j, p[i]->Y, p);
  385.                     if (playerIndex != -1) {
  386.                         if (p[playerIndex]->d) {
  387.                             break;
  388.                         }
  389.                         --p[playerIndex]->hp;
  390.                         if (p[playerIndex]->hp <= 0) {
  391.                             p[playerIndex]->d = true;
  392.                             p[playerIndex]->dStatus = "LASER";
  393.                         }
  394.                         break;
  395.                     }
  396.                     if (f[j][p[i]->Y] == 'W') {
  397.                         break;
  398.                     }
  399.                     --j;
  400.                 }
  401.             } else {
  402.                 int j = p[i]->X + 1;
  403.                 while (j < fHeight) {
  404.                     int playerIndex = robotCheck(j, p[i]->Y, p);
  405.                     if (playerIndex != -1) {
  406.                         if (p[playerIndex]->d) {
  407.                             break;
  408.                         }
  409.                         --p[playerIndex]->hp;
  410.                         if (p[playerIndex]->hp <= 0) {
  411.                             p[playerIndex]->d = true;
  412.                             p[playerIndex]->dStatus = "LASER";
  413.                         }
  414.                         break;
  415.                     }
  416.                     if (f[j][p[i]->Y] == 'W') {
  417.                         break;
  418.                     }
  419.                     ++j;
  420.                 }
  421.             }
  422.         }
  423.  
  424.         up();
  425.     }
  426.  
  427.     void fEffects() {
  428.         for (const auto& item: p) {
  429.             if (item->d)
  430.                 continue;
  431.             if (f[item->X][item->Y] == '<') {
  432.                 item->go('L', f, p, rN);
  433.             } else if (f[item->X][item->Y] == '>') {
  434.                 item->go('R', f, p, rN);
  435.             } else if (f[item->X][item->Y] == '^') {
  436.                 item->go('U', f, p, rN);
  437.             } else if (string(1, f[item->X][item->Y]) == "v") {
  438.                 item->go('D', f, p, rN);
  439.             } else if (f[item->X][item->Y] == 'T') {
  440.                 --item->hp;
  441.                 if (item->hp <= 0) {
  442.                     item->d = true;
  443.                     item->dStatus = "TRAP";
  444.                 }
  445.             }
  446.         }
  447.     }
  448.  
  449.     void up() {
  450.          for (const auto& item: p) {
  451.              if (item->hp > 0)
  452.                  continue;
  453.  
  454.              item->d = true;
  455.              item->onTheBoard = false;
  456.          }
  457.      }
  458.  
  459.     void play() {
  460.         ++rN;
  461.          for (int i = 0; i < cardsOnMove; ++i) {
  462.              makeAction();
  463.              ++moveCNT;
  464.          }
  465.         fEffects();
  466.         up();
  467.         shot();
  468.      }
  469.  
  470.     void playGame() {
  471.         for (int i = 0; i < MN; ++i) {
  472.             play();
  473.         }
  474.      }
  475. };
  476.  
  477.  
  478. int main() {
  479.     int t;
  480.     string tmp;
  481.     cin >> t;
  482.     vector<Game> ans;
  483.     for (int i = 0; i < t; ++i) {
  484. //        cin >> tmp;
  485.         Game tmpGame = Game("Game " + to_string(i + 1));
  486.         tmpGame.playGame();
  487.         ans.push_back(tmpGame);
  488.     }
  489.  
  490.     for (const auto& item: ans) {
  491.         cout << item.name << endl;
  492.         for (const auto& jitem: item.p) {
  493.             if (jitem->d) {
  494.                 cout << "FAILED on " << jitem->X + 1 << " " << jitem->Y + 1 << " cause " << jitem->dStatus << " step " << jitem->lastRound << endl;
  495.             } else {
  496.                 cout << "ACTIVE on " << jitem->X + 1 << " " << jitem->Y + 1 << " facing " << jitem->direction << " with " << jitem->hp << " HP" << endl;
  497.             }
  498.         }
  499.     }
  500.     return 0;
  501. }
  502.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement