Advertisement
Guest User

Deadline24: Cauldron (author: Psyho)

a guest
Apr 13th, 2015
1,040
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.83 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <sys/time.h>
  3. #include <unistd.h>
  4. #include <CImg.h>
  5.  
  6. using namespace std;
  7. using namespace cimg_library;
  8.  
  9. #define INLINE   inline __attribute__ ((always_inline))
  10. #define NOINLINE __attribute__ ((noinline))
  11.  
  12. #define ALIGNED __attribute__ ((aligned(16)))
  13.  
  14. #define likely(x)   __builtin_expect(!!(x),1)
  15. #define unlikely(x) __builtin_expect(!!(x),0)
  16.  
  17. #define SSELOAD(a)     _mm_load_si128((__m128i*)&a)
  18. #define SSESTORE(a, b) _mm_store_si128((__m128i*)&a, b)
  19.  
  20. #define byte unsigned char
  21. #define FOR(i,a,b)  for(int i=(a);i<(b);++i)
  22. #define REP(i,a)    FOR(i,0,a)
  23. #define ZERO(m)     memset(m,0,sizeof(m))
  24. #define ALL(x)      x.begin(),x.end()
  25. #define PB          push_back
  26. #define S           size()
  27. #define LL          long long
  28. #define ULL         unsigned long long
  29. #define LD          long double
  30. #define MP          make_pair
  31. #define X           first
  32. #define Y           second
  33. #define VC          vector
  34. #define PII         pair <int, int>
  35. #define VB          VC < byte >
  36. #define VVB         VC < VB >
  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 VVVD        VC < VVD >
  44. #define VF          VC < float >
  45. #define VVF         VC < VF >
  46. #define VVVF        VC < VVF >
  47. #define VS          VC < string >
  48. #define VVS         VC < VS >
  49. #define DB(a)       cout << #a << ": " << (a) << endl;
  50.  
  51. template<class A, class B> ostream& operator<<(ostream &os, pair<A,B> &p) {os << "(" << p.X << "," << p.Y << ")"; return os;}
  52. template<class A, class B, class C> ostream& operator<<(ostream &os, tuple<A,B,C> &p) {os << "(" << get<0>(p) << "," << get<1>(p) << "," << get<2>(p) << ")"; return os;}
  53. template<class T> ostream& operator<<(ostream &os, VC<T> &v) {os << "{"; REP(i, v.S) {if (i) os << ", "; os << v[i];} os << "}"; return os;}
  54. template<class T> string i2s(T x) {ostringstream o; o << x; return o.str();}
  55. 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;}
  56.  
  57. int turnsLeft;
  58. VS logData;
  59. void addLog(string s) {
  60.     s = "Turn: " + i2s(turnsLeft) + " :: " + s;
  61.     logData.PB(s);
  62. }
  63. #include "lib.cpp"
  64.  
  65. int hexDist(PII p0, PII p1) {
  66.     if (p0.Y > p1.Y) swap(p0, p1);
  67.     int dy = p1.Y - p0.Y;
  68.     int dx = p1.X - p0.X;
  69.     if (dy == 0) return abs(dx);
  70.     if (dx < 0) return dy - dx;
  71.     if (dx > dy) return dx;
  72.     return dy;
  73. }
  74.  
  75. inline int between(double a, double b, double c) {
  76.   return a >= b && a <= c;
  77. }
  78.  
  79. vector<pair<int,int> > visible2(int targetx, int targety, double move) {
  80.   double pi = 2.0 * acos(0.0);
  81.   double h = sqrt(3.0) / 2.0;
  82.   const int K = 6;
  83.   double ddx[K], ddy[K];
  84.   int range = 10;
  85.   REP(i,K){
  86.     double a = 2 * pi / K * i + pi / 6.0;
  87.     ddx[i] = cos(a);
  88.     ddy[i] = sin(a);
  89.   //  printf("kat=%.6lf\n", atan2(ddy[i], ddx[i]));
  90.   }
  91.  
  92.   vector<pair<int,int> > blocking;
  93.   for (int dx = -range; dx <= range; ++dx) for (int dy = -range; dy <= range; ++dy) {
  94.     int d = hexDist(make_pair(0,0), make_pair(dx, dy));
  95.     if (d > 0 && d < hexDist(make_pair(0,0), make_pair(targetx, targety))) {
  96.       blocking.push_back(make_pair(dx, dy));
  97.     }
  98.   }
  99.  
  100.   vector<pair<int,int> > res;
  101.  
  102.   if (targety == 0 && targetx > 0) {
  103.     for (int x = 1; x < targetx; ++x) res.push_back(make_pair(x, 0));
  104.     return res;
  105.   }
  106.  
  107.   for (auto p : blocking) {
  108.     int ok = 0;
  109.  
  110.     double px = 0.0;
  111.     double py = 0.0;
  112.     px += targetx * 2.0 * h;
  113.     px -= targety * h;
  114.     py -= targety * 1.5;
  115.     double angle = atan2(py, px);
  116.     if (angle < 0) angle += 2.0 * pi;
  117.     // printf("dx = %d dy = %d angle = %lf\n", dx, dy, angle);
  118.     double hit_angle = angle + move;
  119.     if (hit_angle > 2 * pi) hit_angle -= 2 * pi;
  120.     else if (hit_angle < 0) hit_angle += 2 * pi;
  121.  
  122.     vector<double> pom;
  123.     double amax = 0.0;
  124.     double amin = 2.0 * pi;
  125.     REP(i,K) {
  126.       px = 0.0; py = 0.0;
  127.       px += p.first * 2.0 * h;
  128.       px -= p.second * h;
  129.       py -= p.second * 1.5;
  130.       px += ddx[i];
  131.       py += ddy[i];
  132.       angle = atan2(py, px);
  133.       if (angle < 0) angle += 2.0 * pi;
  134.       pom.push_back(angle);
  135.       amax = max(amax, angle);
  136.       amin = min(amin, angle);
  137.     }
  138.     //printf("para=(%d,%d) amin=%lf amax=%lf hit=%lf\n", p.first, p.second, amin, amax, hit_angle);
  139.     if (amax - amin <= pi) {
  140.       if (between(hit_angle, amin, amax)) ok = 1;
  141.     } else {
  142.       amax = 0.0;
  143.       amin = 2.0 * pi;
  144.       for (auto a : pom) {
  145.         if (a < pi) amax = max(amax, a);
  146.         else amin = min(amin, a);
  147.       }
  148.       if (between(hit_angle, 0.0, amax)) ok = 1;
  149.       if (between(hit_angle, amin, 2.0 * pi)) ok = 1;
  150.     }
  151.     if (ok) res.push_back(p);
  152.   }
  153.   return res;
  154. }
  155.  
  156. // mode=1 LEFT
  157. // mode=2 RIGHT
  158. // mode=3 BOTH
  159. vector<pair<int,int> > visible(int offset_x, int offset_y, int mode) {
  160.   vector<pair<int,int> > res, pom;
  161.   const double EPS = 1E-6;
  162.   if (mode & 1) {
  163.     pom = visible2(offset_x, offset_y, EPS);
  164.     for (auto p : pom) res.push_back(p);
  165.   }
  166.   if (mode & 2) {
  167.     pom = visible2(offset_x, offset_y, -EPS);
  168.     for (auto p : pom) res.push_back(p);
  169.   }
  170.   sort(res.begin(), res.end());
  171.   res.erase(unique(res.begin(), res.end()), res.end());
  172.   vector<pair<int,int> > perm;
  173.   for (int i = 0; i < (int)res.size(); ++i) perm.push_back(make_pair(hexDist(make_pair(0,0), res[i]), i));
  174.   sort(perm.begin(), perm.end());
  175.   vector<pair<int,int> > res2;
  176.   for (int i = 0; i < (int)perm.size(); ++i) res2.push_back(res[perm[i].second]);
  177.   return res2;
  178. }
  179.  
  180.  
  181. struct RNG {
  182.     unsigned int MT[624];
  183.     int index;
  184.    
  185.     RNG(int seed = 1) {
  186.         init(seed);
  187.     }
  188.    
  189.     void init(int seed = 1) {
  190.         MT[0] = seed;
  191.         FOR(i, 1, 624) MT[i] = (1812433253UL * (MT[i-1] ^ (MT[i-1] >> 30)) + i);
  192.         index = 0;
  193.     }
  194.    
  195.     void generate() {
  196.         const unsigned int MULT[] = {0, 2567483615UL};
  197.         REP(i, 227) {
  198.             unsigned int y = (MT[i] & 0x8000000UL) + (MT[i+1] & 0x7FFFFFFFUL);
  199.             MT[i] = MT[i+397] ^ (y >> 1);
  200.             MT[i] ^= MULT[y&1];
  201.         }
  202.         FOR(i, 227, 623) {
  203.             unsigned int y = (MT[i] & 0x8000000UL) + (MT[i+1] & 0x7FFFFFFFUL);
  204.             MT[i] = MT[i-227] ^ (y >> 1);
  205.             MT[i] ^= MULT[y&1];
  206.         }
  207.         unsigned int y = (MT[623] & 0x8000000UL) + (MT[0] & 0x7FFFFFFFUL);
  208.         MT[623] = MT[623-227] ^ (y >> 1);
  209.         MT[623] ^= MULT[y&1];
  210.     }
  211.    
  212.     unsigned int rand() {
  213.         if (index == 0) {
  214.             generate();
  215.         }
  216.        
  217.         unsigned int y = MT[index];
  218.         y ^= y >> 11;
  219.         y ^= y << 7  & 2636928640UL;
  220.         y ^= y << 15 & 4022730752UL;
  221.         y ^= y >> 18;
  222.         index = index == 623 ? 0 : index + 1;
  223.         return y;
  224.     }
  225.    
  226.     INLINE int next() {
  227.         return rand();
  228.     }
  229.    
  230.     INLINE int next(int x) {
  231.         return rand() % x;
  232.     }
  233.    
  234.     INLINE int next(int a, int b) {
  235.         return a + (rand() % (b - a));
  236.     }
  237.    
  238.     INLINE double nextDouble() {
  239.         return (rand() + 0.5) * (1.0 / 4294967296.0);
  240.     }
  241. };
  242.  
  243. int s2i(string s) {
  244.     return atoi(s.c_str());
  245. }
  246.  
  247. double s2f(string s) {
  248.     return atof(s.c_str());
  249. }
  250.  
  251. const int MAX_MAPN = 210;
  252. const int MAX_UNITS = 1000;
  253. const int MAX_SPS = 1000;
  254. const int MAX_EUNITS = 10000;
  255. mutex gameUpdate;
  256.  
  257. int mpN;
  258. int turnTime;
  259. int scoreHQ;
  260. int scoreSP;
  261. int gameGrace;
  262. int gameInactivity;
  263. int gameShortening;
  264. int maxCommands;
  265. double scoreScaling;
  266. int lastTurnsLeft = 0;
  267.  
  268.  
  269. char mp[MAX_MAPN][MAX_MAPN];
  270. int xp[MAX_MAPN][MAX_MAPN];
  271. int fu[MAX_MAPN][MAX_MAPN];
  272. int cn[MAX_MAPN][MAX_MAPN];
  273. int ls[MAX_MAPN][MAX_MAPN];
  274.  
  275.  
  276. bool newVGame = false;
  277. const int UT_UNKNOWN = 0;
  278. const int UT_CANNON = 1;
  279. const int UT_TANK = 2;
  280. const int UT_ARMORED = 3;
  281. const int UT_HQ = 4;
  282. int parseUnitType(string s) {
  283.     return s == "CANNON" ? UT_CANNON : s == "TANK" ? UT_TANK : s == "ARMORED" ? UT_ARMORED : s == "HQ" ? UT_HQ : UT_UNKNOWN;   
  284. }
  285.  
  286. int points;
  287.  
  288. int spNo;
  289. PII spPos[MAX_SPS];
  290. int spOwner[MAX_SPS];
  291.  
  292. int enunitNo;
  293. PII enunitPos[MAX_EUNITS];
  294. int enunitType[MAX_EUNITS];
  295. int enunitStamina[MAX_EUNITS];
  296. int enunitOwner[MAX_EUNITS];
  297.  
  298. int unitNo;
  299. int unitID[MAX_UNITS];
  300. PII unitPos[MAX_UNITS];
  301. int unitType[MAX_UNITS];
  302. int unitStamina[MAX_UNITS];
  303. int unitBusy[MAX_UNITS];
  304. int HQID;
  305.  
  306.  
  307.  
  308. #define byte unsigned char
  309.  
  310.  
  311. int UNITS_LIMIT = 0;
  312. int BUILD_CANNONS = 2;
  313. bool ORDER_WAIT = 0;
  314. bool FORCE_STAT = 1;
  315. VPII XIGNORE;
  316. VPII XFORTIFY;
  317. VPII XCOVER;
  318. VPII XSCOUT;
  319. int SCOUT_QUEUE = 0;
  320. PII HQ_TARGET = MP(-1,-1);
  321.  
  322. bool needUpdate = false;
  323. bool mapUpdated = false;
  324.  
  325. void toggleElement(VPII &v, int x, int y) {
  326.     REP(i, v.S) if (v[i].X == x && v[i].Y == y) {
  327.         swap(v[i], v[v.S-1]);
  328.         v.pop_back();
  329.         return;
  330.     }
  331.     v.PB(MP(x, y));
  332. }
  333.  
  334. bool canMove(int x, int y) {
  335.     if (x < 0 || x >= mpN || y < 0 || y >= mpN) return false;
  336.     if (xp[x][y]) return false;
  337.     if (mp[x][y] == 'L') return false;
  338.     return true;
  339. }
  340.  
  341. bool canMove(PII p) {
  342.     return canMove(p.X, p.Y);
  343. }
  344.  
  345. bool lineOfFire(int type, PII &s, VPII &p) {
  346.     REP(i, p.S) if (fu[p[i].X][p[i].Y]) return false;
  347.     return true;
  348. }
  349.  
  350. bool lineOfSight(int type, PII &s, VPII &p) {
  351.     char t = mp[s.X][s.Y];
  352.     if (p.S == 0) return false;
  353.     int len = type == UT_ARMORED ? 5 : 4;
  354.     if (t == 'H' && mp[p[p.S-1].X][p[p.S-1].Y] == 'H') return hexDist(p[p.S-1], s) <= len;
  355.     if (t == 'H') len *= 2;
  356.     if (hexDist(p[p.S-1], s) > len) return false;
  357.     if (t == 0) return true;
  358.     REP(i, ((int)p.S) - 1) {
  359.         char c = mp[p[i].X][p[i].Y];
  360.         if (c == 'F' || c == 'H') return false;
  361.         if (c == 'L' || c == 'P') continue;
  362.         if (c == 'B' && t != 'H') return false;
  363.     }
  364.     return true;
  365. }
  366.  
  367.  
  368. int dx[] = {-1,1,0,0,-1,1};
  369. int dy[] = {0,0,-1,1,-1,1};
  370. bool newGame = true;
  371.  
  372. class XGame : public Game {
  373.   void saveGameState() { }
  374.  
  375.   void loadGameState() { }
  376.  
  377.   void clearGameState() {
  378.         gameUpdate.lock();
  379.         gameUpdate.unlock();
  380.   }
  381.  
  382.   void play() {
  383.         int shotsFired = 0;
  384.         int coverShotsFired = 0;
  385.         int destroyed = 0;
  386.         try {
  387.         string line;
  388.         VS vs;
  389.        
  390.         gameUpdate.lock();
  391.        
  392.         //analyze DESCRIBE_WORLD
  393.         network.sendLine("DESCRIBE_WORLD");
  394.         network.readOk();
  395.        
  396.         line = network.readLine();
  397.         vs = splt(line);
  398.         mpN = s2i(vs[0]);
  399.         turnTime = s2i(vs[1]);
  400.         scoreHQ = s2i(vs[2]);
  401.         scoreSP = s2i(vs[3]);
  402.         gameGrace = s2i(vs[4]);
  403.         gameInactivity = s2i(vs[5]);
  404.         gameShortening = s2i(vs[6]);
  405.         maxCommands = s2i(vs[7]);
  406.         scoreScaling = s2f(vs[8]);
  407.        
  408.         int cmdLeft = maxCommands - 1;
  409.        
  410.         //analyze LIST_UNITS
  411.         network.sendLine("LIST_UNITS");
  412.         network.readOk();
  413.         cmdLeft--;
  414.         line = network.readLine();
  415.         unitNo = s2i(line);
  416.         REP(i, unitNo) {
  417.             line = network.readLine();
  418.             vs = splt(line);
  419.             unitID[i] = s2i(vs[0]);
  420.             unitPos[i].X = s2i(vs[1]) - 1;
  421.             unitPos[i].Y = s2i(vs[2]) - 1;
  422.             unitType[i] = parseUnitType(vs[3]);
  423.             assert(unitType[i] != UT_UNKNOWN);
  424.             unitStamina[i] = vs[4] == "INF" ? -1 : s2i(vs[4]);
  425.             unitBusy[i] = s2i(vs[5]);          
  426.             xp[unitPos[i].X][unitPos[i].Y] = 1;
  427.             fu[unitPos[i].X][unitPos[i].Y] = 1;
  428.         }
  429.         HQID = -1;
  430.         REP(i, unitNo) if (unitType[i] == UT_HQ) HQID = i;
  431.        
  432.         //analyze LIST_ENEMIES
  433.         network.sendLine("LIST_ENEMIES");
  434.         network.readOk();
  435.         cmdLeft--;
  436.         enunitNo = s2i(network.readLine());
  437.         REP(i, enunitNo) {
  438.             line = network.readLine();
  439.             vs = splt(line);
  440.             enunitPos[i].X = s2i(vs[0]) - 1;
  441.             enunitPos[i].Y = s2i(vs[1]) - 1;
  442.             enunitType[i] = parseUnitType(vs[2]);
  443.             enunitStamina[i] = vs[3] == "INF" ? -1 : s2i(vs[3]);
  444.             enunitOwner[i] = s2i(vs[4]);
  445.             if (enunitType[i] != UT_HQ) xp[enunitPos[i].X][enunitPos[i].Y] = 1;
  446.             if (enunitType[i] == UT_HQ) fu[enunitPos[i].X][enunitPos[i].Y] = 1;
  447.         }
  448.        
  449.         //analyze LIST_STRATEGIC_POINTS
  450.         network.sendLine("LIST_STRATEGIC_POINTS");
  451.         network.readOk();
  452.         cmdLeft--;
  453.         spNo = s2i(network.readLine());
  454.         REP(i, spNo) {
  455.             line = network.readLine();
  456.             vs = splt(line);
  457.             spPos[i].X = s2i(vs[0]) - 1;
  458.             spPos[i].Y = s2i(vs[1]) - 1;
  459.             spOwner[i] = vs[2] == "NONE" ? -1 : vs[2] == "YOURS" ? 0 : s2i(vs[2]);
  460.         }
  461.        
  462.         //analyze TIME_TO_END
  463.         network.sendLine("TIME_TO_END");
  464.         network.readOk();
  465.         cmdLeft--;
  466.         turnsLeft = s2i(network.readLine());
  467.         if (turnsLeft > lastTurnsLeft) {
  468.             points = 0;
  469.             newGame = true;
  470.             newVGame = true;
  471.             UNITS_LIMIT = maxCommands;
  472.             BUILD_CANNONS = 2;
  473.             XIGNORE.clear();
  474.             XFORTIFY.clear();
  475.             XCOVER.clear();
  476.             XSCOUT.clear();
  477.             HQ_TARGET = MP(-1,-1);
  478.             SCOUT_QUEUE = 0;
  479.             ORDER_WAIT = false;
  480.             FORCE_STAT = true;
  481.             mapUpdated = false;
  482.             REP(i, mpN) REP(j, mpN) cn[i][j] = 1;
  483.            
  484.             addLog("NEW GAME");
  485.             cout << "NEW GAME" << endl;
  486.         }
  487.         lastTurnsLeft = turnsLeft;
  488.        
  489.         //analyze MY_STAT
  490.         if (points < 10 || FORCE_STAT) {
  491.             network.sendLine("MY_STAT");
  492.             network.readOk();
  493.             cmdLeft--;
  494.             int oldPoints = points;
  495.             points = s2i(network.readLine());
  496.             if (FORCE_STAT) {
  497.                 int spBonus = 0;
  498.                 REP(i, spNo) if (spOwner[i] == 0) spBonus += scoreSP;
  499.                 destroyed = (points - oldPoints - spBonus) / 5;
  500.             }
  501.         }
  502.        
  503.        
  504.         shotsFired = 0;
  505.        
  506.         //analyze LOOK_AROUND
  507.         if (!mapUpdated) {
  508.             network.sendLine("LOOK_AROUND");
  509.             cmdLeft--;
  510.             if (network.readOk()) {
  511.                 mapUpdated = true;
  512.                 REP(i, mpN) {
  513.                     string s = network.readLine();
  514.                     REP(j, mpN) mp[j][i] = s[j];
  515.                 }
  516.                
  517.                 REP(i, mpN) REP(j, mpN) cn[i][j] = 0;
  518.                 queue<int> q;
  519.                 REP(i, unitNo) q.push(unitPos[i].X), q.push(unitPos[i].Y);
  520.                 int vis = 0;
  521.                 while (!q.empty()) {
  522.                     int x = q.front(); q.pop();
  523.                     int y = q.front(); q.pop();
  524.                     if (x < 0 || x >= mpN || y < 0 || y >= mpN || mp[x][y] == 'L' || cn[x][y]) continue;
  525.                     cn[x][y] = 1;
  526.                     vis++;
  527.                     REP(d, 6) q.push(x + dx[d]), q.push(y + dy[d]);
  528.                 }
  529.                 DB(vis);
  530.             }
  531.         }
  532.         REP(i, XIGNORE.S) xp[XIGNORE[i].X][XIGNORE[i].Y] = 1;
  533.        
  534.         //capture HQ
  535.         REP(i, unitNo) if (unitBusy[i] == 0 && unitType[i] != UT_HQ) REP(j, enunitNo) if (enunitType[j] == UT_HQ) {
  536.             REP(d, 6) {
  537.                 PII np = MP(unitPos[i].X + dx[d], unitPos[i].Y + dy[d]);
  538.                 if (np == enunitPos[j]) {
  539.                     unitBusy[i] = 100;
  540.                     if (cmdLeft-- == 0) throw 1;
  541.                     network.sendLine("MOVE " + i2s(unitID[i]) + " " + i2s(dx[d]) + " " + i2s(dy[d]));
  542.                     network.readOk();
  543.                     break;
  544.                 }
  545.             }
  546.         }
  547.        
  548.         //attack orders
  549.         REP(i, unitNo) {
  550.             if (cmdLeft <= 1) break;
  551.             if (unitType[i] == UT_HQ) continue;
  552.             if (unitType[i] == UT_CANNON && ls[unitPos[i].X][unitPos[i].Y]) continue;
  553.             VI targets;
  554.             REP(j, enunitNo) {
  555.                 if (enunitType[j] == UT_HQ) continue;
  556.                 int dist = hexDist(unitPos[i], enunitPos[j]);
  557.                 if (unitType[i] == UT_CANNON && (dist < 3 || dist > 8 + (mp[enunitPos[j].X][enunitPos[j].Y] != 'H' && mp[unitPos[i].X][unitPos[i].Y] == 'H' ? 1 : 0))) continue;
  558.                 if (unitType[i] != UT_CANNON) {
  559.                     int range = unitType[i] == UT_TANK ? 5 : 4;
  560.                     if (mp[unitPos[i].X][unitPos[i].Y] == 'H' && mp[enunitPos[j].X][enunitPos[j].Y] != 'H') range++;
  561.                     if (dist > range) continue;
  562.                     PII diff = MP(enunitPos[j].X - unitPos[i].X, enunitPos[j].Y - unitPos[i].Y);
  563.                     VPII sight1 = visible(diff.X, diff.Y, 1);
  564.                     VPII sight2 = visible(diff.X, diff.Y, 2);
  565.                     VPII sight3 = visible(diff.X, diff.Y, 3);
  566.                     sight1.PB(diff);
  567.                     sight2.PB(diff);
  568.                     sight3.PB(diff);
  569.                     for (PII &p : sight1) p.X += unitPos[i].X, p.Y += unitPos[i].Y;
  570.                     for (PII &p : sight2) p.X += unitPos[i].X, p.Y += unitPos[i].Y;
  571.                     for (PII &p : sight3) p.X += unitPos[i].X, p.Y += unitPos[i].Y;
  572.                     // if (dist > 1) continue;
  573.                     if (!lineOfSight(unitType[i], unitPos[i], sight1) && !lineOfSight(unitType[i], unitPos[i], sight2)) continue;
  574.                     if (!lineOfFire(unitType[i], unitPos[i], sight3)) continue;
  575.                 }
  576.                 targets.PB(j);
  577.             }
  578.             if (targets.S == 0) continue;
  579.             int j = targets[rand()%targets.S];
  580.             string cmd = "SHOOT " + i2s(unitID[i]) + " " + i2s(enunitPos[j].X - unitPos[i].X) + " " + i2s(enunitPos[j].Y - unitPos[i].Y);
  581.             if (unitBusy[i]) {
  582.                 if (cmdLeft-- == 0) throw 1;
  583.                 network.sendLine("CANCEL_MOVE " + i2s(unitID[i]));
  584.                 network.readOk();
  585.             }
  586.             if (cmdLeft-- == 0) throw 1;
  587.             network.sendLine(cmd);
  588.             shotsFired++;
  589.             cout << "SHOOT: " << hexDist(unitPos[i], enunitPos[j]) << endl;
  590.             if (network.readOk()) {
  591.                 line = network.readLine();
  592.                 vs = splt(line);
  593.                 int hitx = s2i(vs[0]) - 1;
  594.                 int hity = s2i(vs[1]) - 1;
  595.                 if (hitx != enunitPos[j].X || hity != enunitPos[j].Y) addLog("SHOOT FAILED: " + cmd + " HIT: " + i2s(hitx) + ":" + i2s(hity));
  596.                 ls[unitPos[i].X][unitPos[i].Y] = unitType[i] == UT_CANNON ? 2 : 1;
  597.             }
  598.             unitBusy[i] = 100;
  599.         }
  600.        
  601.         //cover attacks
  602.         REP(i, XCOVER.S) {
  603.             bool bad = false;
  604.             REP(j, unitNo) bad |= XCOVER[i] == unitPos[j];
  605.             if (bad) {
  606.                 swap(XCOVER[i], XCOVER[XCOVER.S-1]);
  607.                 i--;
  608.                 XCOVER.pop_back();
  609.             }
  610.         }
  611.        
  612.         VI xcUsed(XCOVER.S, 0);
  613.         REP(i, unitNo) if (unitType[i] == UT_CANNON && unitBusy[i] == 0 && ls[unitPos[i].X][unitPos[i].Y] == 0) {
  614.             if (cmdLeft <= 1) break;
  615.             VI targets;
  616.             REP(j, XCOVER.S) if (xcUsed[j] == 0) {
  617.                 int dist = hexDist(unitPos[i], XCOVER[j]);
  618.                 if (dist < 3 || dist > 8 + (mp[XCOVER[j].X][XCOVER[j].Y] != 'H' && mp[unitPos[i].X][unitPos[i].Y] == 'H' ? 1 : 0)) continue;
  619.                 targets.PB(j);
  620.             }
  621.             if (targets.S == 0) continue;
  622.             int j = targets[rand()%targets.S];
  623.             string cmd = "SHOOT " + i2s(unitID[i]) + " " + i2s(XCOVER[j].X - unitPos[i].X) + " " + i2s(XCOVER[j].Y - unitPos[i].Y);
  624.             if (cmdLeft-- == 0) throw 1;
  625.             network.sendLine(cmd);
  626.             if (network.readOk()) {
  627.                 coverShotsFired++;
  628.                 line = network.readLine();
  629.                 ls[unitPos[i].X][unitPos[i].Y] = unitType[i] == UT_CANNON ? 2 : 1;
  630.             }
  631.             unitBusy[i] = 100;
  632.             xcUsed[j] = 1;
  633.         }
  634.        
  635.         int cannonsNo = 0;
  636.         REP(i, unitNo) cannonsNo += unitType[i] == UT_CANNON;
  637.        
  638.         //build order
  639.         bool buildOk = false;
  640.         if (HQID != -1) REP(d, 6) buildOk |= canMove(unitPos[HQID].X + dx[d], unitPos[HQID].Y + dy[d]);
  641.         if (points >= 10 && unitNo < UNITS_LIMIT && HQID != -1 && buildOk) {
  642.             if (cmdLeft-- == 0) throw 1;
  643.             if (SCOUT_QUEUE > 0) {
  644.                 network.sendLine("CREATE_UNIT ARMORED");
  645.                 SCOUT_QUEUE--;
  646.                 addLog("BUILD ARMORED");
  647.             } else if (cannonsNo < 5 && (BUILD_CANNONS == 2 || BUILD_CANNONS == 1 && rand() % 4)) {
  648.                 network.sendLine("CREATE_UNIT CANNON");
  649.                 addLog("BUILD CANNON");
  650.             } else {
  651.                 network.sendLine("CREATE_UNIT TANK");
  652.                 addLog("BUILD TANK");
  653.             }
  654.             if (network.readOk()) line = network.readLine();
  655.             points -= 10;
  656.             unitBusy[HQID] = 100;
  657.         }
  658.        
  659.         //MOVE HQ
  660.         if (HQID == -1 || unitPos[HQID] == HQ_TARGET) HQ_TARGET = MP(-1,-1);
  661.        
  662.         if (HQID != -1) {
  663.             if (HQ_TARGET.X == -1) {
  664.                 if (HQID != -1) unitBusy[HQID] = 100;
  665.             } else if (unitBusy[HQID] == 0) {
  666.                 double bv = 1e9;
  667.                 int dir = -1;
  668.                 REP(d, 6) {
  669.                     PII np = MP(unitPos[HQID].X + dx[d], unitPos[HQID].Y + dy[d]);
  670.                     if (!canMove(np)) continue;
  671.                     double av = hexDist(HQ_TARGET, np);
  672.                     if (av < bv) {
  673.                         dir = d;
  674.                         bv = av;
  675.                     }
  676.                 }
  677.                 if (dir != -1) {
  678.                     unitBusy[HQID] = 100;
  679.                     if (cmdLeft-- == 0) throw 1;
  680.                     network.sendLine("MOVE " + i2s(unitID[HQID]) + " " + i2s(dx[dir]) + " " + i2s(dy[dir]));
  681.                     network.readOk();
  682.                 }
  683.             }
  684.         }
  685.        
  686.         //remain on SP
  687.         REP(i, unitNo) if (unitType[i] != UT_CANNON) REP(j, spNo) if (unitPos[i] == spPos[j]) {
  688.             unitBusy[i] = 1000;
  689.             break;
  690.         }
  691.        
  692.         if (ORDER_WAIT) throw 1;
  693.            
  694.         //move orders
  695.         VI xfUsed(XFORTIFY.S, 0);
  696.         VI xaUsed(XSCOUT.S, 0);
  697.         VI spUsed(spNo, 0);
  698.         while (true) {
  699.             double bv = 0;
  700.             int bu = -1;
  701.             int bs = -1;
  702.             int bf = -1;
  703.             int ba = -1;
  704.             PII target = MP(-1, -1);
  705.             REP(i, unitNo) if (unitBusy[i] == 0) {
  706.                 REP(j, spNo) if (spOwner[j] != 0 && cn[spPos[j].X][spPos[j].Y]) {
  707.                     double av = 1e9 - hexDist(spPos[j], unitPos[i]) - 50 * (spOwner[j] != -1) - 25 * spUsed[j];
  708.                     if (av > bv) {
  709.                         bv = av;
  710.                         bu = i;
  711.                         bs = j;
  712.                         bf = -1;
  713.                         ba = -1;
  714.                         target = spPos[j];
  715.                     }
  716.                 }
  717.                 REP(j, XFORTIFY.S) if (unitType[i] == UT_CANNON && xfUsed[j] == 0) {
  718.                     double av = 1e9 - hexDist(XFORTIFY[j], unitPos[i]);
  719.                     if (av > bv) {
  720.                         bv = av;
  721.                         bu = i;
  722.                         bs = -1;
  723.                         bf = j;
  724.                         ba = -1;
  725.                         target = XFORTIFY[j];
  726.                     }
  727.                 }
  728.                 REP(j, XSCOUT.S) if (unitType[i] == UT_ARMORED && xaUsed[j] == 0) {
  729.                     double av = 1e9 - hexDist(XSCOUT[j], unitPos[i]);
  730.                     if (av > bv) {
  731.                         bv = av;
  732.                         bu = i;
  733.                         bs = -1;
  734.                         bf = -1;
  735.                         ba = j;
  736.                         target = XSCOUT[j];
  737.                     }
  738.                 }
  739.             }
  740.            
  741.             if (bu == -1) break;
  742.            
  743.             unitBusy[bu] = 100;
  744.             if (bs != -1) spUsed[bs]++;
  745.             if (bf != -1) xfUsed[bf]++;
  746.             if (ba != -1) xaUsed[ba]++;
  747.            
  748.             if (bf != -1 && unitPos[bu] == XFORTIFY[bf]) continue;
  749.             if (ba != -1 && unitPos[bu] == XSCOUT[ba]) continue;
  750.            
  751.             bv = 1e9;
  752.                
  753.             int dir = -1;
  754.             REP(d, 6) {
  755.                 PII np = MP(unitPos[bu].X + dx[d], unitPos[bu].Y + dy[d]);
  756.                 if (!canMove(np.X, np.Y)) continue;
  757.                 double av = hexDist(target, np);
  758.                 if (dir == -1 || av < bv) {
  759.                     bv = av;
  760.                     dir = d;
  761.                 } else if (av == bv && rand() % 2) {
  762.                     dir = d;
  763.                 }
  764.             }
  765.             if (dir == -1) continue;
  766.            
  767.             if (cmdLeft-- == 0) throw 1;
  768.             network.sendLine("MOVE " + i2s(unitID[bu]) + " " + i2s(dx[dir]) + " " + i2s(dy[dir]));
  769.             network.readOk();
  770.         }
  771.        
  772.         REP(i, unitNo) if (unitBusy[i] == 0) {
  773.             int dir = rand() % 6;
  774.             if (!canMove(unitPos[i].X + dx[dir], unitPos[i].Y + dy[dir])) continue;
  775.             if (cmdLeft-- == 0) throw 1;
  776.             network.sendLine("MOVE " + i2s(unitID[i]) + " " + i2s(dx[dir]) + " " + i2s(dy[dir]));
  777.             network.readOk();
  778.         }
  779.         } catch (int e) { }
  780.        
  781.         ZERO(xp);
  782.         ZERO(fu);
  783.        
  784.         if (shotsFired || coverShotsFired) addLog("SHOTS: " + i2s(shotsFired) + " COVER: " + i2s(coverShotsFired) + " DESTROYED: " + i2s(destroyed));
  785.         REP(i, mpN) REP(j, mpN) ls[i][j] = max(0, ls[i][j]-1);
  786.        
  787.       gameUpdate.unlock();
  788.        
  789.         needUpdate = true;
  790.         cout << "Turn (T-" << turnsLeft << ") Finished" << endl;
  791.         newGame = false;
  792.   }
  793. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement