Advertisement
radmickey

Untitled

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