Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #include <sys/time.h>
- #include <unistd.h>
- #include <CImg.h>
- using namespace std;
- using namespace cimg_library;
- #define INLINE inline __attribute__ ((always_inline))
- #define NOINLINE __attribute__ ((noinline))
- #define ALIGNED __attribute__ ((aligned(16)))
- #define likely(x) __builtin_expect(!!(x),1)
- #define unlikely(x) __builtin_expect(!!(x),0)
- #define SSELOAD(a) _mm_load_si128((__m128i*)&a)
- #define SSESTORE(a, b) _mm_store_si128((__m128i*)&a, b)
- #define byte unsigned char
- #define FOR(i,a,b) for(int i=(a);i<(b);++i)
- #define REP(i,a) FOR(i,0,a)
- #define ZERO(m) memset(m,0,sizeof(m))
- #define ALL(x) x.begin(),x.end()
- #define PB push_back
- #define S size()
- #define LL long long
- #define ULL unsigned long long
- #define LD long double
- #define MP make_pair
- #define X first
- #define Y second
- #define VC vector
- #define PII pair <int, int>
- #define VB VC < byte >
- #define VVB VC < VB >
- #define VI VC < int >
- #define VVI VC < VI >
- #define VVVI VC < VVI >
- #define VPII VC < PII >
- #define VD VC < double >
- #define VVD VC < VD >
- #define VVVD VC < VVD >
- #define VF VC < float >
- #define VVF VC < VF >
- #define VVVF VC < VVF >
- #define VS VC < string >
- #define VVS VC < VS >
- #define DB(a) cout << #a << ": " << (a) << endl;
- template<class A, class B> ostream& operator<<(ostream &os, pair<A,B> &p) {os << "(" << p.X << "," << p.Y << ")"; return os;}
- 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;}
- template<class T> ostream& operator<<(ostream &os, VC<T> &v) {os << "{"; REP(i, v.S) {if (i) os << ", "; os << v[i];} os << "}"; return os;}
- template<class T> string i2s(T x) {ostringstream o; o << x; return o.str();}
- 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;}
- int turnsLeft;
- VS logData;
- void addLog(string s) {
- s = "Turn: " + i2s(turnsLeft) + " :: " + s;
- logData.PB(s);
- }
- #include "lib.cpp"
- int hexDist(PII p0, PII p1) {
- if (p0.Y > p1.Y) swap(p0, p1);
- int dy = p1.Y - p0.Y;
- int dx = p1.X - p0.X;
- if (dy == 0) return abs(dx);
- if (dx < 0) return dy - dx;
- if (dx > dy) return dx;
- return dy;
- }
- inline int between(double a, double b, double c) {
- return a >= b && a <= c;
- }
- vector<pair<int,int> > visible2(int targetx, int targety, double move) {
- double pi = 2.0 * acos(0.0);
- double h = sqrt(3.0) / 2.0;
- const int K = 6;
- double ddx[K], ddy[K];
- int range = 10;
- REP(i,K){
- double a = 2 * pi / K * i + pi / 6.0;
- ddx[i] = cos(a);
- ddy[i] = sin(a);
- // printf("kat=%.6lf\n", atan2(ddy[i], ddx[i]));
- }
- vector<pair<int,int> > blocking;
- for (int dx = -range; dx <= range; ++dx) for (int dy = -range; dy <= range; ++dy) {
- int d = hexDist(make_pair(0,0), make_pair(dx, dy));
- if (d > 0 && d < hexDist(make_pair(0,0), make_pair(targetx, targety))) {
- blocking.push_back(make_pair(dx, dy));
- }
- }
- vector<pair<int,int> > res;
- if (targety == 0 && targetx > 0) {
- for (int x = 1; x < targetx; ++x) res.push_back(make_pair(x, 0));
- return res;
- }
- for (auto p : blocking) {
- int ok = 0;
- double px = 0.0;
- double py = 0.0;
- px += targetx * 2.0 * h;
- px -= targety * h;
- py -= targety * 1.5;
- double angle = atan2(py, px);
- if (angle < 0) angle += 2.0 * pi;
- // printf("dx = %d dy = %d angle = %lf\n", dx, dy, angle);
- double hit_angle = angle + move;
- if (hit_angle > 2 * pi) hit_angle -= 2 * pi;
- else if (hit_angle < 0) hit_angle += 2 * pi;
- vector<double> pom;
- double amax = 0.0;
- double amin = 2.0 * pi;
- REP(i,K) {
- px = 0.0; py = 0.0;
- px += p.first * 2.0 * h;
- px -= p.second * h;
- py -= p.second * 1.5;
- px += ddx[i];
- py += ddy[i];
- angle = atan2(py, px);
- if (angle < 0) angle += 2.0 * pi;
- pom.push_back(angle);
- amax = max(amax, angle);
- amin = min(amin, angle);
- }
- //printf("para=(%d,%d) amin=%lf amax=%lf hit=%lf\n", p.first, p.second, amin, amax, hit_angle);
- if (amax - amin <= pi) {
- if (between(hit_angle, amin, amax)) ok = 1;
- } else {
- amax = 0.0;
- amin = 2.0 * pi;
- for (auto a : pom) {
- if (a < pi) amax = max(amax, a);
- else amin = min(amin, a);
- }
- if (between(hit_angle, 0.0, amax)) ok = 1;
- if (between(hit_angle, amin, 2.0 * pi)) ok = 1;
- }
- if (ok) res.push_back(p);
- }
- return res;
- }
- // mode=1 LEFT
- // mode=2 RIGHT
- // mode=3 BOTH
- vector<pair<int,int> > visible(int offset_x, int offset_y, int mode) {
- vector<pair<int,int> > res, pom;
- const double EPS = 1E-6;
- if (mode & 1) {
- pom = visible2(offset_x, offset_y, EPS);
- for (auto p : pom) res.push_back(p);
- }
- if (mode & 2) {
- pom = visible2(offset_x, offset_y, -EPS);
- for (auto p : pom) res.push_back(p);
- }
- sort(res.begin(), res.end());
- res.erase(unique(res.begin(), res.end()), res.end());
- vector<pair<int,int> > perm;
- for (int i = 0; i < (int)res.size(); ++i) perm.push_back(make_pair(hexDist(make_pair(0,0), res[i]), i));
- sort(perm.begin(), perm.end());
- vector<pair<int,int> > res2;
- for (int i = 0; i < (int)perm.size(); ++i) res2.push_back(res[perm[i].second]);
- return res2;
- }
- struct RNG {
- unsigned int MT[624];
- int index;
- RNG(int seed = 1) {
- init(seed);
- }
- void init(int seed = 1) {
- MT[0] = seed;
- FOR(i, 1, 624) MT[i] = (1812433253UL * (MT[i-1] ^ (MT[i-1] >> 30)) + i);
- index = 0;
- }
- void generate() {
- const unsigned int MULT[] = {0, 2567483615UL};
- REP(i, 227) {
- unsigned int y = (MT[i] & 0x8000000UL) + (MT[i+1] & 0x7FFFFFFFUL);
- MT[i] = MT[i+397] ^ (y >> 1);
- MT[i] ^= MULT[y&1];
- }
- FOR(i, 227, 623) {
- unsigned int y = (MT[i] & 0x8000000UL) + (MT[i+1] & 0x7FFFFFFFUL);
- MT[i] = MT[i-227] ^ (y >> 1);
- MT[i] ^= MULT[y&1];
- }
- unsigned int y = (MT[623] & 0x8000000UL) + (MT[0] & 0x7FFFFFFFUL);
- MT[623] = MT[623-227] ^ (y >> 1);
- MT[623] ^= MULT[y&1];
- }
- unsigned int rand() {
- if (index == 0) {
- generate();
- }
- unsigned int y = MT[index];
- y ^= y >> 11;
- y ^= y << 7 & 2636928640UL;
- y ^= y << 15 & 4022730752UL;
- y ^= y >> 18;
- index = index == 623 ? 0 : index + 1;
- return y;
- }
- INLINE int next() {
- return rand();
- }
- INLINE int next(int x) {
- return rand() % x;
- }
- INLINE int next(int a, int b) {
- return a + (rand() % (b - a));
- }
- INLINE double nextDouble() {
- return (rand() + 0.5) * (1.0 / 4294967296.0);
- }
- };
- int s2i(string s) {
- return atoi(s.c_str());
- }
- double s2f(string s) {
- return atof(s.c_str());
- }
- const int MAX_MAPN = 210;
- const int MAX_UNITS = 1000;
- const int MAX_SPS = 1000;
- const int MAX_EUNITS = 10000;
- mutex gameUpdate;
- int mpN;
- int turnTime;
- int scoreHQ;
- int scoreSP;
- int gameGrace;
- int gameInactivity;
- int gameShortening;
- int maxCommands;
- double scoreScaling;
- int lastTurnsLeft = 0;
- char mp[MAX_MAPN][MAX_MAPN];
- int xp[MAX_MAPN][MAX_MAPN];
- int fu[MAX_MAPN][MAX_MAPN];
- int cn[MAX_MAPN][MAX_MAPN];
- int ls[MAX_MAPN][MAX_MAPN];
- bool newVGame = false;
- const int UT_UNKNOWN = 0;
- const int UT_CANNON = 1;
- const int UT_TANK = 2;
- const int UT_ARMORED = 3;
- const int UT_HQ = 4;
- int parseUnitType(string s) {
- return s == "CANNON" ? UT_CANNON : s == "TANK" ? UT_TANK : s == "ARMORED" ? UT_ARMORED : s == "HQ" ? UT_HQ : UT_UNKNOWN;
- }
- int points;
- int spNo;
- PII spPos[MAX_SPS];
- int spOwner[MAX_SPS];
- int enunitNo;
- PII enunitPos[MAX_EUNITS];
- int enunitType[MAX_EUNITS];
- int enunitStamina[MAX_EUNITS];
- int enunitOwner[MAX_EUNITS];
- int unitNo;
- int unitID[MAX_UNITS];
- PII unitPos[MAX_UNITS];
- int unitType[MAX_UNITS];
- int unitStamina[MAX_UNITS];
- int unitBusy[MAX_UNITS];
- int HQID;
- #define byte unsigned char
- int UNITS_LIMIT = 0;
- int BUILD_CANNONS = 2;
- bool ORDER_WAIT = 0;
- bool FORCE_STAT = 1;
- VPII XIGNORE;
- VPII XFORTIFY;
- VPII XCOVER;
- VPII XSCOUT;
- int SCOUT_QUEUE = 0;
- PII HQ_TARGET = MP(-1,-1);
- bool needUpdate = false;
- bool mapUpdated = false;
- void toggleElement(VPII &v, int x, int y) {
- REP(i, v.S) if (v[i].X == x && v[i].Y == y) {
- swap(v[i], v[v.S-1]);
- v.pop_back();
- return;
- }
- v.PB(MP(x, y));
- }
- bool canMove(int x, int y) {
- if (x < 0 || x >= mpN || y < 0 || y >= mpN) return false;
- if (xp[x][y]) return false;
- if (mp[x][y] == 'L') return false;
- return true;
- }
- bool canMove(PII p) {
- return canMove(p.X, p.Y);
- }
- bool lineOfFire(int type, PII &s, VPII &p) {
- REP(i, p.S) if (fu[p[i].X][p[i].Y]) return false;
- return true;
- }
- bool lineOfSight(int type, PII &s, VPII &p) {
- char t = mp[s.X][s.Y];
- if (p.S == 0) return false;
- int len = type == UT_ARMORED ? 5 : 4;
- if (t == 'H' && mp[p[p.S-1].X][p[p.S-1].Y] == 'H') return hexDist(p[p.S-1], s) <= len;
- if (t == 'H') len *= 2;
- if (hexDist(p[p.S-1], s) > len) return false;
- if (t == 0) return true;
- REP(i, ((int)p.S) - 1) {
- char c = mp[p[i].X][p[i].Y];
- if (c == 'F' || c == 'H') return false;
- if (c == 'L' || c == 'P') continue;
- if (c == 'B' && t != 'H') return false;
- }
- return true;
- }
- int dx[] = {-1,1,0,0,-1,1};
- int dy[] = {0,0,-1,1,-1,1};
- bool newGame = true;
- class XGame : public Game {
- void saveGameState() { }
- void loadGameState() { }
- void clearGameState() {
- gameUpdate.lock();
- gameUpdate.unlock();
- }
- void play() {
- int shotsFired = 0;
- int coverShotsFired = 0;
- int destroyed = 0;
- try {
- string line;
- VS vs;
- gameUpdate.lock();
- //analyze DESCRIBE_WORLD
- network.sendLine("DESCRIBE_WORLD");
- network.readOk();
- line = network.readLine();
- vs = splt(line);
- mpN = s2i(vs[0]);
- turnTime = s2i(vs[1]);
- scoreHQ = s2i(vs[2]);
- scoreSP = s2i(vs[3]);
- gameGrace = s2i(vs[4]);
- gameInactivity = s2i(vs[5]);
- gameShortening = s2i(vs[6]);
- maxCommands = s2i(vs[7]);
- scoreScaling = s2f(vs[8]);
- int cmdLeft = maxCommands - 1;
- //analyze LIST_UNITS
- network.sendLine("LIST_UNITS");
- network.readOk();
- cmdLeft--;
- line = network.readLine();
- unitNo = s2i(line);
- REP(i, unitNo) {
- line = network.readLine();
- vs = splt(line);
- unitID[i] = s2i(vs[0]);
- unitPos[i].X = s2i(vs[1]) - 1;
- unitPos[i].Y = s2i(vs[2]) - 1;
- unitType[i] = parseUnitType(vs[3]);
- assert(unitType[i] != UT_UNKNOWN);
- unitStamina[i] = vs[4] == "INF" ? -1 : s2i(vs[4]);
- unitBusy[i] = s2i(vs[5]);
- xp[unitPos[i].X][unitPos[i].Y] = 1;
- fu[unitPos[i].X][unitPos[i].Y] = 1;
- }
- HQID = -1;
- REP(i, unitNo) if (unitType[i] == UT_HQ) HQID = i;
- //analyze LIST_ENEMIES
- network.sendLine("LIST_ENEMIES");
- network.readOk();
- cmdLeft--;
- enunitNo = s2i(network.readLine());
- REP(i, enunitNo) {
- line = network.readLine();
- vs = splt(line);
- enunitPos[i].X = s2i(vs[0]) - 1;
- enunitPos[i].Y = s2i(vs[1]) - 1;
- enunitType[i] = parseUnitType(vs[2]);
- enunitStamina[i] = vs[3] == "INF" ? -1 : s2i(vs[3]);
- enunitOwner[i] = s2i(vs[4]);
- if (enunitType[i] != UT_HQ) xp[enunitPos[i].X][enunitPos[i].Y] = 1;
- if (enunitType[i] == UT_HQ) fu[enunitPos[i].X][enunitPos[i].Y] = 1;
- }
- //analyze LIST_STRATEGIC_POINTS
- network.sendLine("LIST_STRATEGIC_POINTS");
- network.readOk();
- cmdLeft--;
- spNo = s2i(network.readLine());
- REP(i, spNo) {
- line = network.readLine();
- vs = splt(line);
- spPos[i].X = s2i(vs[0]) - 1;
- spPos[i].Y = s2i(vs[1]) - 1;
- spOwner[i] = vs[2] == "NONE" ? -1 : vs[2] == "YOURS" ? 0 : s2i(vs[2]);
- }
- //analyze TIME_TO_END
- network.sendLine("TIME_TO_END");
- network.readOk();
- cmdLeft--;
- turnsLeft = s2i(network.readLine());
- if (turnsLeft > lastTurnsLeft) {
- points = 0;
- newGame = true;
- newVGame = true;
- UNITS_LIMIT = maxCommands;
- BUILD_CANNONS = 2;
- XIGNORE.clear();
- XFORTIFY.clear();
- XCOVER.clear();
- XSCOUT.clear();
- HQ_TARGET = MP(-1,-1);
- SCOUT_QUEUE = 0;
- ORDER_WAIT = false;
- FORCE_STAT = true;
- mapUpdated = false;
- REP(i, mpN) REP(j, mpN) cn[i][j] = 1;
- addLog("NEW GAME");
- cout << "NEW GAME" << endl;
- }
- lastTurnsLeft = turnsLeft;
- //analyze MY_STAT
- if (points < 10 || FORCE_STAT) {
- network.sendLine("MY_STAT");
- network.readOk();
- cmdLeft--;
- int oldPoints = points;
- points = s2i(network.readLine());
- if (FORCE_STAT) {
- int spBonus = 0;
- REP(i, spNo) if (spOwner[i] == 0) spBonus += scoreSP;
- destroyed = (points - oldPoints - spBonus) / 5;
- }
- }
- shotsFired = 0;
- //analyze LOOK_AROUND
- if (!mapUpdated) {
- network.sendLine("LOOK_AROUND");
- cmdLeft--;
- if (network.readOk()) {
- mapUpdated = true;
- REP(i, mpN) {
- string s = network.readLine();
- REP(j, mpN) mp[j][i] = s[j];
- }
- REP(i, mpN) REP(j, mpN) cn[i][j] = 0;
- queue<int> q;
- REP(i, unitNo) q.push(unitPos[i].X), q.push(unitPos[i].Y);
- int vis = 0;
- while (!q.empty()) {
- int x = q.front(); q.pop();
- int y = q.front(); q.pop();
- if (x < 0 || x >= mpN || y < 0 || y >= mpN || mp[x][y] == 'L' || cn[x][y]) continue;
- cn[x][y] = 1;
- vis++;
- REP(d, 6) q.push(x + dx[d]), q.push(y + dy[d]);
- }
- DB(vis);
- }
- }
- REP(i, XIGNORE.S) xp[XIGNORE[i].X][XIGNORE[i].Y] = 1;
- //capture HQ
- REP(i, unitNo) if (unitBusy[i] == 0 && unitType[i] != UT_HQ) REP(j, enunitNo) if (enunitType[j] == UT_HQ) {
- REP(d, 6) {
- PII np = MP(unitPos[i].X + dx[d], unitPos[i].Y + dy[d]);
- if (np == enunitPos[j]) {
- unitBusy[i] = 100;
- if (cmdLeft-- == 0) throw 1;
- network.sendLine("MOVE " + i2s(unitID[i]) + " " + i2s(dx[d]) + " " + i2s(dy[d]));
- network.readOk();
- break;
- }
- }
- }
- //attack orders
- REP(i, unitNo) {
- if (cmdLeft <= 1) break;
- if (unitType[i] == UT_HQ) continue;
- if (unitType[i] == UT_CANNON && ls[unitPos[i].X][unitPos[i].Y]) continue;
- VI targets;
- REP(j, enunitNo) {
- if (enunitType[j] == UT_HQ) continue;
- int dist = hexDist(unitPos[i], enunitPos[j]);
- 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;
- if (unitType[i] != UT_CANNON) {
- int range = unitType[i] == UT_TANK ? 5 : 4;
- if (mp[unitPos[i].X][unitPos[i].Y] == 'H' && mp[enunitPos[j].X][enunitPos[j].Y] != 'H') range++;
- if (dist > range) continue;
- PII diff = MP(enunitPos[j].X - unitPos[i].X, enunitPos[j].Y - unitPos[i].Y);
- VPII sight1 = visible(diff.X, diff.Y, 1);
- VPII sight2 = visible(diff.X, diff.Y, 2);
- VPII sight3 = visible(diff.X, diff.Y, 3);
- sight1.PB(diff);
- sight2.PB(diff);
- sight3.PB(diff);
- for (PII &p : sight1) p.X += unitPos[i].X, p.Y += unitPos[i].Y;
- for (PII &p : sight2) p.X += unitPos[i].X, p.Y += unitPos[i].Y;
- for (PII &p : sight3) p.X += unitPos[i].X, p.Y += unitPos[i].Y;
- // if (dist > 1) continue;
- if (!lineOfSight(unitType[i], unitPos[i], sight1) && !lineOfSight(unitType[i], unitPos[i], sight2)) continue;
- if (!lineOfFire(unitType[i], unitPos[i], sight3)) continue;
- }
- targets.PB(j);
- }
- if (targets.S == 0) continue;
- int j = targets[rand()%targets.S];
- string cmd = "SHOOT " + i2s(unitID[i]) + " " + i2s(enunitPos[j].X - unitPos[i].X) + " " + i2s(enunitPos[j].Y - unitPos[i].Y);
- if (unitBusy[i]) {
- if (cmdLeft-- == 0) throw 1;
- network.sendLine("CANCEL_MOVE " + i2s(unitID[i]));
- network.readOk();
- }
- if (cmdLeft-- == 0) throw 1;
- network.sendLine(cmd);
- shotsFired++;
- cout << "SHOOT: " << hexDist(unitPos[i], enunitPos[j]) << endl;
- if (network.readOk()) {
- line = network.readLine();
- vs = splt(line);
- int hitx = s2i(vs[0]) - 1;
- int hity = s2i(vs[1]) - 1;
- if (hitx != enunitPos[j].X || hity != enunitPos[j].Y) addLog("SHOOT FAILED: " + cmd + " HIT: " + i2s(hitx) + ":" + i2s(hity));
- ls[unitPos[i].X][unitPos[i].Y] = unitType[i] == UT_CANNON ? 2 : 1;
- }
- unitBusy[i] = 100;
- }
- //cover attacks
- REP(i, XCOVER.S) {
- bool bad = false;
- REP(j, unitNo) bad |= XCOVER[i] == unitPos[j];
- if (bad) {
- swap(XCOVER[i], XCOVER[XCOVER.S-1]);
- i--;
- XCOVER.pop_back();
- }
- }
- VI xcUsed(XCOVER.S, 0);
- REP(i, unitNo) if (unitType[i] == UT_CANNON && unitBusy[i] == 0 && ls[unitPos[i].X][unitPos[i].Y] == 0) {
- if (cmdLeft <= 1) break;
- VI targets;
- REP(j, XCOVER.S) if (xcUsed[j] == 0) {
- int dist = hexDist(unitPos[i], XCOVER[j]);
- if (dist < 3 || dist > 8 + (mp[XCOVER[j].X][XCOVER[j].Y] != 'H' && mp[unitPos[i].X][unitPos[i].Y] == 'H' ? 1 : 0)) continue;
- targets.PB(j);
- }
- if (targets.S == 0) continue;
- int j = targets[rand()%targets.S];
- string cmd = "SHOOT " + i2s(unitID[i]) + " " + i2s(XCOVER[j].X - unitPos[i].X) + " " + i2s(XCOVER[j].Y - unitPos[i].Y);
- if (cmdLeft-- == 0) throw 1;
- network.sendLine(cmd);
- if (network.readOk()) {
- coverShotsFired++;
- line = network.readLine();
- ls[unitPos[i].X][unitPos[i].Y] = unitType[i] == UT_CANNON ? 2 : 1;
- }
- unitBusy[i] = 100;
- xcUsed[j] = 1;
- }
- int cannonsNo = 0;
- REP(i, unitNo) cannonsNo += unitType[i] == UT_CANNON;
- //build order
- bool buildOk = false;
- if (HQID != -1) REP(d, 6) buildOk |= canMove(unitPos[HQID].X + dx[d], unitPos[HQID].Y + dy[d]);
- if (points >= 10 && unitNo < UNITS_LIMIT && HQID != -1 && buildOk) {
- if (cmdLeft-- == 0) throw 1;
- if (SCOUT_QUEUE > 0) {
- network.sendLine("CREATE_UNIT ARMORED");
- SCOUT_QUEUE--;
- addLog("BUILD ARMORED");
- } else if (cannonsNo < 5 && (BUILD_CANNONS == 2 || BUILD_CANNONS == 1 && rand() % 4)) {
- network.sendLine("CREATE_UNIT CANNON");
- addLog("BUILD CANNON");
- } else {
- network.sendLine("CREATE_UNIT TANK");
- addLog("BUILD TANK");
- }
- if (network.readOk()) line = network.readLine();
- points -= 10;
- unitBusy[HQID] = 100;
- }
- //MOVE HQ
- if (HQID == -1 || unitPos[HQID] == HQ_TARGET) HQ_TARGET = MP(-1,-1);
- if (HQID != -1) {
- if (HQ_TARGET.X == -1) {
- if (HQID != -1) unitBusy[HQID] = 100;
- } else if (unitBusy[HQID] == 0) {
- double bv = 1e9;
- int dir = -1;
- REP(d, 6) {
- PII np = MP(unitPos[HQID].X + dx[d], unitPos[HQID].Y + dy[d]);
- if (!canMove(np)) continue;
- double av = hexDist(HQ_TARGET, np);
- if (av < bv) {
- dir = d;
- bv = av;
- }
- }
- if (dir != -1) {
- unitBusy[HQID] = 100;
- if (cmdLeft-- == 0) throw 1;
- network.sendLine("MOVE " + i2s(unitID[HQID]) + " " + i2s(dx[dir]) + " " + i2s(dy[dir]));
- network.readOk();
- }
- }
- }
- //remain on SP
- REP(i, unitNo) if (unitType[i] != UT_CANNON) REP(j, spNo) if (unitPos[i] == spPos[j]) {
- unitBusy[i] = 1000;
- break;
- }
- if (ORDER_WAIT) throw 1;
- //move orders
- VI xfUsed(XFORTIFY.S, 0);
- VI xaUsed(XSCOUT.S, 0);
- VI spUsed(spNo, 0);
- while (true) {
- double bv = 0;
- int bu = -1;
- int bs = -1;
- int bf = -1;
- int ba = -1;
- PII target = MP(-1, -1);
- REP(i, unitNo) if (unitBusy[i] == 0) {
- REP(j, spNo) if (spOwner[j] != 0 && cn[spPos[j].X][spPos[j].Y]) {
- double av = 1e9 - hexDist(spPos[j], unitPos[i]) - 50 * (spOwner[j] != -1) - 25 * spUsed[j];
- if (av > bv) {
- bv = av;
- bu = i;
- bs = j;
- bf = -1;
- ba = -1;
- target = spPos[j];
- }
- }
- REP(j, XFORTIFY.S) if (unitType[i] == UT_CANNON && xfUsed[j] == 0) {
- double av = 1e9 - hexDist(XFORTIFY[j], unitPos[i]);
- if (av > bv) {
- bv = av;
- bu = i;
- bs = -1;
- bf = j;
- ba = -1;
- target = XFORTIFY[j];
- }
- }
- REP(j, XSCOUT.S) if (unitType[i] == UT_ARMORED && xaUsed[j] == 0) {
- double av = 1e9 - hexDist(XSCOUT[j], unitPos[i]);
- if (av > bv) {
- bv = av;
- bu = i;
- bs = -1;
- bf = -1;
- ba = j;
- target = XSCOUT[j];
- }
- }
- }
- if (bu == -1) break;
- unitBusy[bu] = 100;
- if (bs != -1) spUsed[bs]++;
- if (bf != -1) xfUsed[bf]++;
- if (ba != -1) xaUsed[ba]++;
- if (bf != -1 && unitPos[bu] == XFORTIFY[bf]) continue;
- if (ba != -1 && unitPos[bu] == XSCOUT[ba]) continue;
- bv = 1e9;
- int dir = -1;
- REP(d, 6) {
- PII np = MP(unitPos[bu].X + dx[d], unitPos[bu].Y + dy[d]);
- if (!canMove(np.X, np.Y)) continue;
- double av = hexDist(target, np);
- if (dir == -1 || av < bv) {
- bv = av;
- dir = d;
- } else if (av == bv && rand() % 2) {
- dir = d;
- }
- }
- if (dir == -1) continue;
- if (cmdLeft-- == 0) throw 1;
- network.sendLine("MOVE " + i2s(unitID[bu]) + " " + i2s(dx[dir]) + " " + i2s(dy[dir]));
- network.readOk();
- }
- REP(i, unitNo) if (unitBusy[i] == 0) {
- int dir = rand() % 6;
- if (!canMove(unitPos[i].X + dx[dir], unitPos[i].Y + dy[dir])) continue;
- if (cmdLeft-- == 0) throw 1;
- network.sendLine("MOVE " + i2s(unitID[i]) + " " + i2s(dx[dir]) + " " + i2s(dy[dir]));
- network.readOk();
- }
- } catch (int e) { }
- ZERO(xp);
- ZERO(fu);
- if (shotsFired || coverShotsFired) addLog("SHOTS: " + i2s(shotsFired) + " COVER: " + i2s(coverShotsFired) + " DESTROYED: " + i2s(destroyed));
- REP(i, mpN) REP(j, mpN) ls[i][j] = max(0, ls[i][j]-1);
- gameUpdate.unlock();
- needUpdate = true;
- cout << "Turn (T-" << turnsLeft << ") Finished" << endl;
- newGame = false;
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement