Advertisement
Guest User

Marathon24: CTF

a guest
Dec 1st, 2014
711
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 17.09 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <unistd.h>
  3. #include <sys/time.h>
  4.  
  5. #include "lib.cpp"
  6. #include <CImg.h>
  7. //#include <emmintrin.h>
  8.  
  9. using namespace std;
  10. using namespace cimg_library;
  11.  
  12. #define INLINE   inline __attribute__ ((always_inline))
  13. #define NOINLINE __attribute__ ((noinline))
  14.  
  15. #define ALIGNED __attribute__ ((aligned(16)))
  16.  
  17. #define likely(x)   __builtin_expect(!!(x),1)
  18. #define unlikely(x) __builtin_expect(!!(x),0)
  19.  
  20. #define SSELOAD(a)     _mm_load_si128((__m128i*)&a)
  21. #define SSESTORE(a, b) _mm_store_si128((__m128i*)&a, b)
  22.  
  23. #define FOR(i,a,b)  for(int i=(a);i<(b);++i)
  24. #define REP(i,a)    FOR(i,0,a)
  25. #define ZERO(m)     memset(m,0,sizeof(m))
  26. #define ALL(x)      x.begin(),x.end()
  27. #define PB          push_back
  28. #define S           size()
  29. #define LL          long long
  30. #define ULL         unsigned long long
  31. #define LD          long double
  32. #define MP          make_pair
  33. #define X           first
  34. #define Y           second
  35. #define VC          vector
  36. #define PII         pair <int, int>
  37. #define VI          VC < int >
  38. #define VVI         VC < VI >
  39. #define VVVI        VC < VVI >
  40. #define VPII        VC < PII >
  41. #define VD          VC < double >
  42. #define VVD         VC < VD >
  43. #define VS          VC < string >
  44. #define VVS         VC < VS >
  45. #define DB(a)       cerr << #a << ": " << (a) << endl;
  46.  
  47. template<class T> void print(VC < T > v) {cerr << "[";if (v.S) cerr << v[0];FOR(i, 1, v.S) cerr << ", " << v[i];cerr << "]" << endl;}
  48. template<class T> string i2s(T x) {ostringstream o; o << x; return o.str();}
  49. VS splt(string s, char c = ' ') {VS all; int p = 0, np; while (np = s.find(c, p), np >= 0) {if (np != p) all.PB(s.substr(p, np - p)); p = np + 1;} if (p < s.S) all.PB(s.substr(p)); return all;}
  50.  
  51. double pi = 2.0 * acos(0.0);
  52.  
  53. int cut(int x, double a, int right, int &off) {
  54.   const double EPS = 1E-6;
  55.   double y = tan(a) * x;
  56.   off = 0;
  57.   if (y >= 0.0) {
  58.     int iy = (int) ((y+1.0 + EPS) / 2.0);
  59.     if (fabs(iy * 2.0 - 1.0 - y) < EPS)  {
  60.       if (!right) {
  61.         iy--;
  62.       }
  63.       off=1;
  64.     }
  65.     return iy;
  66.   } else {
  67.     int iy = (int) (-(y-1.0 - EPS) / 2.0);
  68.     iy = -iy;
  69.     if (fabs(iy * 2.0 + 1.0 -y) < EPS) {
  70.       if (!right) {
  71.         iy++;
  72.       }
  73.       off = 1;
  74.     }
  75.     return iy;
  76.   }
  77. }
  78.  
  79. vector<pair<pair<int,int>,int> > cut_line_pom(int angle, int n) {
  80.   vector<pair<pair<int,int>,int > > res;
  81.   res.reserve(n);
  82.   if (angle == 90) {
  83.     for (int i = 1; i < n; ++i) res.push_back(make_pair(make_pair(-i, 0), 1));
  84.   } else {
  85.     double a = (double)angle / 180.0 * pi;
  86.     for (int x = 1; x <= 2 * n + 4; x += 2) {
  87.       int off, off2;
  88.       int collast = cut(x- (x == 1 ? 1 : 2), a, 0, off);
  89.       int colcur = cut(x, a,  1, off2);
  90.  
  91.       if (collast <= colcur) {
  92.         for (int i = collast; i <= colcur; ++i) {
  93.           int corner = (i == collast && off) || (i == colcur && off2);
  94.           res.push_back(make_pair(make_pair(-i, x/2), !corner));
  95.         }
  96.       } else {
  97.         for (int i = collast; i >= colcur; --i) {
  98.           int corner = (i == collast && off) || (i == colcur && off2);
  99.           res.push_back(make_pair(make_pair(-i, x/2), !corner));
  100.         }
  101.       }
  102.     }
  103.   }
  104.   return res;
  105. }
  106.  
  107. vector<pair<pair<int,int>,int> > cut_line(int x, int y, int angle, int n) {
  108.   vector<pair<pair<int,int>,int> > v, res;
  109.   if (angle >= 0 && angle <= 90 || angle >= 271) v = cut_line_pom(angle, n);
  110.   else {
  111.     v = cut_line_pom(angle < 180 ? (angle + 180) : (angle - 180), n);
  112.     for (int i = 0; i < (int)v.size(); ++i) {
  113.       v[i].first.first *= -1;
  114.       v[i].first.second *= -1;
  115.     }
  116.   }
  117.   for (int i = 0; i < (int)v.size(); ++i) {
  118.     int xx = x + v[i].first.first;
  119.     int yy = y + v[i].first.second;
  120.     if (xx >= 0 && xx < n && yy >= 0 && yy < n) res.push_back(make_pair(make_pair(xx,yy),v[i].second));
  121.   }
  122.   return res;
  123. }
  124.  
  125.  
  126. VI split2VI(string s) {
  127.     VS vs = splt(s, ' ');
  128.     VI v(vs.S);
  129.     REP(i, vs.S) v[i] = atoi(vs[i].c_str());
  130.     return v;
  131. }
  132.  
  133. VD split2VD(string s) {
  134.     VS vs = splt(s, ' ');
  135.     VD v(vs.S);
  136.     REP(i, vs.S) v[i] = atof(vs[i].c_str());
  137.     return v;
  138. }
  139.  
  140. int need_init_full = 0;
  141. int need_init_vis = 1;
  142. char txt[10000];
  143.  
  144. const int TEAMS_NO = 30;
  145. const int MAX_N = 120;
  146. const int MAX_MONSTERS = 30;
  147. const int MAX_BONUSES = 1000;
  148.  
  149. int turn = -1;
  150. int roundID = -1;
  151. int turnNo = -1;
  152.  
  153. bool gameRunning = false;
  154. int N;
  155. int teamsNo;
  156. int maxMonsters;
  157. int mapID;
  158. int teamID;
  159. PII sniper[TEAMS_NO + 2];
  160. int sniperDir[TEAMS_NO + 2];
  161. PII flag[TEAMS_NO + 2];
  162. int flagOwner[TEAMS_NO + 2];
  163. PII base[TEAMS_NO + 2];
  164. int monsterNo[TEAMS_NO + 2];
  165. int monsterVisNo[TEAMS_NO + 2];
  166. int mp[MAX_N][MAX_N];
  167. int bonusNo;
  168. PII bonus[MAX_BONUSES];
  169. string bonusType[MAX_BONUSES];
  170. int bonusTime[MAX_BONUSES];
  171.  
  172. PII forceTarget = MP(-1, -1);
  173. PII sniperTarget = MP(-1, -1);
  174.  
  175. int bonusUsed[256];
  176. string bonusKnown[256];
  177.  
  178. int monstersNo;
  179. PII monsters[MAX_MONSTERS];
  180. int monstersID[MAX_MONSTERS];
  181. PII monstersDest[MAX_MONSTERS];
  182. PII monstersFinalDest[MAX_MONSTERS];
  183. int monstersSense[MAX_MONSTERS][3];
  184.  
  185. int monstersVisNo;
  186. PII monstersVis[MAX_MONSTERS * 30];
  187. int monstersVisID[MAX_MONSTERS * 30];
  188.  
  189. int monsterMap[MAX_N][MAX_N];
  190. int sniperMap[MAX_N][MAX_N];
  191. int bonusMap[MAX_N][MAX_N];
  192.  
  193. int shots = 3;
  194. int lastReload = -100;
  195. int lastRotate = -100;
  196.  
  197. mutex gameUpdate;
  198. bool needUpdate = false;
  199. bool mapLoaded = false;
  200.  
  201. VI scores;
  202.  
  203.  
  204. VS logData;
  205.  
  206. void addLog(string s) {
  207.     s = "Turn: " + i2s(turn) + " :: " + s;
  208.     logData.PB(s);
  209. }
  210.  
  211. #define byte unsigned char
  212.  
  213. void loadMap() {
  214.     string s = "../ctf" + i2s(SERVER_ID+1) + "/map_" + i2s(mapID/10) + i2s(mapID%10) + ".txt";
  215.     cout << "Loading Map : " << s << endl;
  216.     ifstream fs(s.c_str());
  217.     int x;
  218.     fs >> x;
  219.     ZERO(mp);
  220.     REP(i, N) {
  221.         fs >> s;
  222.         REP(j, N) mp[i][j] = s[j] == '#';
  223.     }
  224.     fs.close();
  225.     cout << "Map Loaded" << endl;
  226.     mapLoaded = true;
  227. }
  228.  
  229.  
  230. VPII shootLine(int angle) {
  231.     VC<pair<PII,int>> v = cut_line(sniper[teamID].X, sniper[teamID].Y, angle, N);
  232.     VPII rv;
  233.     REP(i, v.S) {
  234.         if (mp[v[i].X.X][v[i].X.Y]) break;
  235.         if (v[i].Y && monsterMap[v[i].X.X][v[i].X.Y]) rv.PB(v[i].X);
  236.     }
  237.     return rv;
  238. }
  239.  
  240. int calcShootScore(int angle, bool close = false) {
  241.     VPII v = shootLine(angle);
  242.     int rv = 0;
  243.     REP(i, v.S) {
  244.         int d = abs(sniper[teamID].X-v[i].X) + abs(sniper[teamID].Y-v[i].Y);
  245.         if (d > 1 && close) break;
  246.         if (monsterMap[v[i].X][v[i].Y] == 0) addLog("Wut?");
  247.         rv += monsterMap[v[i].X][v[i].Y] == teamID ? -1 : 1;
  248.     }
  249.     return rv;
  250. }
  251.  
  252.  
  253.  
  254. VVI bfs(PII s) {
  255.     queue<int> q;
  256.     VVI v(N, VI(N, 1<<20));
  257.     q.push(0);
  258.     q.push(s.X);
  259.     q.push(s.Y);
  260.     while (!q.empty()) {
  261.         int d = q.front(); q.pop();
  262.         int x = q.front(); q.pop();
  263.         int y = q.front(); q.pop();
  264.         if (x < 0 || x >= N || y < 0 || y >= N || mp[x][y] || v[x][y] <= d) continue;
  265.         v[x][y] = d;
  266.         q.push(d+1), q.push(x+1), q.push(y);
  267.         q.push(d+1), q.push(x-1), q.push(y);
  268.         q.push(d+1), q.push(x), q.push(y+1);
  269.         q.push(d+1), q.push(x), q.push(y-1);
  270.     }
  271.     return v;
  272. }
  273.  
  274. VPII genPath(VVI &v, PII p) {
  275.     int x = p.X;
  276.     int y = p.Y;
  277.     if (v[x][y] >= 1 << 19) return VPII();
  278.    
  279.     VPII vp;
  280.     while (v[x][y]) {
  281.         vp.PB(MP(x, y));
  282.         if (x && v[x-1][y] < v[x][y]) {
  283.             x--;
  284.         } else if (x + 1 < N && v[x+1][y] < v[x][y]) {
  285.             x++;
  286.         } else if (y && v[x][y-1] < v[x][y]) {
  287.             y--;
  288.         } else if (y + 1 < N && v[x][y+1] < v[x][y]) {
  289.             y++;
  290.         }
  291.     }
  292.     vp.PB(MP(x, y));
  293.    
  294.     reverse(ALL(vp));
  295.     return vp;
  296. }
  297.  
  298. PII genDest(VPII &path) {
  299.     int dirNo = 0;
  300.     int dirs[4] = {0};
  301.    
  302.     int ox = path[0].X;
  303.     int oy = path[0].Y;
  304.    
  305.     FOR(i, 1, path.S) {
  306.         int d = path[i].X != path[i-1].X ? (path[i].X<path[i-1].X?0:1) : (path[i].Y<path[i-1].Y?2:3);
  307.         if (dirs[d]==0) {
  308.             dirNo++;
  309.             if (dirNo>2) return path[i-1];
  310.             if (dirNo==2) {
  311.                 int x = ox + (d == 0 ? -1 : d == 1 ? 1 : 0);
  312.                 int y = oy + (d == 2 ? -1 : d == 3 ? 1 : 0);
  313.                 if (x < 0 || x >= N || y < 0 || y >= N || mp[x][y]) return path[i-1];
  314.             }
  315.         }
  316.         dirs[d]=1;
  317.     }
  318.     return path[path.S-1];
  319. }
  320.  
  321.  
  322. int angleDiff(int a, int b) {
  323.     if (b < a) swap(a, b);
  324.     return min(b - a, a - b + 360);
  325. }
  326.  
  327. int optimalAngle(PII p1, PII p2) {
  328.     int x = p2.X - p1.X;
  329.     int y = p2.Y - p1.Y;
  330.     double a = y;//asteroids[best].y - spaceships[i].y;
  331.     double b = -x;//spaceships[i].x - asteroids[best].x;
  332.     double alfa = (atan2(b,a) + 2.0 * pi) / 2.0 / pi * 360.0;
  333.     int alfa2 = alfa;
  334.     alfa2 %= 360;
  335.     if (alfa2 < 0) alfa2 += 360;
  336.     return alfa2;
  337. }
  338.  
  339.  
  340.  
  341. double randDouble() {
  342.     return (rand() + 0.5) / (RAND_MAX + 1.0);
  343. }
  344.  
  345. char chooseMove() {
  346.     const string moves = "NSWE";
  347.     double values[4] = {0};
  348.     int dx[] = {-1,1,0,0};
  349.     int dy[] = {0,0,-1,1};
  350.     REP(d, 4) {
  351.         int x = sniper[teamID].X;
  352.         int y = sniper[teamID].Y;
  353.         x += dx[d];
  354.         y += dy[d];
  355.         if (x < 0 || y < 0 || x >= N || y >= N) continue;
  356.         if (monsterMap[x][y] && monsterMap[x][y] != teamID) values[d] = -1e9;
  357.         REP(dd, 4) {
  358.             int nx = x + dx[d];
  359.             int ny = y + dy[d];
  360.             if (nx >= 0 && nx < N && ny >= 0 && ny < N && monsterMap[x][y] && monsterMap[x][y] != teamID) values[d] -= 10;
  361.         }
  362.         if (monsterMap[x][y] == teamID || mp[x][y]) values[d]--;
  363.     }
  364.     REP(d, 4) values[d] += randDouble();
  365.     int rv = 0;
  366.     REP(i, 4) if (values[i] > values[rv]) rv = i;
  367.     return moves[rv];
  368. }
  369.  
  370. int enemiesClose(PII p) {
  371.     int dx[] = {-1,1,0,0};
  372.     int dy[] = {0,0,-1,1};
  373.     int rv = 0;
  374.     REP(d, 4) {
  375.         int x = p.X + dx[d];
  376.         int y = p.Y + dy[d];
  377.         rv += x >= 0 && x < N && y >= 0 && y < N && monsterMap[x][y] && monsterMap[x][y] != teamID;
  378.     }
  379.     return rv;
  380. }
  381.  
  382. string moveSniper() {
  383.     if (sniper[teamID].X == -1) {
  384.         shots = 3;
  385.         sniperTarget = MP(-1, -1);
  386.         forceTarget = MP(-1, -1);
  387.         return "RESPAWN";
  388.     }
  389.    
  390.     if (forceTarget == sniper[teamID]) forceTarget = MP(-1, -1);
  391.    
  392.     int flags = 0;
  393.     FOR(t, 1, teamsNo+1) flags += flagOwner[t] == teamID;
  394.    
  395.     bool flagBelow = false;
  396.     FOR(t, 1, teamsNo+1) if (t != teamID && flagOwner[t] == 0 && flag[t] == sniper[teamID]) flagBelow = true;
  397.     if (flags < 5 && flagBelow && enemiesClose(sniper[teamID]) == 0) {
  398.         return "PICK_UP";
  399.     }
  400.    
  401.     if (turn > lastReload + 5 && calcShootScore(sniperDir[teamID]) > 0 && enemiesClose(sniper[teamID]) - calcShootScore(sniperDir[teamID], true) <= 0) {
  402.         shots--;
  403.         if (shots == 0) lastReload = turn, shots = 3;
  404.         return "SHOOT";
  405.     }
  406.    
  407.     VVI dist = bfs(sniper[teamID]);
  408.    
  409.     int bflag = -1;
  410.     int bv = 1<<20;
  411.     FOR(t, 1, teamsNo+1) if (t != teamID && flagOwner[t] == 0 && flag[t].X != -1) {
  412.         int av = dist[flag[t].X][flag[t].Y];
  413.         if (av >= 1<<19) continue;
  414.         if (av < bv) {
  415.             bflag = t;
  416.             bv = av;
  417.         }
  418.     }
  419.    
  420.    
  421.     if (flags < 5 && bflag == -1) {
  422.         return string("MOVE ") + chooseMove();
  423.     }
  424.    
  425.     if (flags < 5 && bv == 0 && (flags > 0 || enemiesClose(sniper[teamID]) == 0)) {
  426.         return "PICK_UP";
  427.     }
  428.    
  429.     PII target = flags < 5 ? flag[bflag] : base[teamID];
  430.     if (forceTarget.X != -1) target = forceTarget;
  431.     sniperTarget = target;
  432.    
  433.     VVI dist2 = bfs(target);
  434.    
  435.     if (enemiesClose(sniper[teamID]) == 0 && angleDiff(sniperDir[teamID], optimalAngle(sniper[teamID], target)) > 45) {
  436.         int angle = optimalAngle(sniper[teamID], target);
  437.         if (angle % 90 == 45) angle--;
  438.         return "ROTATE " + i2s(angle);
  439.         lastRotate = turn;
  440.     }
  441.    
  442.    
  443.    
  444.     const string moves = "NSWE";
  445.     double values[4] = {0};
  446.     int dx[] = {-1,1,0,0};
  447.     int dy[] = {0,0,-1,1};
  448.     int ox = sniper[teamID].X;
  449.     int oy = sniper[teamID].Y;
  450.     REP(d, 4) {
  451.         int x = sniper[teamID].X + dx[d];
  452.         int y = sniper[teamID].Y + dy[d];
  453.         if (x < 0 || y < 0 || x >= N || y >= N || mp[x][y] || monsterMap[x][y] == teamID) {
  454.             values[d] = -1e5;
  455.             continue;
  456.         }
  457.        
  458.         if (monsterMap[x][y] && monsterMap[x][y] != teamID) {
  459.             values[d] = -1e9;
  460.             continue;
  461.         }
  462.        
  463.         values[d] -= 10 * enemiesClose(MP(x, y));
  464.        
  465.         if (sniperMap[x][y])  values[d] -= 6;
  466.        
  467.         if (dist2[ox][oy] > dist2[x][y]) values[d] += 5;
  468.         if (dist2[ox][oy] == dist2[x][y]) values[d] += 2.5;
  469.     }
  470.    
  471.     REP(d, 4) values[d] += randDouble();
  472.     int rv = 0;
  473.     REP(i, 4) if (values[i] > values[rv]) rv = i;
  474.    
  475.     if (values[rv] < -1 && enemiesClose(sniper[teamID]) == 0) {
  476.         int ba = 0;
  477.         int bv = -1<<20;
  478.         for (int i = 22; i < 360; i += 45) {
  479.             int av = calcShootScore(i);
  480.             if (av > bv) {
  481.                 bv = av;
  482.                 ba = i;
  483.             }
  484.         }
  485.         if (bv > 0) return string("ROTATE ") + i2s(ba);
  486.     }
  487.    
  488.     return string("MOVE ") + moves[rv];
  489. }
  490.  
  491. class XGame : public Game {
  492.   void saveGameState() {
  493.    
  494.   }
  495.  
  496.   void loadGameState() {
  497.    
  498.   }
  499.  
  500.   void clearGameState() {
  501.     gameUpdate.lock();
  502.     mapLoaded = false;
  503.     forceTarget = MP(-1, -1);
  504.     sniperTarget = MP(-1, -1);
  505.     shots = 3;
  506.     bonusNo = 0;
  507.     lastReload = -100;
  508.     lastRotate = -100;
  509.     ZERO(bonusUsed);
  510.     REP(i, 256) bonusKnown[i] = "";
  511.     logData.clear();
  512.     gameUpdate.unlock();
  513.   }
  514.  
  515.   void debug(string s) {
  516.     printf("%s\n", s.c_str());
  517.     network.logger.log(s.c_str());
  518.   }
  519.  
  520.   void play() {
  521.     int commandsLeft = 20;
  522.  
  523.     network.logger.log("New play");
  524.     cout << "New Turn" << endl;
  525.  
  526.     VI gt = network.getTime();
  527.     while (gt.empty() || gt[1] > gt[2]) {
  528.       usleep((gt.empty() || gt[1] > gt[2]) ? 1000 * 200 : 1000 * 100);
  529.       gt = network.getTime();
  530.     }
  531.    
  532.     static int last_round = -1;
  533.     /* Detect whether a new game has started in the meantime. */
  534.     if (gt[0] != last_round) {
  535.       cout << "New game" << endl;
  536.       last_round = gt[0];
  537.       clearGameState();
  538.     }
  539.     commandsLeft--;
  540.    
  541.     if (turn == gt[1]) return;
  542.  
  543.     gameUpdate.lock();
  544.     roundID = gt[0];
  545.     turn = gt[1];
  546.     turnNo = gt[2];
  547.    
  548.     network.sendLine("DESCRIBE_WORLD");
  549.     network.readOk();
  550.     commandsLeft--;
  551.    
  552.     string line;
  553.     line = network.readLine();
  554.    
  555.     VI v = split2VI(line);
  556.     N = v[0];
  557.     mapID = v[1];
  558.     maxMonsters = v[2];
  559.     teamsNo = v[3];
  560.     teamID = v[4];
  561.     if (!mapLoaded) {
  562.         loadMap();
  563.     }
  564.    
  565.     FOR(team, 1, teamsNo + 1) {
  566.         VI v0 = split2VI(network.readLine());
  567.         VI v1 = split2VI(network.readLine());
  568.         VI v2 = split2VI(network.readLine());
  569.         VI v3 = split2VI(network.readLine());
  570.         sniper[team] = MP(v0[0], v0[1]);
  571.         sniperDir[team] = v0[2];
  572.         flag[team] = MP(v1[0], v1[1]);
  573.         flagOwner[team] = v1[2];
  574.         base[team] = MP(v2[0], v2[1]);
  575.         monsterNo[team] = v3[0];
  576.         monsterVisNo[team] = v3[1];
  577.     }
  578.    
  579.     ZERO(bonusMap);
  580.     REP(i, bonusNo) if (bonusTime[i] > 2) bonusMap[bonus[i].X][bonus[i].Y] = bonusType[i][0];
  581.     bonusNo = atoi(network.readLine().c_str());
  582.     REP(i, bonusNo) {
  583.         VS vs = splt(network.readLine(), ' ');
  584.         bonus[i] = MP(atoi(vs[0].c_str()), atoi(vs[1].c_str()));
  585.         bonusType[i] = vs[2];
  586.         bonusTime[i] = atoi(vs[3].c_str());
  587.         bonusMap[bonus[i].X][bonus[i].Y] = 0;
  588.     }
  589.     REP(i, N) REP(j, N) if (bonusMap[i][j]) bonusUsed[bonusMap[i][j]] = 1;
  590.    
  591.    
  592.    
  593.     network.sendLine("DESCRIBE_MONSTERS");
  594.     network.readOk();
  595.     commandsLeft--;
  596.    
  597.     monstersNo = atoi(network.readLine().c_str());
  598.     REP(i, monstersNo) {
  599.         v = split2VI(network.readLine());
  600.         monsters[i] = MP(v[1], v[2]);
  601.         monstersDest[i] = MP(v[3], v[4]);
  602.         monstersID[i] = v[0];
  603.         monstersSense[i][0] = v[5];
  604.         monstersSense[i][1] = v[6];
  605.         monstersSense[i][2] = v[7];
  606.     }
  607.    
  608.     needUpdate = true;
  609.    
  610.     if (sniper[teamID].X != -1) {
  611.         network.sendLine("LOOK");
  612.         network.readOk();
  613.         commandsLeft--;
  614.        
  615.         monstersVisNo = atoi(network.readLine().c_str());
  616.         REP(i, monstersVisNo) {
  617.             v = split2VI(network.readLine());
  618.             monstersVis[i] = MP(v[0], v[1]);
  619.             monstersVisID[i] = v[2];
  620.         }
  621.     } else {
  622.         monstersVisNo = 0;
  623.     }
  624.    
  625.     ZERO(monsterMap);
  626.     ZERO(sniperMap);
  627.     REP(i, monstersNo) monsterMap[monsters[i].X][monsters[i].Y] = teamID;
  628.     REP(i, monstersVisNo) monsterMap[monstersVis[i].X][monstersVis[i].Y] = monstersVisID[i];
  629.     FOR(t, 1, teamsNo+1) if (sniper[t].X != -1) sniperMap[sniper[t].X][sniper[t].Y] = t;
  630.    
  631.     string sniperCMD = moveSniper();
  632.     network.sendLine(sniperCMD.c_str());
  633.     if (network.readOk()) {
  634.         addLog(sniperCMD);
  635.     } else {
  636.         addLog(sniperCMD + " (FAILED!)");
  637.     }
  638.     commandsLeft--;
  639.    
  640.     int targets[TEAMS_NO + 2] = {0};
  641.     targets[teamID] = 1000;
  642.     int monsterMoved[30] = {0};
  643.    
  644.     VVI dist[MAX_MONSTERS];
  645.     REP(i, monstersNo) {
  646.         dist[i] = bfs(monsters[i]);
  647.         monstersFinalDest[i] = MP(-1,-1);
  648.     }
  649.    
  650.     while (commandsLeft) {
  651.         int bd = 1<<20;
  652.         int mid = -1;
  653.         int sid = -1;
  654.         REP(i, monstersNo) if (!monsterMoved[i]) FOR(t, 1, teamsNo+1) if (sniper[t].X != -1) {
  655.             int ad = dist[i][sniper[t].X][sniper[t].Y];
  656.             if (ad >= 1<<19) continue;
  657.             ad += targets[t] * N / 2;
  658.             if (ad < bd) {
  659.                 bd = ad;
  660.                 mid = i;
  661.                 sid = t;
  662.             }
  663.         }
  664.        
  665.         if (mid == -1) break;
  666.         monsterMoved[mid] = 1;
  667.         targets[sid]++;
  668.        
  669.         VPII path = genPath(dist[mid], sniper[sid]);
  670.         PII dest = genDest(path);
  671.         monstersFinalDest[mid] = sniper[sid];
  672.        
  673.         if (monstersDest[mid] == dest) continue;
  674.         commandsLeft--;
  675.        
  676.         network.sendLine(("SEND_MONSTER " + i2s(monstersID[mid]) + " " + i2s(dest.X) + " " + i2s(dest.Y)).c_str());
  677.         network.readOk();
  678.     }
  679.    
  680.     while (commandsLeft) {
  681.         int id = -1;
  682.         REP(i, 256) if (bonusUsed[i] && bonusKnown[i] == "") id = i;
  683.         if (id == -1) break;
  684.         commandsLeft--;
  685.         string cmd = string("BONUS_INFO ") + (char)id;
  686.         DB(cmd);
  687.         DB(id);
  688.         network.sendLine((cmd).c_str());
  689.         network.readOk();
  690.         bonusKnown[id] = network.readLine();
  691.     }
  692.    
  693.     if (commandsLeft >= 2) {
  694.         scores = network.getAllScores();
  695.         int myScore = network.getMyScore();
  696.         REP(i, scores.S) if (scores[i] == myScore) scores[i] = -scores[i], myScore = -1;
  697.     }
  698.    
  699.     // int enemyMonstersVisNo = 0;
  700.    
  701.     gameUpdate.unlock();
  702.    
  703.     fflush(stdout);
  704.   }      
  705.  
  706. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement