Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "MyStrategy.h"
- #define _USE_MATH_DEFINES
- #include <cmath>
- #include <cstdlib>
- #include <string>
- #include <set>
- #include <map>
- #include <algorithm>
- #include <cassert>
- #define ENABLE_LOGGING 0
- const char * trooperTypeNames [] = {"UNKNOWN_TROOPER", "COMMANDER", "FIELD_MEDIC", "SOLDIER", "SNIPER", "SCOUT"};
- int trooperMoveOrderIndex = 0;
- #if ENABLE_LOGGING
- #include <iostream>
- #define LOG(x_) cout << g_world->getMoveIndex() << "-" << trooperMoveOrderIndex << "|" << g_self->getTeammateIndex() << "-" << trooperTypeNames[g_self->getType() + 1] << ":" << g_self->getHitpoints() << "|" << x_ << std::endl
- std::string pad(int l)
- {
- std::string res;
- for (int i = 0; i < l; ++i)
- res += "----";
- res += "]";
- return res;
- }
- //#define LOG_PAD(i, x) LOG(pad(i) << x)
- #define LOG_PAD(i, x)
- #else
- #define LOG(x)
- #define LOG_PAD(i, x)
- #endif
- #define INF_DIST 1000000
- #define W 30
- #define H 20
- #define TOOPERS_COUNT 5
- #define COVER_KNEELING 20.0
- #define COVER_PRONE 50.0
- int ENEMY_TROOPERSN;
- using namespace model;
- using namespace std;
- const World * g_world;
- const Trooper * g_self;
- const Game * g_game;
- Move * g_move;
- int moveIndex = -1;
- map<TrooperType, int> moveOrder;
- map<TrooperType, int> stuck;
- unsigned int sp_random(unsigned int range)
- {
- static unsigned int seed = 1234567890;
- seed = (seed * 58321) + 11113;
- return (seed >> 16) % range;
- }
- vector<const Trooper *> troopersMap;
- struct Point
- {
- int x, y;
- Point() {}
- Point(int x, int y) : x(x), y(y) {}
- Point(const Point &o) : x(o.x), y(o.y) {}
- Point(const Unit &unit)
- {
- x = unit.getX();
- y = unit.getY();
- }
- bool isClose(const Point & o) const
- {
- int dx = abs(x - o.x);
- int dy = abs(y - o.y);
- return dx == 0 && dy == 1 || dx == 1 && dy == 0;
- }
- bool operator == (const Point & o) const
- {
- return x == o.x && y == o.y;
- }
- Point & operator = (const Point & o)
- {
- x = o.x;
- y = o.y;
- return *this;
- }
- bool operator < (const Point & o) const
- {
- return (y*W + x) < (o.y*W + o.x);
- }
- int dist2(const Point &o) const
- {
- return (x - o.x)*(x - o.x) + (y - o.y)*(y - o.y);
- }
- int sqDist(const Point &o) const
- {
- return abs(x - o.x) + abs(y - o.y);
- }
- };
- vector<Point> nearDistDeltas;
- vector<Point> aheadDistDeltas1;
- vector<Point> aheadDistDeltas2;
- vector<Point> sideDistDeltas1;
- vector<Point> sideDistDeltas2;
- vector<Point> backDistDeltas1;
- vector<Point> backDistDeltas2;
- void initializeNearDistDeltas()
- {
- nearDistDeltas.push_back(Point(0, 0));
- nearDistDeltas.push_back(Point(-1, 0));
- nearDistDeltas.push_back(Point(1, 0));
- nearDistDeltas.push_back(Point(0, -1));
- nearDistDeltas.push_back(Point(0, 1));
- nearDistDeltas.push_back(Point(-1, -1));
- nearDistDeltas.push_back(Point(-1, 1));
- nearDistDeltas.push_back(Point(1, -1));
- nearDistDeltas.push_back(Point(1, 1));
- nearDistDeltas.push_back(Point(-2, 0));
- nearDistDeltas.push_back(Point(2, 0));
- nearDistDeltas.push_back(Point(0, -2));
- nearDistDeltas.push_back(Point(0, 2));
- nearDistDeltas.push_back(Point(-2, -1));
- nearDistDeltas.push_back(Point(-2, 1));
- nearDistDeltas.push_back(Point(2, -1));
- nearDistDeltas.push_back(Point(2, 1));
- nearDistDeltas.push_back(Point(-1, -2));
- nearDistDeltas.push_back(Point(1, -2));
- nearDistDeltas.push_back(Point(-1, 2));
- nearDistDeltas.push_back(Point(1, 2));
- nearDistDeltas.push_back(Point(-2, -2));
- nearDistDeltas.push_back(Point(-2, 2));
- nearDistDeltas.push_back(Point(2, -2));
- nearDistDeltas.push_back(Point(2, 2));
- nearDistDeltas.push_back(Point(-3, 0));
- nearDistDeltas.push_back(Point(3, 0));
- nearDistDeltas.push_back(Point(0, -3));
- nearDistDeltas.push_back(Point(0, 3));
- nearDistDeltas.push_back(Point(-3, -1));
- nearDistDeltas.push_back(Point(-3, 1));
- nearDistDeltas.push_back(Point(3, -1));
- nearDistDeltas.push_back(Point(3, 1));
- nearDistDeltas.push_back(Point(-1, -3));
- nearDistDeltas.push_back(Point(1, -3));
- nearDistDeltas.push_back(Point(-1, 3));
- nearDistDeltas.push_back(Point(1, 3));
- aheadDistDeltas1.push_back(Point(1, 0));
- aheadDistDeltas1.push_back(Point(1, 1));
- aheadDistDeltas1.push_back(Point(1, -1));
- aheadDistDeltas2.push_back(Point(2, 0));
- aheadDistDeltas2.push_back(Point(2, 1));
- aheadDistDeltas2.push_back(Point(2, -1));
- sideDistDeltas1.push_back(Point(0, -1));
- sideDistDeltas1.push_back(Point(0, 1));
- sideDistDeltas2.push_back(Point(0, -2));
- sideDistDeltas2.push_back(Point(0, 2));
- backDistDeltas1.push_back(Point(-1, 0));
- backDistDeltas1.push_back(Point(-1, 1));
- backDistDeltas1.push_back(Point(-1, -1));
- backDistDeltas2.push_back(Point(-2, 0));
- backDistDeltas2.push_back(Point(-2, 1));
- backDistDeltas2.push_back(Point(-2, -1));
- }
- map<Point, int> bonusInUse;
- bool checkBounds(const Point &p)
- {
- if (p.x < 0 || p.x >= W || p.y < 0 || p.y >= H)
- return false;
- return true;
- }
- bool checkPoint(const Point &p)
- {
- return checkBounds(p) && g_world->getCells()[p.x][p.y] == FREE;
- }
- struct Position : public Point
- {
- int stance;
- Position() {}
- Position(const Trooper &tr)
- {
- x = tr.getX();
- y = tr.getY();
- stance = (int) tr.getStance();
- }
- Position(int x, int y, int stance)
- {
- this->x = x;
- this->y = y;
- this->stance = stance;
- }
- bool isClose(const Position & o) const
- {
- int dx = abs(x - o.x);
- int dy = abs(y - o.y);
- int ds = abs(stance - o.stance);
- return (dx == 0 && dy == 1 || dx == 1 && dy == 0) && ds == 0 || (dx == 0 && dy == 0 && ds == 1);
- }
- bool isValid() const
- {
- return stance >= 0 && stance < _TROOPER_STANCE_COUNT_ && checkBounds(*this);
- }
- bool operator == (const Position & o) const
- {
- return x == o.x && y == o.y && stance == o.stance;
- }
- Position & operator = (const Position & o)
- {
- x = o.x;
- y = o.y;
- stance = o.stance;
- return *this;
- }
- };
- struct TrooperId
- {
- long long playerId;
- int teammateIndex;
- TrooperId() {}
- TrooperId(const Trooper & t)
- {
- teammateIndex = t.getTeammateIndex();
- playerId = t.getPlayerId();
- }
- TrooperId(const TrooperId & o)
- {
- playerId = o.playerId;
- teammateIndex = o.teammateIndex;
- }
- TrooperId & operator = (const TrooperId & o)
- {
- playerId = o.playerId;
- teammateIndex = o.teammateIndex;
- return *this;
- }
- bool operator == (const TrooperId & o) const
- {
- return teammateIndex == o.teammateIndex && playerId == o.playerId;
- }
- bool operator < (const TrooperId &o) const
- {
- if (playerId < o.playerId)
- return true;
- if (playerId > o.playerId)
- return false;
- return teammateIndex < o.teammateIndex;
- }
- };
- struct Enemy
- {
- Position pos;
- int hitPoints;
- TrooperId id;
- TrooperType type;
- int lastSeenMoveIndex;
- int lastSeenMoveOrderIndex;
- bool hasGrenade;
- bool hasMedikit;
- bool hasFieldRation;
- bool isConfirmed() const
- {
- if (lastSeenMoveIndex == moveIndex && lastSeenMoveOrderIndex == trooperMoveOrderIndex)
- return true;
- int enemyMoveIndex = moveOrder.count(type) ? moveOrder[type] : 0;
- if (lastSeenMoveIndex == moveIndex)
- {
- return enemyMoveIndex > trooperMoveOrderIndex;
- }
- if (lastSeenMoveIndex == (moveIndex - 1))
- {
- return enemyMoveIndex < lastSeenMoveOrderIndex && enemyMoveIndex > trooperMoveOrderIndex;
- }
- return false;
- }
- bool isProbable() const
- {
- return (moveIndex - lastSeenMoveIndex) <= 2;
- }
- };
- #define NO_BONUS (-2)
- class FieldMap
- {
- public:
- vector<int> bonuses;
- typedef map<TrooperId, Enemy> Enemies;
- Enemies enemies;
- bool hasEnemies() const
- {
- for (Enemies::const_iterator it = enemies.begin(); it != enemies.end(); ++it)
- {
- const Enemy &enemy = it->second;
- if (enemy.isConfirmed() || enemy.isProbable())
- return true;
- }
- return false;
- }
- void initialize()
- {
- bonuses.resize(W*H);
- for (int i = 0; i < W*H; ++i)
- bonuses[i] = (int) UNKNOWN_BONUS;
- lastPoints = -1;
- }
- int &getBonus(int x, int y)
- {
- return bonuses[y * W + x];
- }
- Enemy *get(const TrooperId &id)
- {
- Enemies::iterator it = enemies.find(id);
- if (it == enemies.end())
- return NULL;
- return &it->second;
- }
- void update()
- {
- const vector<Trooper> &troopers = g_world->getTroopers();
- vector<const Trooper *> myTroopers;
- set<TrooperId> confirmedTroopers;
- for (int i = 0; i < troopers.size(); ++i)
- {
- const Trooper &trooper = troopers[i];
- if (!trooper.isTeammate())
- {
- TrooperId id = TrooperId(trooper);
- Enemy &e = enemies[id];
- e.pos = Position(trooper);
- e.hitPoints = trooper.getHitpoints();
- e.id = id;
- e.type = trooper.getType();
- e.lastSeenMoveIndex = moveIndex;
- e.lastSeenMoveOrderIndex = trooperMoveOrderIndex;
- e.hasGrenade = trooper.isHoldingGrenade();
- e.hasMedikit = trooper.isHoldingMedikit();
- e.hasFieldRation = trooper.isHoldingFieldRation();
- confirmedTroopers.insert(id);
- }
- else
- {
- myTroopers.push_back(&trooper);
- }
- }
- for (int y = 0; y < H; ++y)
- {
- for (int x = 0; x < W; ++x)
- {
- bool isVisible = false;
- for (int i = 0; i < myTroopers.size(); ++i)
- {
- const Trooper *trooper = myTroopers[i];
- isVisible = g_world->isVisible(trooper->getVisionRange(), trooper->getX(), trooper->getY(), trooper->getStance(), x, y, PRONE);
- if (isVisible)
- break;
- }
- if (isVisible)
- {
- getBonus(x, y) = NO_BONUS;
- for (Enemies::iterator it = enemies.begin(); it != enemies.end(); ++it)
- {
- Enemy &enemy = it->second;
- if (!confirmedTroopers.count(enemy.id))
- {
- if ((Point &) enemy.pos == Point(x, y))
- {
- enemies.erase(it);
- break;
- }
- }
- }
- }
- }
- }
- const std::vector<Bonus> &bns = g_world->getBonuses();
- for (int i = 0; i < bns.size(); ++i)
- {
- const Bonus &bonus = bns[i];
- int x = bonus.getX();
- int y = bonus.getY();
- getBonus(bonus.getX(), bonus.getY()) = bonus.getType();
- int x1 = W - x - 1;
- int y1 = H - y- 1;
- if (getBonus(x1, y) == (int) UNKNOWN_BONUS)
- getBonus(x1, y) = bonus.getType();
- if (getBonus(x, y1) == (int) UNKNOWN_BONUS)
- getBonus(x, y1) = bonus.getType();
- if (getBonus(x1, y1) == (int) UNKNOWN_BONUS)
- getBonus(x1, y1) = bonus.getType();
- }
- if (lastPoints >= 0)
- {
- if (lastActionType == SHOOT)
- {
- int points = g_world->getPlayers()[g_self->getPlayerId()].getScore();
- Enemies::iterator it;
- for (it = enemies.begin(); it != enemies.end(); ++it)
- {
- Enemy &enemy = it->second;
- if (!confirmedTroopers.count(enemy.id))
- {
- if ((Point &) enemy.pos == lastActionPoint)
- {
- break;
- }
- }
- }
- if (it != enemies.end())
- {
- if (points == lastPoints)
- {
- enemies.erase(it);
- }
- else
- {
- Enemy &enemy = it->second;
- enemy.lastSeenMoveIndex = moveIndex;
- enemy.lastSeenMoveOrderIndex = trooperMoveOrderIndex;
- }
- }
- }
- }
- }
- void updateAfterMove()
- {
- lastActionType = g_move->getAction();
- lastActionPoint = Point(g_move->getX(), g_move->getY());
- lastPoints = g_world->getPlayers()[g_self->getPlayerId()].getScore();
- if (g_move->getAction() == SHOOT)
- {
- Point shootPos = Point(g_move->getX(), g_move->getY());
- for (Enemies::iterator it = enemies.begin(); it != enemies.end(); ++it)
- {
- Enemy &e = it->second;
- if (Point(e.pos) == shootPos)
- {
- int damage = g_self->getDamage(g_self->getStance());
- makeDamage(e, it, damage);
- return;
- }
- }
- }
- else if (g_move->getAction() == THROW_GRENADE)
- {
- Point throwPos = Point(g_move->getX(), g_move->getY());
- for (Enemies::iterator it = enemies.begin(); it != enemies.end();)
- {
- Enemy &e = it->second;
- if (Point(e.pos) == throwPos)
- {
- int damage = g_game->getGrenadeDirectDamage();
- makeDamage(e, it++, damage);
- }
- else if (Point(e.pos).isClose(throwPos))
- {
- int damage = g_game->getGrenadeCollateralDamage();
- makeDamage(e, it++, damage);
- }
- else
- {
- ++it;
- }
- }
- }
- }
- void makeDamage(Enemy &e, const Enemies::iterator &it, int damage)
- {
- if (damage >= e.hitPoints)
- {
- enemies.erase(it);
- }
- else
- {
- e.hitPoints -= damage;
- }
- }
- Point lastActionPoint;
- ActionType lastActionType;
- int lastPoints;
- } fieldMap;
- struct TrooperDistributionMap
- {
- vector<double> probabilities;
- double sum;
- int lastUpdateMoveIndex;
- int lastUpdateTroopMoveIndex;
- void initialize()
- {
- probabilities.resize(W*H);
- const vector<Trooper> &troopers = g_world->getTroopers();
- for (int i = 0; i < W*H; ++i)
- probabilities[i] = 0.0;
- sum = 0.0;
- for (int i = 0; i < troopers.size(); ++i)
- {
- const Trooper &trooper = troopers[i];
- if (trooper.isTeammate())
- {
- int x = trooper.getX();
- int y = trooper.getY();
- probabilities[(H - y - 1)*W + x] = 1.0;
- probabilities[(H - y - 1)*W + (W - x - 1)] = 1.0;
- probabilities[y*W + (W - x - 1)] = 1.0;
- sum += 3.0;
- }
- }
- lastUpdateMoveIndex = 0;
- lastUpdateTroopMoveIndex = 0;
- }
- void update()
- {
- int rounds = 1;
- if (moveIndex == lastUpdateMoveIndex)
- {
- if (trooperMoveOrderIndex != lastUpdateTroopMoveIndex)
- rounds += (trooperMoveOrderIndex - lastUpdateTroopMoveIndex - 1) * 4;
- }
- else
- {
- rounds += (ENEMY_TROOPERSN / 3 - lastUpdateTroopMoveIndex - 1) * 4;
- }
- LOG("rounds " << rounds);
- lastUpdateMoveIndex = moveIndex;
- lastUpdateTroopMoveIndex = trooperMoveOrderIndex;
- vector<double> newProbabilities(W*H);
- for (int i = 0; i < W*H; ++i)
- newProbabilities[i] = 0.0;
- const vector<Trooper> &troopers = g_world->getTroopers();
- vector<const Trooper *> myTroopers;
- for (int i = 0; i < troopers.size(); ++i)
- {
- const Trooper &trooper = troopers[i];
- if (trooper.isTeammate())
- {
- myTroopers.push_back(&trooper);
- }
- }
- vector<bool> visibilityMap(W*H);
- for (int y = 0; y < H; ++y)
- {
- for (int x = 0; x < W; ++x)
- {
- bool isVisible = false;
- for (int i = 0; i < myTroopers.size(); ++i)
- {
- const Trooper *trooper = myTroopers[i];
- isVisible = g_world->isVisible(trooper->getVisionRange(), trooper->getX(), trooper->getY(), trooper->getStance(), x, y, PRONE);
- if (isVisible)
- break;
- }
- visibilityMap[y*W + x] = isVisible;
- if (isVisible)
- probabilities[y*W + x] = 0.0;
- }
- }
- const vector<vector<CellType> >&cells = g_world->getCells();
- for (int r = 0; r < rounds; ++r)
- {
- for (int y = 0; y < H; ++y)
- {
- for (int x = 0; x < W; ++x)
- {
- if (g_world->getCells()[x][y] != FREE)
- {
- newProbabilities[y*W + x] = 0.0;
- }
- else
- {
- double surN = 0;
- double val = probabilities[y*W + x];
- if (x > 0 && cells[x - 1][y] == FREE)
- surN++;
- if (y > 0 && cells[x][y - 1] == FREE)
- surN++;
- if ((x + 1) < W && cells[x + 1][y] == FREE)
- surN++;
- if ((y + 1) < H && cells[x][y + 1] == FREE)
- surN++;
- double alpha = 0.2;
- val = val/(alpha + (1.0 - alpha)*surN);
- double cv = val * alpha;
- double sv = (1.0 - alpha) * val;
- newProbabilities[y*W + x] += cv;
- if (x > 0 && cells[x - 1][y] == FREE)
- newProbabilities[y*W + (x - 1)] += sv;
- if (y > 0 && cells[x][y - 1] == FREE)
- newProbabilities[(y - 1)*W + x] += sv;
- if ((x + 1) < W && cells[x + 1][y] == FREE)
- newProbabilities[y*W + (x + 1)] += sv;
- if ((y + 1) < H && cells[x][y + 1] == FREE)
- newProbabilities[(y + 1)*W + x] += sv;
- }
- }
- }
- probabilities.swap(newProbabilities);
- }
- for (int i = 0; i < W*H; ++i)
- {
- if (visibilityMap[i])
- probabilities[i] = 0.0;
- }
- sum = 0.0;
- for (int i = 0; i < W*H; ++i)
- sum += probabilities[i];
- double koef = (ENEMY_TROOPERSN - (troopers.size() - myTroopers.size())) / sum;
- for (int i = 0; i < W*H; ++i)
- probabilities[i] *= koef;
- for (int i = 0; i < troopers.size(); ++i)
- {
- const Trooper &trooper = troopers[i];
- if (!trooper.isTeammate())
- {
- int x = trooper.getX();
- int y = trooper.getY();
- probabilities[y*W + x] = 1.0;
- sum++;
- }
- }
- }
- void log()
- {
- #if ENABLE_LOGGING
- for (int y = 0; y < H; ++y)
- {
- cout << "|";
- for (int x = 0; x < W; ++x)
- {
- double v = probabilities[y*W + x];
- int i;
- for (i = 0; i < 10; ++i)
- {
- if (v >= 1.0)
- {
- cout << (9 - i);
- break;
- }
- else
- {
- v *= 2.0;
- }
- }
- if (i == 10)
- {
- cout << 0;
- }
- }
- cout << "|" << std::endl;
- }
- cout << std::endl;
- cout << "SUM " << sum << std::endl;
- #endif
- }
- double get(const Point &p) const
- {
- return probabilities[p.y*W + p.x];
- }
- } trooperDistributionMap;
- const Trooper *getTrooper(const Point &p)
- {
- if (!checkBounds(p))
- return NULL;
- return troopersMap[p.y * W + p.x];
- }
- #define CLOSE_POINTS_N 5
- Point getClosePoints(const Point &p, int k)
- {
- if (k == 0)
- return p;
- if (k == 1)
- return Point(p.x + 1, p.y);
- if (k == 2)
- return Point(p.x - 1, p.y);
- if (k == 3)
- return Point(p.x, p.y + 1);
- if (k == 4)
- return Point(p.x, p.y - 1);
- assert(false);
- }
- bool isPointFree(const Point &p, const TrooperId *id, bool ignoreTeammates = false)
- {
- if (!checkBounds(p))
- return false;
- if (g_world->getCells()[p.x][p.y] != FREE)
- return false;
- const Trooper *trooper = getTrooper(p);
- return !trooper || !id || (TrooperId(*trooper) == *id) || ignoreTeammates && trooper->isTeammate();
- }
- bool isPointFree(const Point &p, const Trooper *self, bool ignoreTeammates = false)
- {
- if (self)
- {
- TrooperId id = TrooperId(*self);
- return isPointFree(p, &id, ignoreTeammates);
- }
- return isPointFree(p, (const TrooperId *) NULL, ignoreTeammates);
- }
- Point getRandomPoint(const Trooper *self)
- {
- int rounds = 0;
- while(1)
- {
- ++rounds;
- int x = (int) sp_random((unsigned int) W);
- int y = (int) sp_random((unsigned int) H);
- Point result = Point(x, y);
- if (isPointFree(result, self))
- return result;
- if (rounds > 1000)
- {
- LOG("getRandomPoint doesn't work");
- return Point(W / 2, H / 2);
- }
- }
- }
- void fit(Point &p)
- {
- if (p.x < 0)
- p.x = 0;
- if (p.y < 0)
- p.y = 0;
- if (p.x >= W)
- p.x = W - 1;
- if (p.y >= H)
- p.y = H - 1;
- }
- double getPointCover(const Point &p, TrooperStance stance)
- {
- int r = 9;
- Point p1 = Point(p.x - r, p.y - r);
- Point p2 = Point(p.x + r, p.y + r);
- fit(p1);
- fit(p2);
- double res = 0.0;
- for (int x = p1.x; x <= p2.x; ++x)
- {
- for (int y = p1.y; y <= p2.y; ++y)
- {
- if (g_world->getCells()[x][y] == FREE)
- {
- int c = 0;
- if (g_world->isVisible(10.0, x, y, STANDING, p.x, p.y, STANDING))
- c++;
- if (g_world->isVisible(10.0, x, y, STANDING, p.x, p.y, stance))
- c--;
- if (c)
- {
- double prob = trooperDistributionMap.probabilities[y * W + x];
- int dist2 = Point(x, y).dist2(p);
- if (dist2 <= 25)
- res += 100.0*prob;
- else if (dist2 <= 36)
- res += 80.0*prob;
- else
- res += 50.0*prob;
- }
- }
- }
- }
- return res;
- }
- int getViewRadius(TrooperType t)
- {
- if (t == COMMANDER)
- return 8;
- if (t == SOLDIER)
- return 7;
- if (t == FIELD_MEDIC)
- return 7;
- if (t == SNIPER)
- return 7;
- if (t == SCOUT)
- return 9;
- return 8;
- }
- double estimateDanger(const Point &p, TrooperType type)
- {
- int r = 9;
- Point p1 = Point(p.x - r, p.y - r);
- Point p2 = Point(p.x + r, p.y + r);
- fit(p1);
- fit(p2);
- double res = 0.0;
- double viewRad = getViewRadius(type);
- for (int x = p1.x; x <= p2.x; ++x)
- {
- for (int y = p1.y; y <= p2.y; ++y)
- {
- if (g_world->getCells()[x][y] == FREE)
- {
- Point d = Point(x, y);
- double prob = trooperDistributionMap.get(d);
- int dist2 = d.dist2(p);
- int c = 0;
- if (g_world->isVisible(10.0, x, y, STANDING, p.x, p.y, STANDING))
- c++;
- if (g_world->isVisible(viewRad, x, y, STANDING, p.x, p.y, STANDING))
- c--;
- if (c)
- {
- res += prob * 50.0;
- }
- if (dist2 <= 25)
- res += prob * 80.0;
- }
- }
- }
- return res;
- }
- bool isHoldingBonus(const Trooper &trooper, BonusType bonusType)
- {
- switch (bonusType)
- {
- case GRENADE:
- return trooper.isHoldingGrenade();
- case MEDIKIT:
- return trooper.isHoldingMedikit();
- case FIELD_RATION:
- return trooper.isHoldingFieldRation();
- }
- return true;
- }
- int getMoveCost(int stance)
- {
- if ((TrooperStance) stance == PRONE)
- return g_game->getProneMoveCost();
- if ((TrooperStance) stance == KNEELING)
- return g_game->getKneelingMoveCost();
- if ((TrooperStance) stance == STANDING)
- return g_game->getStandingMoveCost();
- assert(false);
- return 0;
- }
- int getBonusPoints(bool hasBonus, BonusType bonusType)
- {
- switch (bonusType)
- {
- case GRENADE:
- return hasBonus ? 0 : 5;
- case MEDIKIT:
- return hasBonus ? 0 : 10;
- case FIELD_RATION:
- return hasBonus ? 0 : 5;
- }
- return 0;
- }
- const Trooper *findTeamTrooper(int index)
- {
- const vector<Trooper>& troopers = g_world->getTroopers();
- for (int i = 0; i < troopers.size(); ++i)
- {
- const Trooper &trooper = troopers[i];
- if (trooper.isTeammate())
- {
- if (trooper.getTeammateIndex() == index)
- return &trooper;
- }
- }
- return NULL;
- }
- const Trooper *findTrooper(const TrooperId &id)
- {
- const vector<Trooper>& troopers = g_world->getTroopers();
- for (int i = 0; i < troopers.size(); ++i)
- {
- const Trooper &trooper = troopers[i];
- if (TrooperId(trooper) == id)
- {
- return &trooper;
- }
- }
- return NULL;
- }
- int getDamage(TrooperType t, TrooperStance s)
- {
- if (t == COMMANDER)
- {
- if (s == STANDING)
- return 15;
- if (s == KNEELING)
- return 20;
- if (s == PRONE)
- return 25;
- }
- if (t == SOLDIER)
- {
- if (s == STANDING)
- return 25;
- if (s == KNEELING)
- return 30;
- if (s == PRONE)
- return 35;
- }
- if (t == FIELD_MEDIC)
- {
- if (s == STANDING)
- return 9;
- if (s == KNEELING)
- return 12;
- if (s == PRONE)
- return 15;
- }
- if (t == SNIPER)
- {
- if (s == STANDING)
- return 65;
- if (s == KNEELING)
- return 80;
- if (s == PRONE)
- return 95;
- }
- if (t == SCOUT)
- {
- if (s == STANDING)
- return 20;
- if (s == KNEELING)
- return 25;
- if (s == PRONE)
- return 30;
- }
- return 20;
- }
- int getShootCost(TrooperType t)
- {
- if (t == COMMANDER)
- return 3;
- if (t == SOLDIER)
- return 4;
- if (t == FIELD_MEDIC)
- return 2;
- if (t == SNIPER)
- return 9;
- if (t == SCOUT)
- return 4;
- return 3;
- }
- int getShootRange(TrooperType t)
- {
- if (t == COMMANDER)
- return 7;
- if (t == SOLDIER)
- return 8;
- if (t == FIELD_MEDIC)
- return 5;
- if (t == SNIPER)
- return 10;
- if (t == SCOUT)
- return 6;
- return 8;
- }
- const int getDanger(const Trooper &self, const Point &p)
- {
- int result = 0;
- int dist2 = 100*100;
- for (FieldMap::Enemies::iterator it = fieldMap.enemies.begin(); it != fieldMap.enemies.end(); ++it)
- {
- Enemy &e = it->second;
- Point trooperPoint = e.pos;
- int curDist2 = trooperPoint.dist2(p);
- if (dist2 > curDist2)
- dist2 = curDist2;
- bool canShoot = g_world->isVisible(8,
- trooperPoint.x, trooperPoint.y, STANDING,
- p.x, p.y, self.getStance());
- int trooperDanger = 0;
- if (canShoot)
- {
- trooperDanger = getDamage(e.type, (TrooperStance) e.pos.stance)*(10/getShootCost(e.type));
- }
- for (int k = CLOSE_POINTS_N; k --> 0;)
- {
- Point cp = getClosePoints(p, k);
- if (cp.dist2(trooperPoint) <= g_game->getGrenadeThrowRange()*g_game->getGrenadeThrowRange() && checkBounds(cp))
- {
- int damage = (cp == p) ? g_game->getGrenadeDirectDamage() : g_game->getGrenadeCollateralDamage();
- if (canShoot)
- damage += getShootCost(e.type);
- if (trooperDanger < damage)
- trooperDanger = damage;
- }
- }
- result += trooperDanger;
- }
- if (dist2 >= 81)
- dist2 = 100*100;
- return result*1000 + 1000 - (int) sqrt((double) (dist2 * 100));
- }
- void logMap(const vector<Position> *path)
- {
- if (!ENABLE_LOGGING)
- return;
- const vector<vector<CellType> >& cells = g_world->getCells();
- const vector<Bonus> & bonuses = g_world->getBonuses();
- LOG("--------------------------------");
- for (int y = 0; y < g_world->getHeight(); ++y)
- {
- string rowStr = "|";
- for (int x = 0; x < g_world->getWidth(); ++x)
- {
- CellType cellType = cells[x][y];
- char ch;
- switch (cellType) {
- case UNKNOWN_CELL:
- ch = 'U';
- break;
- case FREE:
- ch = ' ';
- break;
- case LOW_COVER:
- ch = '1';
- break;
- case MEDIUM_COVER:
- ch = '2';
- break;
- case HIGH_COVER:
- ch = '3';
- break;
- default:
- break;
- }
- if (fieldMap.getBonus(x, y) >= 0)
- {
- BonusType type = (BonusType) fieldMap.getBonus(x, y);
- switch (type) {
- case UNKNOWN_BONUS:
- ch = 'u';
- break;
- case GRENADE:
- ch = 'G';
- break;
- case MEDIKIT:
- ch = 'A';
- break;
- case FIELD_RATION:
- ch = 'F';
- break;
- }
- }
- if (path)
- {
- for (int i = 0; i < path->size(); ++i)
- {
- Position p = (*path)[i];
- if (p.x == x && p.y == y)
- {
- ch = 'X';
- break;
- }
- }
- }
- if (troopersMap[y * W + x])
- {
- const Trooper *trooper = troopersMap[y * W + x];
- TrooperType type = trooper->getType();
- if (trooper->isTeammate())
- {
- if (type == COMMANDER)
- {
- ch = 'C';
- }
- else if (type == FIELD_MEDIC)
- {
- ch = 'M';
- }
- else if(type == SOLDIER)
- {
- ch = 'S';
- }
- }
- else
- {
- if (type == COMMANDER)
- {
- ch = 'c';
- }
- else if (type == FIELD_MEDIC)
- {
- ch = 'm';
- }
- else if(type == SOLDIER)
- {
- ch = 's';
- }
- }
- }
- rowStr += ch;
- }
- rowStr += "|";
- LOG(rowStr);
- }
- LOG("--------------------------------");
- }
- const Trooper *findTeamTrooperByType(TrooperType type);
- class MapView
- {
- public:
- virtual bool isPointFree(const Point &p, const TrooperId &id, bool ignoreTeammates = false) = 0;
- };
- class DefaultMapView : public MapView
- {
- virtual bool isPointFree(const Point &p, const TrooperId &id, bool ignoreTeammates = false)
- {
- return ::isPointFree(p, &id, ignoreTeammates);
- }
- } defaultMapView;
- class WalkMap
- {
- public:
- struct PtVal
- {
- int dist;
- //int bonuses; // TODO
- //int cover; // TODO
- Position from;
- PtVal()
- {
- dist = INF_DIST;
- //bonuses = 0;
- //cover = 0;
- }
- void operator = (const PtVal & o)
- {
- dist = o.dist;
- //bonuses = o.bonuses;
- //cover = o.cover;
- from = o.from;
- }
- void log() const
- {
- LOG("Pt " << dist << " " << from.x << " " << from.y << " " << from.stance);
- }
- };
- vector<PtVal> vals;
- bool ignoreTeammates;
- Position from;
- WalkMap(bool ignoreTeammates = false)
- {
- vals.resize(W*H*_TROOPER_STANCE_COUNT_);
- this->ignoreTeammates = ignoreTeammates;
- }
- void log()
- {
- #if ENABLE_LOGGING
- for (int y = 0; y < H; ++y)
- {
- for (int x = 0; x < W; ++x)
- {
- int dist = get(Position(x, y, STANDING)).dist;
- if (dist >= INF_DIST)
- dist = -1;
- cout.width(2);
- cout << dist << " ";
- }
- cout << std::endl;
- }
- cout << std::endl;
- #endif
- }
- PtVal &get(const Position &p)
- {
- int ind = (p.y * W + p.x) * _TROOPER_STANCE_COUNT_ + (int) p.stance;
- return vals[ind];
- }
- const PtVal &get(const Position &p) const
- {
- int ind = (p.y * W + p.x) * _TROOPER_STANCE_COUNT_ + (int) p.stance;
- return vals[ind];
- }
- void build(const Trooper *trooper, int maxCost = -1, MapView *mapView = &defaultMapView)
- {
- return build(Position(*trooper), TrooperId(*trooper), maxCost, mapView);
- }
- void build(const Position &from, const TrooperId &id, int maxCost = -1, MapView *mapView = &defaultMapView)
- {
- this->from = from;
- PtVal &f = get(from);
- f.dist = 0;
- vector<Position> positions;
- positions.reserve(W*H*3 + 1);
- positions.push_back(from);
- int i = 0;
- while (i < positions.size())
- {
- Position p = positions[i++];
- PtVal &oldPtVal = get(p);
- if (maxCost != -1 && oldPtVal.dist > maxCost)
- return;
- for (int k = 0; k < 6; ++k)
- {
- int points;
- Position newp = p;
- if (k == 0)
- {
- newp.x++;
- points = getMoveCost(p.stance);
- }
- else if (k == 1)
- {
- newp.x--;
- points = getMoveCost(p.stance);
- }
- else if (k == 2)
- {
- newp.y++;
- points = getMoveCost(p.stance);
- }
- else if (k == 3)
- {
- newp.y--;
- points = getMoveCost(p.stance);
- }
- else if (k == 4)
- {
- newp.stance++;
- points = g_game->getStanceChangeCost();
- }
- else if (k == 5)
- {
- newp.stance--;
- points = g_game->getStanceChangeCost();
- }
- if (!newp.isValid())
- continue;
- PtVal &newPtVal = get(newp);
- if (newPtVal.dist >= INF_DIST)
- {
- if (mapView->isPointFree(newp, id, ignoreTeammates))
- {
- newPtVal.dist = oldPtVal.dist + points;
- newPtVal.from = p;
- positions.push_back(newp);
- }
- }
- }
- }
- }
- void getPath(const Position &destination, vector<Position> &path, bool standing = true)
- {
- LOG("findPath " << from.x << " " << from.y);
- PtVal t;
- if (standing)
- t = get(Position(destination.x, destination.y, STANDING));
- else
- t = get(destination);
- path.clear();
- if (t.dist < INF_DIST && t.dist > 0)
- {
- Position p = destination;
- path.push_back(p);
- while (!(p == from))
- {
- WalkMap::PtVal &val = get(p);
- p = val.from;
- path.push_back(p);
- }
- reverse(path.begin(), path.end());
- }
- }
- };
- enum FightActionDetailsType
- {
- AD_NONE,
- AD_FIRE,
- AD_THROW_GRENADE,
- AD_HEAL_YOURSELF,
- AD_HEAL_YOURSELF_BY_MEDIKIT,
- AD_HEAL
- };
- const char* fightActionDetailsTypeNames[] = {"AD_NONE", "AD_FIRE", "AD_THROW_GRENADE", "AD_HEAL_YOURSELF", "AD_HEAL_YOURSELF_BY_MEDIKIT", "AD_HEAL"};
- struct FightActionDetails
- {
- FightActionDetails()
- {
- shootsN = 0;
- }
- FightActionDetailsType type;
- bool eat;
- Position from;
- Point to;
- TrooperId enemyId;
- Position evacuationPos;
- int shootsN;
- void log()
- {
- LOG("FightActionDetails: " << fightActionDetailsTypeNames[type]);
- LOG("eat " << eat);
- LOG("from: " << from.x << " " << from.y << " " << from.stance);
- LOG("to: " << to.x << " " << to.y);
- LOG("shootsN: " << shootsN);
- LOG("evacuationPos: " << evacuationPos.x << " " << evacuationPos.y << " " << evacuationPos.stance);
- }
- };
- struct TrooperState
- {
- int hitPoints;
- };
- enum CoordinatedActionType
- {
- AT_NONE,
- AT_FIGHT,
- AT_REGROUP,
- AT_COLLECT_BONUSES,
- AT_GOTO_RANDOM_POINT,
- AT_STOP
- };
- const char *coordinatedActionTypeNames[] = {"AT_NONE", "AT_FIGHT", "AT_REGROUP", "AT_COLLECT_BONUSES", "AT_GOTO_RANDOM_POINT", "AT_STOP"};
- int getChangeCost(const Position &from, const Position &to)
- {
- if (from == to)
- return 0;
- if (from.x == to.x && from.y == to.y)
- return g_game->getStanceChangeCost();
- return getMoveCost(from.stance);
- }
- enum NearPosType
- {
- NP_AHEAD,
- NP_SIDE,
- NP_BACK,
- NP_OTHER
- };
- const char *nearPosTypeName[] = {"NP_AHEAD", "NP_SIDE", "NP_BACK", "NP_OTHER"};
- bool findNearPoint(const Point &src, const Point &aheadDir, Point &out, const vector<Point> &deltas, const set<Point> &reserved, const WalkMap &walkMap)
- {
- bool result = false;
- int dist = INF_DIST;
- Point p;
- Point sideDir = Point(aheadDir.y, - aheadDir.x);
- for (size_t i = 0; i < deltas.size(); ++i)
- {
- p = src;
- const Point &delta = deltas[i];
- p.x += aheadDir.x * delta.x + sideDir.x * delta.y;
- p.y += aheadDir.y * delta.x + sideDir.y * delta.y;
- if (checkPoint(p) && isPointFree(p, (const TrooperId *) NULL) && !reserved.count(p))
- {
- int curDist = walkMap.get(Position(p.x, p.y, STANDING)).dist;
- LOG("findNearPoint " << p.x << " " << p.y << " " << curDist << " " << dist);
- if (dist >= INF_DIST || dist > curDist)
- {
- dist = curDist;
- out = p;
- result = true;
- }
- }
- }
- return result;
- }
- bool getNearPosition(const vector<Position> &path, int index, const NearPosType type, Position &out, const set<Point> &reserved, const WalkMap &walkMap)
- {
- Point dir;
- int dind = index;
- if ((dind + 1) < path.size())
- dind++;
- if (path.size() == 0)
- {
- LOG("ERROR getNearPosition index == 0");
- return false;
- }
- dir = Point(1, 0);
- if (path.size() == 1)
- {
- LOG("getNearPosition index == 1");
- }
- else
- {
- Point nextPoint = path[dind];
- for (int i = dind; i --> 0;)
- {
- Point curPoint = path[i];
- if (!(nextPoint == curPoint))
- {
- dir = Point(nextPoint.x - curPoint.x, nextPoint.y - curPoint.y);
- LOG("getNearPosition " << nearPosTypeName[type] << " " << nextPoint.x << " " << nextPoint.y << "<--" << curPoint.x << " " << curPoint.y);
- break;
- }
- }
- }
- Point side = Point(dir.y, -dir.x);
- if (type == NP_AHEAD)
- {
- if (findNearPoint(path[index], dir, out, aheadDistDeltas1, reserved, walkMap))
- return true;
- if (findNearPoint(path[index], dir, out, aheadDistDeltas2, reserved, walkMap))
- return true;
- return false;
- }
- else if (type == NP_SIDE)
- {
- if (findNearPoint(path[index], dir, out, sideDistDeltas1, reserved, walkMap))
- return true;
- if (findNearPoint(path[index], dir, out, sideDistDeltas2, reserved, walkMap))
- return true;
- return false;
- }
- else if (type == NP_BACK)
- {
- if (findNearPoint(path[index], dir, out, backDistDeltas1, reserved, walkMap))
- return true;
- if (findNearPoint(path[index], dir, out, backDistDeltas2, reserved, walkMap))
- return true;
- return false;
- }
- else
- {
- for (int i = 0; i < nearDistDeltas.size(); ++i)
- {
- out = path[index];
- out.x += nearDistDeltas[i].x;
- out.y += nearDistDeltas[i].y;
- if (isPointFree(out, (const TrooperId *) NULL) && !reserved.count(out))
- return true;
- }
- }
- return false;
- }
- bool hasBonus(BonusType bt, const Trooper *trooper)
- {
- return bt == (int) MEDIKIT && trooper->isHoldingMedikit() ||
- bt == (int) FIELD_RATION && trooper->isHoldingFieldRation() ||
- bt == (int) GRENADE && trooper->isHoldingGrenade();
- }
- struct TrooperStatus : public Enemy
- {
- bool isTeammate;
- int actionPoints;
- void log()
- {
- LOG("TrooperStatus: " << (isTeammate ? "my " : "ememy ") << id.playerId << " " << trooperTypeNames[type + 1]);
- LOG("hitPoints: " << hitPoints);
- LOG("pos: " << pos.x << " " << pos.y << " " << pos.stance);
- LOG("actionPoints: " << actionPoints);
- }
- };
- struct SimulationMapView : public MapView
- {
- map<Point, TrooperId> usedPoints;
- SimulationMapView(const vector <TrooperStatus> &allTroopers)
- {
- for (int i = 0; i < allTroopers.size(); ++i)
- {
- const TrooperStatus &ts = allTroopers[i];
- if (ts.hitPoints > 0)
- {
- usedPoints[ts.pos] = ts.id;
- }
- }
- }
- virtual bool isPointFree(const Point &p, const TrooperId &id, bool ignoreTeammates = false)
- {
- if (!checkBounds(p))
- return false;
- if (g_world->getCells()[p.x][p.y] != FREE)
- return false;
- if (!usedPoints.count(p))
- return true;
- TrooperId &tid = usedPoints[p];
- if (ignoreTeammates && tid.playerId == g_self->getPlayerId())
- return true;
- return tid == id;
- }
- };
- #define MAX_ACTIONS 10
- struct FightCounters
- {
- void clean()
- {
- for (int i = 0; i < MAX_ACTIONS; ++i)
- {
- computeFightTeammate[i] = 0;
- computeFightAfterMove[i] = 0;
- computeFightAfterShoot[i] = 0;
- }
- }
- void log()
- {
- LOG("STATS");
- for (int i = 0; i < count; ++i)
- {
- LOG(i << " computeFightTeammate " << computeFightTeammate[i]);
- LOG(i << " computeFightAfterMove " << computeFightAfterMove[i]);
- LOG(i << " computeFightAfterShoot " << computeFightAfterShoot[i]);
- }
- LOG("END STATS");
- }
- int count;
- int computeFightTeammate[MAX_ACTIONS];
- int computeFightAfterMove[MAX_ACTIONS];
- int computeFightAfterShoot[MAX_ACTIONS];
- };
- class CoordinationCenter
- {
- public:
- Point bonusPoints[TOOPERS_COUNT];
- Position goToPositions[TOOPERS_COUNT];
- map<TrooperType, FightActionDetails> detailsMap;
- const Trooper *troopersByMoveOrder[TOOPERS_COUNT];
- const Trooper *troopers[TOOPERS_COUNT];
- TrooperState oldStates[TOOPERS_COUNT];
- TrooperState newStates[TOOPERS_COUNT];
- map<TrooperType, int> typeIndexMap;
- CoordinatedActionType actionType;
- bool hasLastRandomPoint;
- Point lastRandomPoint;
- TrooperType stopTrooperType;
- bool enemyFound;
- FightCounters counters;
- CoordinationCenter()
- {
- hasLastRandomPoint = false;
- }
- void updateMissions()
- {
- updateTroopers();
- updateCurrentState();
- actionType = AT_NONE;
- enemyFound = false;
- if (hasEnemies())
- {
- LOG("he");
- enemyFound = true;
- computeFight();
- }
- else if (hadDamageFromInvisibleEnemy())
- {
- LOG("hd");
- computeRegroup();
- }
- else if (needBonuses())
- {
- LOG("nb");
- computeCollectBonuses();
- }
- else
- {
- LOG("gr");
- computeGoToRandomPoint();
- }
- log();
- }
- void log()
- {
- #if ENABLE_LOGGING
- LOG("coordinatedActionType " << coordinatedActionTypeNames[actionType]);
- if (actionType == AT_GOTO_RANDOM_POINT || actionType == AT_COLLECT_BONUSES)
- {
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper)
- {
- Position pos = goToPositions[trooper->getTeammateIndex()];
- LOG("GoTo Point " << trooperTypeNames[trooper->getType() + 1] << " " << pos.x << " " << pos.y << " " << pos.stance);
- }
- }
- }
- #endif
- }
- void updateTroopers()
- {
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- troopers[i] = NULL;
- troopersByMoveOrder[i] = NULL;
- }
- typeIndexMap.clear();
- int j = trooperMoveOrderIndex;
- const vector<Trooper>& trs = g_world->getTroopers();
- for (int i = 0; i < trs.size(); ++i)
- {
- const Trooper &trooper = trs[i];
- if (trooper.isTeammate())
- {
- TrooperType type = trooper.getType();
- if (moveOrder.count(type))
- {
- troopersByMoveOrder[moveOrder[type]] = &trooper;
- }
- else
- {
- troopersByMoveOrder[++j] = &trooper;
- }
- troopers[trooper.getTeammateIndex()] = &trooper;
- typeIndexMap[trooper.getType()] = trooper.getTeammateIndex();
- }
- }
- }
- void updateCurrentState()
- {
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper)
- {
- TrooperState &state = newStates[trooper->getTeammateIndex()];
- state.hitPoints = trooper->getHitpoints();
- }
- }
- }
- void updateState()
- {
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- oldStates[i] = newStates[i];
- }
- }
- bool hasEnemies()
- {
- for (FieldMap::Enemies::iterator it = fieldMap.enemies.begin(); it != fieldMap.enemies.end(); ++it)
- {
- Enemy &e = it->second;
- if (e.isConfirmed() || e.isProbable())
- return true;
- }
- return false;
- }
- bool hadDamageFromInvisibleEnemy()
- {
- if (moveIndex == 0 && trooperMoveOrderIndex == 0)
- return false;
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper)
- {
- TrooperState &state = newStates[trooper->getTeammateIndex()];
- TrooperState &oldState = oldStates[trooper->getTeammateIndex()];
- if (state.hitPoints < oldState.hitPoints)
- return true;
- }
- }
- return false;
- }
- bool needBonuses()
- {
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper)
- {
- if (!(trooper->isHoldingFieldRation() && trooper->isHoldingGrenade() && trooper->isHoldingMedikit()))
- return true;
- }
- }
- return false;
- }
- void computeFight()
- {
- //return ;
- actionType = AT_FIGHT;
- vector <TrooperStatus> allTroopers;
- allTroopers.push_back(TrooperStatus());
- TrooperStatus &ts = allTroopers[0];
- ts.hitPoints = g_self->getHitpoints();
- ts.isTeammate = true;
- ts.pos = Position(*g_self);
- ts.type = g_self->getType();
- ts.actionPoints = g_self->getActionPoints();
- ts.id = TrooperId(*g_self);
- ts.hasGrenade = g_self->isHoldingGrenade();
- ts.hasMedikit = g_self->isHoldingMedikit();
- ts.hasFieldRation = g_self->isHoldingFieldRation();
- if (g_self->isHoldingFieldRation())
- ts.actionPoints += 3;
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- int subMoveInd = (trooperMoveOrderIndex + i) % TOOPERS_COUNT;
- for (int type = 0; type < TOOPERS_COUNT; ++type)
- {
- if (moveOrder[(TrooperType) type] == subMoveInd)
- {
- for (FieldMap::Enemies::iterator it = fieldMap.enemies.begin(); it != fieldMap.enemies.end(); ++it)
- {
- Enemy &enemy = it->second;
- if ((enemy.isConfirmed() || enemy.isProbable()) && enemy.type == type)
- {
- allTroopers.push_back(TrooperStatus());
- (Enemy &) allTroopers[allTroopers.size() - 1] = enemy;
- allTroopers[allTroopers.size() - 1].isTeammate = false;
- if (allTroopers[allTroopers.size() - 1].actionPoints < 10)
- allTroopers[allTroopers.size() - 1].actionPoints = 10;
- }
- }
- if (i > 0)
- {
- const Trooper * teamTrooper = findTeamTrooperByType((TrooperType) type);
- if (teamTrooper)
- {
- allTroopers.push_back(TrooperStatus());
- TrooperStatus &ts = allTroopers[allTroopers.size() - 1];
- ts.hitPoints = teamTrooper->getHitpoints();
- ts.isTeammate = true;
- ts.pos = Position(*teamTrooper);
- ts.type = teamTrooper->getType();
- ts.actionPoints = 10;
- ts.id = TrooperId(*teamTrooper);
- ts.hasGrenade = teamTrooper->isHoldingGrenade();
- ts.hasMedikit = teamTrooper->isHoldingMedikit();
- ts.hasFieldRation = teamTrooper->isHoldingFieldRation();
- if (teamTrooper->isHoldingFieldRation())
- ts.actionPoints += 3;
- }
- }
- }
- }
- }
- vector<FightActionDetails> details;
- details.resize(allTroopers.size());
- for (int i = 0; i < details.size(); ++i)
- {
- details[i].type = AD_NONE;
- }
- counters.clean();
- counters.count = allTroopers.size();
- LOG("=========== Compute fight ===========");
- logMap(NULL);
- for (int i = 0; i < allTroopers.size(); ++i)
- allTroopers[i].log();
- int maxResult = -1000000;
- computeFight(allTroopers, 0, details, 0, maxResult);
- LOG("=========== RESULTS Compute fight ===========");
- LOG("maxResult " << maxResult);
- for (int i = 0; i < details.size(); ++i)
- {
- details[i].log();
- }
- LOG("=========== END Compute fight ===========");
- for (int i = 0; i < details.size(); ++i)
- {
- if (allTroopers[i].isTeammate)
- {
- detailsMap[allTroopers[i].type] = details[i];
- }
- details[i].log();
- }
- counters.log();
- return;
- }
- int computeFightNext(vector <TrooperStatus> &allTroopers, int ind, vector<FightActionDetails> &details, int result, int &maxResult)
- {
- ind++;
- if (ind == allTroopers.size())
- {
- if (result > maxResult)
- maxResult = result;
- return result;
- }
- return computeFight(allTroopers, ind, details, result, maxResult);
- }
- int computeFight(vector <TrooperStatus> &allTroopers, int ind, vector<FightActionDetails> &details, int result, int &maxResult)
- {
- LOG_PAD(ind, "call computeFight " << ind << " result:" << result << " maxResult:" << maxResult);
- /*for (int i = 0; i < allTroopers.size(); ++i)
- allTroopers[i].log();*/
- TrooperStatus &ts = allTroopers[ind];
- if (ts.hitPoints > 0)
- {
- if (ts.isTeammate)
- {
- return computeFightTeammate(allTroopers, ind, details, result, maxResult);
- }
- else
- {
- return computeFightEnemy(allTroopers, ind, details, result, maxResult);
- }
- }
- return computeFightNext(allTroopers, ind, details, result, maxResult);
- }
- int computeFightTeammate(vector <TrooperStatus> &allTroopers, int ind, vector<FightActionDetails> &details, int result, int &maxResult)
- {
- LOG_PAD(ind, "computeFightTeammate " << ind);
- TrooperStatus &ts = allTroopers[ind];
- SimulationMapView mapView = SimulationMapView(allTroopers);
- WalkMap walkMap;
- int ap = ts.actionPoints;
- if ((ind == 1 || ind == 2) && ap > 2)
- ap = 2;
- else if (ind >= 3)
- ap = 0;
- walkMap.build(ts.pos, ts.id, ap, &mapView);
- int r = (ind == 0) ? 2 : 1;
- Point p1 = Point(ts.pos.x - r, ts.pos.y - r);
- Point p2 = Point(ts.pos.x + r, ts.pos.y + r);
- fit(p1);
- fit(p2);
- int maxCalculatedResult = -1000000;
- for (int x = p1.x; x <= p2.x; ++x)
- {
- for (int y = p1.y; y <= p2.y; ++y)
- {
- for (int s = 0; s < 3; ++s)
- {
- if (abs(s - ts.pos.stance) > 1)
- continue;
- WalkMap::PtVal &ptVal = walkMap.get(Position(x, y, s));
- LOG_PAD(ind, "PtVal " << x << " " << y << " " << s << " " << ptVal.dist);
- if (ptVal.dist < INF_DIST)
- {
- if (ptVal.dist <= ap)
- {
- counters.computeFightTeammate[ind]++;
- int oldActionPoints = ts.actionPoints ;
- ts.actionPoints -= ptVal.dist;
- Position oldPos = ts.pos;
- ts.pos = Position(x, y, s);
- LOG_PAD(ind, "move i" << ind << " x" << x << " y" << y << " s" << s << " ap" << ts.actionPoints);
- int calculatedResult = computeFightAfterMove(allTroopers, ind, details, result, maxResult);
- LOG_PAD(ind, "computeFightTeammate " << ind << " " << calculatedResult);
- if (calculatedResult > maxCalculatedResult)
- {
- maxCalculatedResult = calculatedResult;
- }
- if (calculatedResult >= maxResult)
- {
- FightActionDetails &thisDetails = details[ind];
- thisDetails.from = Position(x, y, s);
- if (ind == 0)
- {
- LOG("+++1 " << calculatedResult);
- for (int i = 0; i < details.size(); ++i)
- details[i].log();
- }
- }
- ts.pos = oldPos;
- ts.actionPoints = oldActionPoints;
- }
- }
- }
- }
- }
- return maxCalculatedResult;
- }
- int computeFightEnemy(vector <TrooperStatus> &allTroopers, int ind, vector<FightActionDetails> &details, int result, int &maxResult)
- {
- LOG_PAD(ind, "computeFightEnemy " << ind);
- TrooperStatus &ts = allTroopers[ind];
- int shootRange = getShootRange(ts.type);
- int shootDamage = getDamage(ts.type, KNEELING);
- int indToShoot = -1;
- int health = 1000;
- int grenageRange = g_game->getGrenadeThrowRange();
- bool hasGrenade = ts.hasGrenade;
- int shootCost = getShootCost(ts.type);
- int viewRad = getViewRadius(ts.type);
- int maxShoots = ts.actionPoints / shootCost;
- int inGrenadeRangeN = 0;
- for (int i = 0; i < allTroopers.size(); ++i)
- {
- TrooperStatus &tr = allTroopers[i];
- if (tr.isTeammate && tr.hitPoints > 0)
- {
- bool isVisible = g_world->isVisible(shootRange, ts.pos.x, ts.pos.y, STANDING, tr.pos.x, tr.pos.y, (TrooperStance) tr.pos.stance);
- if (isVisible)
- {
- if (health > tr.hitPoints)
- {
- health = tr.hitPoints;
- indToShoot = i;
- }
- tr.hitPoints -= 5;
- result -= 5;
- }
- bool isViewable = g_world->isVisible(viewRad, ts.pos.x, ts.pos.y, STANDING, tr.pos.x, tr.pos.y, (TrooperStance) tr.pos.stance);
- if (isViewable)
- {
- health = tr.hitPoints;
- tr.hitPoints -= 2;
- result -= 2;
- }
- if (hasGrenade)
- {
- int dist2 = ts.pos.dist2(tr.pos);
- if (dist2 <= (grenageRange + 1) * (grenageRange + 1))
- {
- inGrenadeRangeN++;
- }
- }
- }
- }
- if (hasGrenade && inGrenadeRangeN)
- {
- int damage = 60/inGrenadeRangeN;
- for (int i = 0; i < allTroopers.size(); ++i)
- {
- TrooperStatus &tr = allTroopers[i];
- if (tr.isTeammate && tr.hitPoints > 0)
- {
- int dist2 = ts.pos.dist2(tr.pos);
- if (dist2 <= (grenageRange) * (grenageRange))
- {
- int dmg = damage * 1.4;
- tr.hitPoints -= dmg;
- result -= dmg;
- }
- else if (dist2 <= (grenageRange + 1) * (grenageRange + 1))
- {
- int dmg = damage;
- tr.hitPoints -= dmg;
- result -= dmg;
- }
- }
- }
- }
- int oldHitpoints;
- if (indToShoot != -1)
- {
- LOG_PAD(ind, "Enemy shoot " << trooperTypeNames[allTroopers[indToShoot].type + 1]);
- oldHitpoints = allTroopers[indToShoot].hitPoints;
- allTroopers[indToShoot].hitPoints -= shootDamage*maxShoots;
- result -= shootDamage*maxShoots;
- if (allTroopers[indToShoot].hitPoints <= 0)
- {
- result -= allTroopers[indToShoot].hitPoints;
- result -= 50;
- }
- }
- else
- {
- LOG_PAD(ind, "Enemy can't shoot");
- }
- int calculatedResult = computeFightNext(allTroopers, ind, details, result, maxResult);
- LOG_PAD(ind, "calculatedResult computeFightEnemy " << ind << " = " << calculatedResult);
- if (calculatedResult >= maxResult)
- {
- FightActionDetails &thisDetails = details[ind];
- thisDetails.from = ts.pos;
- thisDetails.evacuationPos = ts.pos;
- if (indToShoot != -1)
- {
- thisDetails.to = allTroopers[indToShoot].pos;
- thisDetails.type = AD_FIRE;
- thisDetails.shootsN = maxShoots;
- }
- else
- {
- thisDetails.to = Point(-1, -1);
- thisDetails.type = AD_NONE;
- }
- }
- if (indToShoot != -1)
- {
- allTroopers[indToShoot].hitPoints = oldHitpoints;
- }
- return calculatedResult;
- }
- int computeFightAfterMove(vector <TrooperStatus> &allTroopers, int ind, vector<FightActionDetails> &details, int result, int &maxResult)
- {
- LOG_PAD(ind, "computeFightAfterMove " << ind);
- TrooperStatus &ts = allTroopers[ind];
- int shootCost = getShootCost(ts.type);
- int maxShoots = ts.actionPoints / shootCost;
- int damage = getDamage(ts.type, (TrooperStance) ts.pos.stance);
- double shootRange = getShootRange(ts.type);
- vector<TrooperStatus *> visibleEnemies;
- for (int i = 0; i < allTroopers.size(); ++i)
- {
- TrooperStatus &target = allTroopers[i];
- if (!target.isTeammate && target.hitPoints > 0)
- {
- bool isVisible = g_world->isVisible(shootRange, ts.pos.x, ts.pos.y, (TrooperStance) ts.pos.stance, target.pos.x, target.pos.y, (TrooperStance) target.pos.stance);
- if (isVisible)
- visibleEnemies.push_back(&target);
- }
- }
- int maxCalculatedResult = -1000000;
- LOG_PAD(ind, "enemies " << visibleEnemies.size());
- for (int i = 0; i < visibleEnemies.size(); ++i)
- {
- TrooperStatus &target = *visibleEnemies[i];
- int shootsToKill = (target.hitPoints + damage - 1) / damage;
- if (shootsToKill < maxShoots)
- maxShoots = shootsToKill;
- int shoots = maxShoots - 1;
- if (shoots < 0)
- shoots = 0;
- for (; shoots <= maxShoots; ++shoots)
- {
- counters.computeFightAfterMove[ind]++;
- LOG_PAD(ind, "shootsN " << shoots << "/" << maxShoots);
- int oldActionPoints = ts.actionPoints;
- ts.actionPoints -= shoots*shootCost;
- int oldTargetHitPoints = target.hitPoints;
- target.hitPoints -= shoots * damage;
- int newResult = result + shoots * damage;
- if (target.hitPoints < 0)
- {
- newResult += target.hitPoints;
- newResult += 25;
- }
- int calculatedResult = computeFightAfterShoot(allTroopers, ind, details, newResult, maxResult);
- LOG_PAD(ind, "computeFightAfterMove " << ind << " " << calculatedResult);
- if (calculatedResult >= maxResult)
- {
- FightActionDetails &thisDetails = details[ind];
- thisDetails.type = AD_FIRE;
- thisDetails.to = target.pos;
- thisDetails.enemyId = target.id;
- thisDetails.shootsN = shoots;
- if (ind == 0)
- {
- LOG("+++2 " << calculatedResult);
- thisDetails.log();
- }
- }
- if (maxCalculatedResult < calculatedResult)
- maxCalculatedResult = calculatedResult;
- target.hitPoints = oldTargetHitPoints;
- ts.actionPoints = oldActionPoints;
- }
- }
- if (visibleEnemies.empty())
- {
- LOG_PAD(ind, "Can't shoot " << ind);
- int calculatedResult = computeFightAfterShoot(allTroopers, ind, details, result, maxResult);
- LOG_PAD(ind, "computeFightAfterMove " << ind << " " << calculatedResult);
- if (maxCalculatedResult < calculatedResult)
- maxCalculatedResult = calculatedResult;
- if (calculatedResult >= maxResult)
- {
- FightActionDetails &thisDetails = details[ind];
- thisDetails.type = AD_NONE;
- if (ind == 0)
- {
- LOG("+++3 " << calculatedResult);
- thisDetails.log();
- }
- }
- return maxCalculatedResult;
- }
- return maxCalculatedResult;
- }
- int computeFightAfterShoot(vector <TrooperStatus> &allTroopers, int ind, vector<FightActionDetails> &details, int result, int &maxResult)
- {
- LOG_PAD(ind, "computeFightAfterShoot " << ind);
- TrooperStatus &ts = allTroopers[ind];
- SimulationMapView mapView = SimulationMapView(allTroopers);
- WalkMap walkMap;
- int ap = ts.actionPoints;
- if ((ind == 1 || ind == 2) && ap > 2)
- ap = 2;
- else if (ind >= 3)
- ap = 0;
- walkMap.build(ts.pos, ts.id, ap, &mapView);
- int r = 1;
- Point p1 = Point(ts.pos.x - r, ts.pos.y - r);
- Point p2 = Point(ts.pos.x + r, ts.pos.y + r);
- fit(p1);
- fit(p2);
- Position oldPos = ts.pos;
- int maxCalculatedResult = -1000000;
- int oldActionPoints = ts.actionPoints;
- for (int x = p1.x; x <= p2.x; ++x)
- {
- for (int y = p1.y; y <= p2.y; ++y)
- {
- for (int s = 0; s < 3; ++s)
- {
- if (abs(s - ts.pos.stance) > 1)
- continue;
- WalkMap::PtVal &ptVal = walkMap.get(Position(x, y, s));
- if (ptVal.dist < INF_DIST && ptVal.dist <= ap)
- {
- counters.computeFightAfterShoot[ind]++;
- LOG_PAD(ind, "Move after shoot " << x << " " << y << " " << s);
- ts.actionPoints = oldActionPoints - ptVal.dist;
- ts.pos = Position(x, y, s);
- int calculatedResult = computeFightNext(allTroopers, ind, details, result, maxResult);
- LOG_PAD(ind, "calculatedResult computeFightAfterShoot " << ind << " = " << calculatedResult);
- if (maxCalculatedResult < calculatedResult)
- maxCalculatedResult = calculatedResult;
- if (calculatedResult >= maxResult)
- {
- LOG_PAD(ind, "New result " << ind << " " << calculatedResult);
- FightActionDetails &thisDetails = details[ind];
- thisDetails.evacuationPos = Position(x, y, s);
- }
- }
- }
- }
- }
- ts.pos = oldPos;
- ts.actionPoints = oldActionPoints;
- return maxCalculatedResult;
- }
- void computeRegroup()
- {
- //actionType = AT_REGROUP;
- //computeGoToRandomPoint();
- }
- void computeCollectBonuses()
- {
- actionType = AT_COLLECT_BONUSES;
- int needMedikitCount = 0;
- int needFieldRationCount = 0;
- int needGrenageCount = 0;
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper)
- {
- if (!trooper->isHoldingMedikit())
- needMedikitCount++;
- if (!trooper->isHoldingFieldRation())
- needFieldRationCount++;
- if (!trooper->isHoldingGrenade())
- needGrenageCount++;
- }
- }
- BonusType bonusTypeOrdered[] = {MEDIKIT, FIELD_RATION, GRENADE};
- int tempOrder[] = {needMedikitCount, needFieldRationCount, needGrenageCount};
- if (tempOrder[0] < tempOrder[1])
- {
- swap(tempOrder[0], tempOrder[1]);
- swap(bonusTypeOrdered[0], bonusTypeOrdered[1]);
- }
- if (tempOrder[1] < tempOrder[2])
- {
- swap(tempOrder[1], tempOrder[2]);
- swap(bonusTypeOrdered[1], bonusTypeOrdered[2]);
- }
- if (tempOrder[0] < tempOrder[1])
- {
- swap(tempOrder[0], tempOrder[1]);
- swap(bonusTypeOrdered[0], bonusTypeOrdered[1]);
- }
- TrooperType mainTrooperType = getMainTrooperType();
- const Trooper *mainTrooper = troopers[typeIndexMap[mainTrooperType]];
- WalkMap walkMap(true);
- walkMap.build(mainTrooper);
- Point closestBonuses[3];
- int bonusDist[3] = {INF_DIST, INF_DIST, INF_DIST};
- for (int y = 0; y < H; ++y)
- {
- for (int x = 0; x < W; ++x)
- {
- int bonusType = fieldMap.getBonus(x, y);
- if (bonusType >= 0)
- {
- int dist = walkMap.get(Position(x, y, STANDING)).dist;
- if (bonusDist[bonusType] == INF_DIST || bonusDist[bonusType] > dist)
- {
- closestBonuses[bonusType] = Point(x, y);
- bonusDist[bonusType] = dist;
- }
- }
- }
- }
- Point goToPoint;
- BonusType bt;
- LOG("bonusTypeOrdered " << bonusTypeOrdered[0] << " " << bonusTypeOrdered[1] << " " << bonusTypeOrdered[2]);
- LOG("bonusDist " << bonusDist[MEDIKIT] << " " << bonusDist[GRENADE] << " " << bonusDist[FIELD_RATION]);
- if (bonusDist[bonusTypeOrdered[0]] != INF_DIST && tempOrder[0] > 0)
- {
- goToPoint = closestBonuses[bonusTypeOrdered[0]];
- bt = bonusTypeOrdered[0];
- }
- else if (bonusDist[bonusTypeOrdered[1]] != INF_DIST && tempOrder[1] > 0)
- {
- goToPoint = closestBonuses[bonusTypeOrdered[1]];
- bt = bonusTypeOrdered[1];
- }
- else if (bonusDist[bonusTypeOrdered[2]] != INF_DIST && tempOrder[2] > 0)
- {
- goToPoint = closestBonuses[bonusTypeOrdered[2]];
- bt = bonusTypeOrdered[2];
- }
- else
- {
- computeGoToRandomPoint();
- return;
- }
- LOG("computeCollectBonuses point " << goToPoint.x << " " << goToPoint.y);
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper)
- {
- LOG("TR " << trooperTypeNames[trooper->getType() + 1] << " M" << trooper->isHoldingMedikit() << " F" << trooper->isHoldingFieldRation() << " G" << trooper->isHoldingGrenade());
- }
- }
- if (hasBonus(bt, mainTrooper) && goToPoint.sqDist(Point(*mainTrooper)) < 3 && !(goToPoint == Point(*mainTrooper)))
- {
- bool stop = true;
- Point mp = Point(*mainTrooper);
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper && trooper->getType() != mainTrooper->getType())
- {
- LOG("III " << i << mp.sqDist(Point(*trooper)) );
- if (mp.sqDist(Point(*trooper)) > 2)
- {
- stop = false;
- break;
- }
- }
- }
- if (stop)
- {
- actionType = AT_STOP;
- stopTrooperType = mainTrooper->getType();
- return;
- }
- }
- computeGoToPoint(goToPoint, mainTrooper, 1);
- set<Point> reservedPoints;
- set<int> reservedBy;
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper)
- {
- Position &target = goToPositions[trooper->getTeammateIndex()];
- LOG("TR " << trooperTypeNames[trooper->getType() + 1] << " M" << trooper->isHoldingMedikit() << " F" << trooper->isHoldingFieldRation() << " G" << trooper->isHoldingGrenade());
- for (int i = 0; i < nearDistDeltas.size(); ++i)
- {
- Point p = target;
- p.x += nearDistDeltas[i].x;
- p.y += nearDistDeltas[i].y;
- //LOG("check p " << p.x << " " << p.y);
- if (checkPoint(p) && !reservedPoints.count(p))
- {
- //LOG("check p2 " << p.x << " " << p.y);
- int bonusType = fieldMap.getBonus(p.x, p.y);
- if (bonusType >= 0)
- {
- if (bonusInUse[p] != trooper->getTeammateIndex())
- continue;
- if (bonusType == (int) MEDIKIT && !trooper->isHoldingMedikit() ||
- bonusType == (int) FIELD_RATION && !trooper->isHoldingFieldRation() ||
- bonusType == (int) GRENADE && !trooper->isHoldingGrenade())
- {
- LOG("Bonus Target " << trooperTypeNames[trooper->getType() + 1] << " " << p.x << " " << p.y);
- target.x = p.x;
- target.y = p.y;
- reservedPoints.insert(p);
- reservedBy.insert(trooper->getTeammateIndex());
- bonusInUse[p] = trooper->getTeammateIndex();
- break;
- }
- }
- }
- }
- }
- }
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper && !reservedBy.count(trooper->getTeammateIndex()))
- {
- Position &target = goToPositions[trooper->getTeammateIndex()];
- if (reservedPoints.count(target))
- {
- for (int i = 0; i < nearDistDeltas.size(); ++i)
- {
- Point p = target;
- p.x += nearDistDeltas[i].x;
- p.y += nearDistDeltas[i].x;
- if (checkPoint(p) && !reservedPoints.count(p))
- {
- target.x = p.x;
- target.y = p.y;
- reservedPoints.insert(p);
- reservedBy.insert(trooper->getTeammateIndex());
- break;
- }
- }
- }
- else
- {
- reservedPoints.insert(target);
- }
- }
- }
- }
- TrooperType getMainTrooperType()
- {
- TrooperType mainType;
- if (typeIndexMap.count(COMMANDER))
- mainType = COMMANDER;
- else if (typeIndexMap.count(SCOUT))
- mainType = SCOUT;
- else if (typeIndexMap.count(SOLDIER))
- mainType = SOLDIER;
- else if (typeIndexMap.count(SNIPER))
- mainType = SNIPER;
- else if (typeIndexMap.count(FIELD_MEDIC))
- mainType = FIELD_MEDIC;
- return mainType;
- }
- void computeGoToRandomPoint()
- {
- actionType = AT_GOTO_RANDOM_POINT;
- TrooperType mainType = getMainTrooperType();
- const Trooper *mainTrooper = troopers[typeIndexMap[mainType]];
- if (hasLastRandomPoint)
- {
- if (Point(*mainTrooper).dist2(lastRandomPoint) < 9)
- hasLastRandomPoint = false;
- }
- if (!hasLastRandomPoint)
- {
- lastRandomPoint = getRandomPoint(mainTrooper);
- hasLastRandomPoint = true;
- }
- LOG("GOTO RANDOM POINT " << lastRandomPoint.x << " " << lastRandomPoint.y);
- computeGoToPoint(lastRandomPoint, mainTrooper, 1);
- }
- void computeGoToPoint(const Point &point, const Trooper *mainTrooper, int reservedMoves)
- {
- WalkMap walkMap(false);
- walkMap.build(mainTrooper);
- vector<Position> path;
- walkMap.getPath(Position(point.x, point.y, STANDING), path);
- {
- WalkMap walkMap2(true);
- walkMap2.build(mainTrooper);
- vector<Position> path2;
- walkMap2.getPath(Position(point.x, point.y, STANDING), path2);
- if (path.size() <= 1 || path.size() > (path2.size() + 4))
- {
- path.swap(path2);
- }
- }
- if (path.size() <= 1)
- {
- LOG("computeGoToPoint ERROR " << mainTrooper->getX() << " " << mainTrooper->getY() << "->" << point.x << " " << point.y);
- actionType = AT_NONE;
- hasLastRandomPoint = false;
- return;
- }
- logMap(&path);
- int points = mainTrooper->getActionPoints() - reservedMoves*g_game->getStandingMoveCost();
- Position &lastPoint = path[0];
- int pi;
- for (pi = 1; pi < path.size(); ++pi)
- {
- int cost = getChangeCost(lastPoint, path[pi]);
- if (points >= cost)
- {
- if (points >= g_game->getStanceChangeCost() && points < (g_game->getStanceChangeCost() + cost))
- {
- int cover = getPointCover(path[pi], KNEELING);
- LOG("cover " << path[pi].x << " " << path[pi].y << "=" << cover);
- if (cover > COVER_KNEELING)
- {
- LOG("KNEELING");
- lastPoint = path[pi];
- lastPoint.stance = KNEELING;
- points -= g_game->getStanceChangeCost();
- break;
- }
- }
- lastPoint = path[pi];
- points -= cost;
- }
- else
- {
- break;
- }
- }
- pi--;
- goToPositions[mainTrooper->getTeammateIndex()] = lastPoint;
- set <Point> reservedPoints;
- reservedPoints.insert(lastPoint);
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- const Trooper *trooper = troopersByMoveOrder[i];
- if (trooper && trooper->getType() != mainTrooper->getType())
- {
- WalkMap trooperWalkMap(true);
- trooperWalkMap.build(trooper, trooper->getActionPoints() + 5);
- Position &p = goToPositions[trooper->getTeammateIndex()];
- if (trooper->getType() == SCOUT)
- {
- if (getNearPosition(path, pi, NP_AHEAD, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- if (getNearPosition(path, pi, NP_SIDE, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- if (getNearPosition(path, pi, NP_OTHER, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- LOG("ERROR, cant find position for SCOUT");
- }
- else if (trooper->getType() == SOLDIER)
- {
- if (getNearPosition(path, pi, NP_SIDE, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- if (getNearPosition(path, pi, NP_AHEAD, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- if (getNearPosition(path, pi, NP_OTHER, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- LOG("ERROR, cant find position for SOLDIER");
- }
- else if (trooper->getType() == SNIPER)
- {
- if (getNearPosition(path, pi, NP_BACK, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- if (getNearPosition(path, pi, NP_OTHER, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- LOG("ERROR, cant find position for SNIPER");
- }
- else if (trooper->getType() == FIELD_MEDIC)
- {
- if (getNearPosition(path, pi, NP_BACK, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- if (getNearPosition(path, pi, NP_OTHER, p, reservedPoints, trooperWalkMap))
- {
- reservedPoints.insert(p);
- continue;
- }
- LOG("ERROR, cant find position for FIELD_MEDIC");
- }
- }
- }
- }
- } coordinationCenter;
- MyStrategy::MyStrategy() { }
- class Mission
- {
- public:
- virtual bool perform() = 0;
- virtual bool isPossible()
- {
- return true;
- }
- virtual ~Mission() {}
- };
- bool eatFieldRation()
- {
- if (g_self->getActionPoints() <= (g_self->getInitialActionPoints() - g_game->getFieldRationBonusActionPoints())
- && g_self->getActionPoints() >= g_game->getFieldRationEatCost()
- && g_self->isHoldingFieldRation())
- {
- g_move->setAction(EAT_FIELD_RATION);
- return true;
- }
- return false;
- }
- class GoToPointMission : public Mission
- {
- public:
- GoToPointMission(const Trooper & trooper, const Point & destination, TrooperStance stance = STANDING)
- {
- this->from = Position(trooper);
- this->destination = Position(destination.x, destination.y, stance);
- this->trooperIndex = trooper.getTeammateIndex();
- this->ignoreDanger = true;
- this->mayIgnoreTeammates = true;
- findPath(trooper, false);
- }
- virtual bool perform()
- {
- const Trooper *trooper = findTeamTrooper(trooperIndex);
- if (!trooper)
- {
- LOG("No Trooper " << trooperIndex);
- return false;
- }
- logMap(&path);
- Point d = Point(*trooper);
- if (path.size() > 1)
- d = path[1];
- if (!canWalk(trooper, d))
- return false;
- //optimizePath(trooper);
- if (!canWalk(trooper, d, 1) && trooper->getActionPoints() >= g_game->getStanceChangeCost() && trooper->getStance() == STANDING)
- {
- int cover = getPointCover(Point(*trooper), KNEELING);
- if (cover >= COVER_KNEELING)
- {
- g_move->setAction(LOWER_STANCE);
- return true;
- }
- }
- /*if (!canWalk(trooper, 2) && trooper->getActionPoints() >= g_game->getStanceChangeCost() && trooper->getStance() == STANDING
- || !canWalk(trooper, 1) && trooper->getActionPoints() >= g_game->getStanceChangeCost() && trooper->getStance() == KNEELING)
- {
- int coverKneeling = getPointCover(Point(*trooper), KNEELING);
- int coverProne = getPointCover(Point(*trooper), PRONE);
- LOG("Cover " << coverProne << " " << coverKneeling);
- if ((coverProne - coverKneeling) >= COVER_PRONE)
- {
- g_move->setAction(LOWER_STANCE);
- return true;
- }
- }*/
- if (path.size() > 1)
- {
- Position p = path[1];
- Position curPoint = Position(*trooper);
- if (p.isClose(curPoint) && isPointFree(p, trooper))
- {
- if (p.stance > curPoint.stance)
- {
- if (trooper->getActionPoints() < g_game->getStanceChangeCost())
- return false;
- g_move->setAction(RAISE_STANCE);
- }
- else if (p.stance < curPoint.stance)
- {
- if (trooper->getActionPoints() < g_game->getStanceChangeCost())
- return false;
- g_move->setAction(LOWER_STANCE);
- }
- else
- {
- if (trooper->getActionPoints() < getMoveCost(trooper->getStance()))
- return false;
- g_move->setAction(MOVE);
- g_move->setX(p.x);
- g_move->setY(p.y);
- }
- return true;
- }
- else
- {
- LOG("No GoToPointMission move " << curPoint.x << " " << curPoint.y << " -> " << p.x << " " << p.y);
- stuck[trooper->getType()] = moveIndex;
- for (int i = 1; i < path.size(); ++i)
- {
- const Trooper * obstacleTrooper = getTrooper(path[i]);
- if (obstacleTrooper && obstacleTrooper->isTeammate() && obstacleTrooper->getTeammateIndex() != trooperIndex)
- {
- LOG("notifyObstacle " << trooperTypeNames[obstacleTrooper->getType() + 1]);
- notifyObstacle(obstacleTrooper);
- }
- }
- }
- }
- LOG("No GoToPointMission move " << path.size());
- return true;
- }
- void notifyObstacle(const Trooper * obstacleTrooper);
- /* void optimizePath(const Trooper *trooper)
- {
- WalkMap walkMap;
- walkMap.build(trooper, trooper->getActionPoints() - reservedMoves*2);
- Position lastPos = Position(*trooper);
- int i = 1;
- for (i = 1; i < path.size(); ++i)
- {
- Position &p = path[i];
- int coverKneeling = getPointCover(Point(*trooper), KNEELING);
- int coverProne = getPointCover(Point(*trooper), PRONE);
- TrooperStance stance = (TrooperStance) p.stance;
- if (coverKneeling >= COVER_KNEELING)
- stance = KNEELING;
- if ((coverProne - coverKneeling) >= COVER_PRONE)
- stance = PRONE;
- int dist = walkMap.get(Position(p.x, p.y, stance)).dist ;
- LOG("i " << i << " " << dist);
- if (dist >= INF_DIST)
- break;
- lastPos = Position(p.x, p.y, stance);
- LOG(p.x << " " << p.y);
- }
- walkMap.getPath(lastPos, path);
- }*/
- virtual bool canWalk(const Trooper *trooper, const Point &to, int nm = 0)
- {
- int reservedMoves = 0;
- if (!this->ignoreDanger)
- {
- double danger = estimateDanger(to, trooper->getType());
- LOG("Estimated danger " << danger);
- if (danger > 20.0)
- reservedMoves = 1;
- }
- LOG("ActionPoints " << trooper->getActionPoints());
- if (trooper->getActionPoints() < (1 + reservedMoves + nm) * g_game->getStandingMoveCost())
- {
- if (nm == 0)
- LOG("GoToPointMission, no actionPoints " << trooperIndex << " reservedMoves: " << reservedMoves);
- return false;
- }
- return true;
- }
- const vector<Position> &getPath() const
- {
- return path;
- }
- int getLength() const
- {
- return path.size();
- }
- virtual bool isPossible()
- {
- if (path.empty())
- return false;
- const Trooper *trooper = findTeamTrooper(trooperIndex);
- if (!trooper)
- {
- LOG("No Trooper " << trooperIndex);
- return false;
- }
- if (path.size() > 1 && !isPointFree(path[1], trooper) && stuck.count(trooper->getType()) && (stuck[trooper->getType()] + 1) == moveIndex)
- {
- return false;
- }
- return true;
- }
- private:
- void findPath(const Trooper &trooper, bool standing = true)
- {
- WalkMap walkMap;
- walkMap.build(&trooper);
- LOG("findPath " << from.x << " " << from.y);
- walkMap.getPath(destination, path, standing);
- if (mayIgnoreTeammates)
- {
- WalkMap walkMap2(true);
- walkMap2.build(&trooper);
- vector<Position> path2;
- walkMap2.getPath(destination, path2, standing);
- if (path.size() <= 1 || path.size() > (path2.size() + 4))
- {
- if (path2.size() > 1 && !isPointFree(path2[1], &trooper) && stuck.count(trooper.getType()) && (stuck[trooper.getType()] + 1) == moveIndex)
- {
- LOG("Stuck!");
- for (int i = 1; i < path2.size() && i < 5; ++i)
- {
- const Trooper * obstacleTrooper = getTrooper(path2[i]);
- if (obstacleTrooper && obstacleTrooper->isTeammate() && obstacleTrooper->getTeammateIndex() != trooper.getTeammateIndex())
- {
- LOG("findPath notifyObstacle " << trooperTypeNames[obstacleTrooper->getType() + 1]);
- notifyObstacle(obstacleTrooper);
- }
- }
- }
- LOG("Shoose path ignoring teammates");
- path.swap(path2);
- }
- }
- }
- void logPath()
- {
- if (!ENABLE_LOGGING)
- return;
- LOG("PATH");
- for (int i = 0; i < path.size(); ++i)
- {
- LOG(i << " - (" << path[i].x << ", " << path[i].y << ")");
- }
- }
- protected:
- vector<Position> path;
- Position from, destination;
- int trooperIndex;
- bool ignoreDanger;
- bool mayIgnoreTeammates;
- };
- class ClearWayMission : public GoToPointMission
- {
- public:
- ClearWayMission(const Trooper & trooper, const Point & destination) : GoToPointMission(trooper, destination)
- {
- this->ignoreDanger = false;
- this->mayIgnoreTeammates = false;
- }
- };
- class GoToBonusMission : public GoToPointMission
- {
- public:
- GoToBonusMission(const Trooper & trooper, const Point & destination) : GoToPointMission(trooper, destination)
- {
- this->ignoreDanger = false;
- }
- ~GoToBonusMission()
- {
- if (bonusInUse.count(destination))
- LOG("BONUS IN USE REMOVE" << destination.x << " " << destination.y << " - " << bonusInUse[destination]);
- bonusInUse.erase(destination);
- }
- };
- class GoToRandomPointMission : public GoToPointMission
- {
- public:
- GoToRandomPointMission(const Trooper & trooper, const Point & destination) : GoToPointMission(trooper, destination)
- {
- this->ignoreDanger = false;
- }
- };
- class Fight
- {
- public:
- Fight()
- {
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- distances[i] = INF_DIST;
- closestEnemyes[i] = NULL;
- minDistTrooper = -1;
- }
- }
- void calculateDistances();
- bool calculate()
- {
- if (minDistTrooper == -1)
- return false;
- const Trooper * trooper = findTeamTrooper(minDistTrooper);
- if (!trooper)
- return false;
- WalkMap walkMap;
- walkMap.build(trooper, trooper->getActionPoints());
- Enemy *enemies[3*5];
- int enemiesN = 0;
- for (FieldMap::Enemies::iterator it = fieldMap.enemies.begin(); it != fieldMap.enemies.end(); ++it)
- {
- enemies[enemiesN++] = &it->second;
- }
- }
- int distances[TOOPERS_COUNT];
- Enemy *closestEnemyes[TOOPERS_COUNT];
- int minDistTrooper;
- };
- class ShootEnemyMission : public Mission
- {
- public:
- ShootEnemyMission(const Trooper & self, const Enemy & enemy)
- {
- this->trooperIndex = self.getTeammateIndex();
- this->enemyId = enemy.id;
- }
- virtual bool perform()
- {
- if (eatFieldRation())
- return true;
- const Trooper *self = findTeamTrooper(trooperIndex);
- if (!fieldMap.enemies.count(this->enemyId))
- return false;
- const Enemy &enemy = fieldMap.enemies.find(this->enemyId)->second;
- if (self->getActionPoints() >= g_game->getGrenadeThrowCost() && self->isHoldingGrenade())
- {
- int dirInd = s_canThrowGrenage(*self, enemy);
- if (dirInd != -1)
- {
- Point target = getClosePoints(enemy.pos, dirInd);
- g_move->setAction(THROW_GRENADE);
- g_move->setX(target.x);
- g_move->setY(target.y);
- return true;
- }
- }
- if (self->getActionPoints() < self->getShootCost())
- {
- LOG("ShootEnemyMission, no actionPoints " << trooperIndex);
- return false;
- }
- if (!s_canShoot(*self, enemy))
- {
- LOG("Can't shoot " << self->getX() << " " << self->getY() << "->" << enemy.pos.x << " " << enemy.pos.y);
- return false;
- }
- LOG("SHOOT " << sqrt((double) (enemy.pos.dist2(Point(*self)))));
- g_move->setAction(SHOOT);
- g_move->setX(enemy.pos.x);
- g_move->setY(enemy.pos.y);
- return true;
- }
- virtual bool isPossible()
- {
- const Trooper *self = findTeamTrooper(trooperIndex);
- if (!self)
- return false;
- const Enemy *enemy = fieldMap.get(enemyId);
- if (!enemy || !(enemy->isConfirmed() || enemy->isProbable()))
- return false;
- return s_canShoot(*self, *enemy);
- }
- static bool s_canShoot(const Trooper &self, const Enemy &enemy)
- {
- bool canShoot = g_world->isVisible(self.getShootingRange(),
- self.getX(), self.getY(), self.getStance(),
- enemy.pos.x, enemy.pos.y, (TrooperStance) enemy.pos.stance);
- return canShoot;
- }
- static int s_canThrowGrenage(const Trooper &self, const Enemy &enemy)
- {
- Point target = enemy.pos;
- Point selfPoint = Point(self);
- int maxDamage = 0;
- int result = -1;
- for (int k = CLOSE_POINTS_N; k --> 0;)
- {
- Point cp = getClosePoints(target, k);
- if (selfPoint.dist2(cp) <= g_game->getGrenadeThrowRange()*g_game->getGrenadeThrowRange() && checkBounds(cp) && !selfPoint.isClose(cp))
- {
- int damage = (cp == target) ? g_game->getGrenadeDirectDamage() : g_game->getGrenadeCollateralDamage();
- if (maxDamage < damage)
- {
- maxDamage = damage;
- result = k;
- }
- }
- }
- return result;
- }
- private:
- int trooperIndex;
- TrooperId enemyId;
- };
- const Trooper *findTeamTrooperByType(TrooperType type)
- {
- const vector<Trooper>& troopers = g_world->getTroopers();
- for (int i = 0; i < troopers.size(); ++i)
- {
- const Trooper &trooper = troopers[i];
- if (trooper.isTeammate())
- {
- if (trooper.getType() == type)
- {
- return &trooper;
- }
- }
- }
- return NULL;
- }
- class MyTrooper
- {
- public:
- MyTrooper()
- {
- mission = NULL;
- hasLastRandomPoint = false;
- fireTime = -1000;
- getAwayFromWay = false;
- getAwayMoveIndex = -1;
- getAwayTrooperOrderIndex = -1;
- }
- virtual void recalculateMission() {}
- virtual ~MyTrooper()
- {
- delete mission;
- }
- void setMission(Mission *m)
- {
- delete mission;
- mission = m;
- }
- Mission * getMission()
- {
- return mission;
- }
- bool useMedikit()
- {
- const Trooper *self = findTeamTrooper(teammateIndex);
- if (self->getActionPoints() >= g_game->getMedikitUseCost() && self->isHoldingMedikit())
- {
- Point selfPoint = Point(*self);
- for (int k = CLOSE_POINTS_N; k --> 0;)
- {
- Point p = getClosePoints(selfPoint, k);
- const Trooper * trooper = getTrooper(p);
- int points = (selfPoint == p) ? g_game->getMedikitHealSelfBonusHitpoints() : g_game->getMedikitBonusHitpoints();
- if (trooper && trooper->isTeammate() && trooper->getHitpoints() <= (trooper->getMaximalHitpoints() - points))
- {
- LOG("USE MEDIKIT " << p.x << " " << p.y << " " << trooper->getHitpoints());
- g_move->setAction(USE_MEDIKIT);
- g_move->setX(p.x);
- g_move->setY(p.y);
- return true;
- }
- }
- }
- return false;
- }
- virtual bool heal()
- {
- return false;
- }
- bool findEnemy()
- {
- const Trooper *self = findTeamTrooper(teammateIndex);
- const vector<Trooper>& troopers = g_world->getTroopers();
- int enemyHealth = 1000;
- const Enemy *foundEnemy = NULL;
- for (FieldMap::Enemies::iterator it = fieldMap.enemies.begin(); it != fieldMap.enemies.end(); ++it)
- {
- const Enemy &enemy = it->second;
- if (enemy.isConfirmed())
- {
- bool canShoot = ShootEnemyMission::s_canShoot(*self, enemy);
- int curEnemyHealth = enemy.hitPoints;
- if (canShoot && (!foundEnemy || enemyHealth > curEnemyHealth))
- {
- enemyHealth = curEnemyHealth;
- foundEnemy = &enemy;
- }
- }
- }
- if (foundEnemy)
- {
- setMission(new ShootEnemyMission(*self, *foundEnemy));
- fireTime = g_world->getMoveIndex();
- return true;
- }
- for (FieldMap::Enemies::iterator it = fieldMap.enemies.begin(); it != fieldMap.enemies.end(); ++it)
- {
- const Enemy &enemy = it->second;
- if (enemy.isProbable())
- {
- bool canShoot = ShootEnemyMission::s_canShoot(*self, enemy);
- int curEnemyHealth = enemy.hitPoints;
- if (canShoot && (!foundEnemy || enemyHealth > curEnemyHealth))
- {
- enemyHealth = curEnemyHealth;
- foundEnemy = &enemy;
- }
- }
- }
- if (foundEnemy)
- {
- setMission(new ShootEnemyMission(*self, *foundEnemy));
- fireTime = g_world->getMoveIndex();
- return true;
- }
- /*for (FieldMap::Enemies::iterator it = fieldMap.enemies.begin(); it != fieldMap.enemies.end(); ++it)
- {
- const Enemy &enemy = it->second;
- if (enemy.isConfirmed())
- {
- int viewRad = getViewRadius(enemy.type);
- int shootRad = getShootRange(enemy.type);
- int rad = (viewRad > shootRad) ? viewRad : shootRad;
- bool isVisible = g_world->isVisible(rad, enemy.pos.x, enemy.pos.y, STANDING, self->getX(), self->getY(), self->getStance());
- int curEnemyHealth = enemy.hitPoints;
- if (isVisible && (!foundEnemy || enemyHealth < curEnemyHealth))
- {
- enemyHealth = curEnemyHealth;
- foundEnemy = &enemy;
- }
- }
- }
- if (foundEnemy)
- {
- setMission(new ShootEnemyMission(*self, *foundEnemy));
- fireTime = g_world->getMoveIndex();
- return true;
- }*/
- return false;
- }
- bool findBonus()
- {
- const Trooper *self = findTeamTrooper(teammateIndex);
- const Trooper *commander = findTeamTrooperByType(COMMANDER);
- Point foundBonusPoint;
- int bonusCost = 10000;
- bool foundBonus = false;
- for (int y = 0; y < H; ++y)
- {
- for (int x = 0; x < W; ++x)
- {
- int bonusType = fieldMap.getBonus(x, y);
- if (bonusType >= 0)
- {
- Point bonusPoint = Point(x, y);
- if (!isPointFree(bonusPoint, self))
- continue;
- if (bonusInUse.find(bonusPoint) != bonusInUse.end())
- {
- if (bonusInUse[bonusPoint] != self->getTeammateIndex())
- continue;
- }
- bool hasBonus = isHoldingBonus(*self, (BonusType) bonusType);
- int points = getBonusPoints(hasBonus, (BonusType) bonusType);
- if (points > 0)
- {
- GoToPointMission m(*self, bonusPoint);
- //if (m.isPossible())
- {
- int cost = m.getLength() * 2 - points;
- if (bonusCost > cost)
- {
- bonusCost = cost;
- foundBonusPoint = bonusPoint;
- foundBonus = true;
- }
- }
- }
- }
- }
- }
- if (foundBonus)
- {
- LOG("GoToPointMission " << foundBonusPoint.x << " " << foundBonusPoint.y);
- setMission(new GoToBonusMission(*self, foundBonusPoint));
- bonusInUse[foundBonusPoint] = self->getTeammateIndex();
- return true;
- }
- return false;
- }
- bool goToSafePlace()
- {
- LOG("goToSafePlace");
- const Trooper *self = findTeamTrooper(teammateIndex);
- if (self->getActionPoints() < g_game->getStandingMoveCost())
- {
- LOG("goToSafePlace, no actionPoints " << teammateIndex);
- return false;
- }
- Point selfPoint = Point(*self);
- int safePointInd = -1;
- int estimatedSafePointInd = -1;
- int danger = 1000000;
- double estimatedDanger = 1000000;
- int cdanger = danger;
- double cEstimatedDanger = estimatedDanger;
- for (int k = CLOSE_POINTS_N; k --> 0;)
- {
- Point p = getClosePoints(selfPoint, k);
- if (isPointFree(p, self))
- {
- int curDanger = getDanger(*self, p);
- double curEstimatedDanger = estimateDanger(p, self->getType());
- if (p == selfPoint)
- {
- cdanger = curDanger;
- cEstimatedDanger = curEstimatedDanger;
- }
- LOG("Danger " << p.x << " " << p.y << " = " << curDanger << "|" << curEstimatedDanger);
- if (danger > curDanger)
- {
- danger = curDanger;
- safePointInd = k;
- }
- if (estimatedDanger > curEstimatedDanger)
- {
- estimatedDanger = curEstimatedDanger;
- estimatedSafePointInd = k;
- }
- }
- }
- int moveToInd = -1;
- if (safePointInd != -1 && danger < cdanger)
- {
- moveToInd = safePointInd;
- }
- else if (estimatedSafePointInd != -1 && estimatedDanger < cEstimatedDanger && cEstimatedDanger > 20.0)
- {
- moveToInd = estimatedSafePointInd;
- }
- if (moveToInd != -1)
- {
- Point p = getClosePoints(selfPoint, moveToInd);
- if (!(p == selfPoint))
- {
- if (self->getActionPoints() < getMoveCost(self->getStance()))
- return false;
- g_move->setAction(MOVE);
- g_move->setX(p.x);
- g_move->setY(p.y);
- return true;
- }
- }
- return false;
- }
- bool findRandomPoint()
- {
- const Trooper *self = findTeamTrooper(teammateIndex);
- if (hasLastRandomPoint)
- {
- if (Point(*self).dist2(lastRandomPoint) < 9)
- hasLastRandomPoint = false;
- }
- if (!hasLastRandomPoint)
- {
- lastRandomPoint = getRandomPoint(self);
- hasLastRandomPoint = true;
- }
- LOG("GOTO RANDOM POINT " << lastRandomPoint.x << " " << lastRandomPoint.y);
- setMission(new GoToRandomPointMission(*self, lastRandomPoint));
- return true;
- }
- bool goToTeamMember(TrooperType type)
- {
- const Trooper *self = findTeamTrooper(teammateIndex);
- const Trooper * trooper = findTeamTrooperByType(type);
- int danger = 1000000;
- if (trooper)
- {
- bool isMedic = (self->getType() == FIELD_MEDIC);
- Point trooperPoint = Point(*trooper);
- int dirInd = -1;
- int len = 1000000;
- for (int k = CLOSE_POINTS_N; k --> 0;)
- {
- Point p = getClosePoints(trooperPoint, k);
- if (isPointFree(p, self))
- {
- GoToPointMission m = GoToPointMission(*self, p);
- if (m.isPossible())
- {
- int curDanger = getDanger(*self, p);
- if (dirInd == -1)
- {
- dirInd = k;
- len = m.getLength();
- danger = curDanger;
- }
- else
- {
- if (isMedic)
- {
- if (len > m.getLength())
- len = m.getLength();
- if ((len + 2) > m.getLength() && curDanger < danger)
- {
- dirInd = k;
- danger = curDanger;
- }
- }
- else
- {
- if (len > m.getLength())
- {
- dirInd = k;
- len = m.getLength();
- danger = curDanger;
- }
- }
- }
- }
- }
- }
- if (dirInd != -1)
- {
- Point p = getClosePoints(trooperPoint, dirInd);
- LOG("GOTO Teammember " << p.x << " " << p.y);
- setMission(new GoToPointMission(*self, p));
- return true;
- }
- }
- return false;
- }
- bool getAway()
- {
- LOG("Check getAway " << getAwayFromWay << " " << getAwayMoveIndex << " " << getAwayTrooperOrderIndex);
- const Trooper *self = findTeamTrooper(teammateIndex);
- if (getAwayFromWay)
- {
- LOG("Set GetAway");
- if (self->getType() == g_self->getType())
- getAwayFromWay = false;
- getAwayMoveIndex = moveIndex;
- getAwayTrooperOrderIndex = trooperMoveOrderIndex;
- }
- if (getAwayMoveIndex == moveIndex && getAwayTrooperOrderIndex == trooperMoveOrderIndex)
- {
- LOG("GetAway");
- Point curPoint = Point(*self);
- if (!obstaclePoints.count(curPoint))
- return true;
- WalkMap walkMap;
- walkMap.build(self, self->getActionPoints());
- int r = 5;
- Point p1 = Point(curPoint.x - r, curPoint.y - r);
- Point p2 = Point(curPoint.x + r, curPoint.y + r);
- fit(p1);
- fit(p2);
- int dist = INF_DIST;
- Point destination;
- for (int x = p1.x; x <= p2.x; ++x)
- {
- for (int y = p1.y; y <= p2.y; ++y)
- {
- Point t = Point(x, y);
- const WalkMap::PtVal &val = walkMap.get(Position(t.x, t.y, STANDING));
- if (dist > val.dist && !obstaclePoints.count(t))
- {
- dist = val.dist;
- destination = t;
- }
- }
- }
- if (dist == INF_DIST)
- {
- LOG("getAway can't find free point");
- return false;
- }
- setMission(new ClearWayMission(*self, destination));
- return true;
- }
- return false;
- }
- bool getCommandFromCoordinationCenter()
- {
- if ((coordinationCenter.actionType == AT_COLLECT_BONUSES ||
- coordinationCenter.actionType == AT_GOTO_RANDOM_POINT ||
- coordinationCenter.actionType == AT_STOP) && getAway())
- return true;
- const Trooper *self = findTeamTrooper(teammateIndex);
- if (coordinationCenter.actionType == AT_COLLECT_BONUSES)
- {
- Position &p = coordinationCenter.goToPositions[teammateIndex];
- LOG("AT_COLLECT_BONUSES " << p.x << " " << p.y);
- setMission(new GoToBonusMission(*self, p));
- if (getMission()->isPossible())
- return true;
- }
- if (coordinationCenter.actionType == AT_GOTO_RANDOM_POINT)
- {
- Position &p = coordinationCenter.goToPositions[teammateIndex];
- LOG("AT_GOTO_RANDOM_POINT " << p.x << " " << p.y);
- setMission(new GoToRandomPointMission(*self, p));
- if (getMission()->isPossible())
- return true;
- }
- if (coordinationCenter.actionType == AT_STOP && coordinationCenter.stopTrooperType == self->getType())
- {
- return true;
- }
- if (coordinationCenter.actionType == AT_FIGHT)
- {
- if (self->getType() == g_self->getType() && coordinationCenter.detailsMap.count(self->getType()))
- {
- FightActionDetails &details = coordinationCenter.detailsMap[self->getType()];
- if (details.type == AD_FIRE)
- {
- if (details.from == Position(*self))
- {
- if (fieldMap.enemies.count(details.enemyId))
- {
- LOG(trooperTypeNames[self->getType() + 1] << ": shoot enemy " << details.to.x << " " << details.to.y);
- setMission(new ShootEnemyMission(*self, fieldMap.enemies[details.enemyId]));
- return true;
- }
- }
- else
- {
- LOG(trooperTypeNames[self->getType() + 1] << ": go to pos " << details.from.x << " " << details.from.y << " " << details.from.stance);
- setMission(new GoToPointMission(*self, details.from, (TrooperStance) details.from.stance));
- return true;
- }
- }
- }
- }
- return false;
- }
- bool goToCommander()
- {
- LOG("goToCommander");
- return goToTeamMember(COMMANDER);
- }
- bool goToMedic()
- {
- LOG("goToMedic");
- return goToTeamMember(FIELD_MEDIC);
- }
- bool goToSniper()
- {
- LOG("goToSniper");
- return goToTeamMember(SNIPER);
- }
- bool goToScout()
- {
- LOG("goToScout");
- return goToTeamMember(SCOUT);
- }
- bool goToSoldier()
- {
- LOG("goToSoldier");
- return goToTeamMember(SOLDIER);
- }
- bool needBackup() const
- {
- bool result = (fireTime > (g_world->getMoveIndex() - 1));
- if (result)
- LOG("Need Backup " << teammateIndex << " fireTime: " << fireTime);
- return result;
- }
- void notifyObstacle(const vector<Position> &path)
- {
- if (!getAwayFromWay)
- obstaclePoints.clear();
- getAwayFromWay = true;
- for (int i = 0; i < path.size(); ++i)
- obstaclePoints.insert(path[i]);
- }
- int teammateIndex;
- private:
- int fireTime;
- Mission *mission;
- Point lastRandomPoint;
- bool hasLastRandomPoint;
- bool getAwayFromWay;
- int getAwayMoveIndex, getAwayTrooperOrderIndex;
- set<Point> obstaclePoints;
- };
- typedef MyTrooper * MyTrooperPtr;
- MyTrooperPtr g_myTroopers[TOOPERS_COUNT];
- MyTrooperPtr g_myTroopersOrdered[TOOPERS_COUNT];
- void GoToPointMission::notifyObstacle(const Trooper *obstacleTrooper)
- {
- MyTrooperPtr myTrooper = g_myTroopers[obstacleTrooper->getTeammateIndex()];
- if (myTrooper)
- {
- myTrooper->notifyObstacle(path);
- }
- }
- class MyCommander : public MyTrooper
- {
- virtual void recalculateMission()
- {
- LOG("Commander recalculateMission");
- if (getCommandFromCoordinationCenter())
- return;
- if (findEnemy())
- return;
- if (getAway())
- return;
- const Trooper * soldier = findTeamTrooperByType(SOLDIER);
- if (soldier && g_myTroopers[soldier->getTeammateIndex()]->needBackup())
- {
- LOG("cgs");
- if (goToSoldier())
- return;
- }
- const Trooper * medic = findTeamTrooperByType(FIELD_MEDIC);
- if (medic && g_myTroopers[medic->getTeammateIndex()]->needBackup())
- {
- LOG("cgm");
- if (goToMedic())
- return;
- }
- LOG("cgb");
- if (findBonus())
- return;
- if (soldier && soldier->getHitpoints() < soldier->getMaximalHitpoints())
- {
- LOG("cgs2");
- if (goToSoldier())
- return;
- }
- LOG("cgr");
- findRandomPoint();
- }
- };
- class MyMedic : public MyTrooper
- {
- bool heal()
- {
- LOG("Medic heal");
- const Trooper *self = findTeamTrooper(teammateIndex);
- Point selfPoint = Point(*self);
- bool canHeal = false;
- Point healPoint;
- int healHitpoints = 0;
- if (self->getActionPoints() >= g_game->getFieldMedicHealCost())
- {
- for (int k = CLOSE_POINTS_N; k --> 0;)
- {
- Point p = getClosePoints(selfPoint, k);
- const Trooper * trooper = getTrooper(p);
- int points = (selfPoint == p) ? g_game->getFieldMedicHealSelfBonusHitpoints() : g_game->getFieldMedicHealBonusHitpoints();
- if (trooper && trooper->isTeammate() && trooper->getHitpoints() < trooper->getMaximalHitpoints())
- {
- if (!fieldMap.hasEnemies() || trooper->getHitpoints() <= (trooper->getMaximalHitpoints() - points))
- {
- canHeal = true;
- int currentHealHitpoints = trooper->getMaximalHitpoints() - trooper->getHitpoints();
- if (currentHealHitpoints > points)
- currentHealHitpoints = points;
- if (healHitpoints < currentHealHitpoints)
- {
- healHitpoints = currentHealHitpoints;
- healPoint = p;
- }
- }
- }
- }
- }
- // if not healing yorself and there is danger, go to safe point
- if (canHeal && (healPoint == selfPoint))
- {
- if (getDanger(*self, selfPoint) > 0 || estimateDanger(Point(*self), self->getType()) > 20.0)
- {
- const Trooper * commander = findTeamTrooperByType(COMMANDER);
- const Trooper * soldier = findTeamTrooperByType(SOLDIER);
- int minDist = 1000;
- if (commander)
- {
- int md = selfPoint.sqDist(Point(*commander));
- if (md < minDist)
- minDist = md;
- }
- if (soldier)
- {
- int md = selfPoint.sqDist(Point(*soldier));
- if (md < minDist)
- minDist = md;
- }
- if (minDist >= 2)
- {
- if (goToSafePlace())
- return true;
- }
- }
- }
- if (canHeal)
- {
- g_move->setAction(HEAL);
- g_move->setX(healPoint.x);
- g_move->setY(healPoint.y);
- return true;
- }
- return false;
- }
- virtual void recalculateMission()
- {
- LOG("Medic recalculateMission");
- if (getCommandFromCoordinationCenter())
- return;
- if (findEnemy())
- return;
- if (getAway())
- return;
- const Trooper * commander = findTeamTrooperByType(COMMANDER);
- if (commander && (commander->getHitpoints() < commander->getMaximalHitpoints() || g_myTroopers[commander->getTeammateIndex()]->needBackup()))
- {
- LOG("mgc");
- if (goToCommander())
- return;
- }
- const Trooper * soldier = findTeamTrooperByType(SOLDIER);
- if (soldier && (soldier->getHitpoints() < soldier->getMaximalHitpoints() || g_myTroopers[soldier->getTeammateIndex()]->needBackup()))
- {
- LOG("mgs");
- if (goToSoldier())
- return;
- }
- if (commander && coordinationCenter.enemyFound)
- {
- if (goToCommander())
- return;
- }
- if (soldier && coordinationCenter.enemyFound)
- {
- if (goToSoldier())
- return;
- }
- LOG("mgb");
- if (findBonus())
- return;
- LOG("mgc2");
- if (goToCommander())
- return;
- LOG("mgs2");
- if (goToSoldier())
- return;
- LOG("mgr");
- findRandomPoint();
- }
- };
- class MySoldier : public MyTrooper
- {
- virtual void recalculateMission()
- {
- LOG("Soldier recalculateMission");
- if (getCommandFromCoordinationCenter())
- return;
- if (findEnemy())
- return;
- if (getAway())
- return;
- const Trooper * commander = findTeamTrooperByType(COMMANDER);
- if (commander && g_myTroopers[commander->getTeammateIndex()]->needBackup())
- {
- LOG("sgc");
- if (goToCommander())
- return;
- }
- const Trooper * medic = findTeamTrooperByType(FIELD_MEDIC);
- if (medic && g_myTroopers[medic->getTeammateIndex()]->needBackup())
- {
- LOG("sgm");
- if (goToMedic())
- return;
- }
- if (findBonus())
- return;
- const Trooper *self = findTeamTrooper(teammateIndex);
- if (self->getHitpoints() < self->getMaximalHitpoints())
- {
- LOG("sgm");
- if (goToMedic())
- return;
- }
- LOG("sgc2");
- if (goToCommander())
- return;
- LOG("sgr");
- findRandomPoint();
- }
- };
- class MySniper : public MyTrooper
- {
- virtual void recalculateMission()
- {
- LOG("Soldier recalculateMission");
- if (getCommandFromCoordinationCenter())
- return;
- if (findEnemy())
- return;
- if (getAway())
- return;
- const Trooper *self = findTeamTrooper(teammateIndex);
- Point selfPoint = Point(*self);
- if (getDanger(*self, selfPoint) > 0 || estimateDanger(Point(*self), self->getType()) > 20.0)
- {
- const Trooper * commander = findTeamTrooperByType(COMMANDER);
- const Trooper * soldier = findTeamTrooperByType(SOLDIER);
- int minDist = 1000;
- if (commander)
- {
- int md = selfPoint.sqDist(Point(*commander));
- if (md < minDist)
- minDist = md;
- }
- if (soldier)
- {
- int md = selfPoint.sqDist(Point(*soldier));
- if (md < minDist)
- minDist = md;
- }
- if (minDist >= 2)
- {
- if (goToSafePlace())
- return;
- }
- }
- const Trooper * commander = findTeamTrooperByType(COMMANDER);
- if (commander && g_myTroopers[commander->getTeammateIndex()]->needBackup())
- {
- LOG("sngc");
- if (goToCommander())
- return;
- }
- const Trooper * soldier = findTeamTrooperByType(SOLDIER);
- if (soldier && g_myTroopers[soldier->getTeammateIndex()]->needBackup())
- {
- LOG("sngs");
- if (goToSoldier())
- return;
- }
- const Trooper * scout = findTeamTrooperByType(SCOUT);
- if (scout && g_myTroopers[scout->getTeammateIndex()]->needBackup())
- {
- LOG("sngsc");
- if (goToScout())
- return;
- }
- const Trooper * medic = findTeamTrooperByType(FIELD_MEDIC);
- if (medic && g_myTroopers[medic->getTeammateIndex()]->needBackup())
- {
- LOG("sngm");
- if (goToMedic())
- return;
- }
- if (findBonus())
- return;
- if (self->getHitpoints() < self->getMaximalHitpoints())
- {
- LOG("sngm");
- if (goToMedic())
- return;
- }
- LOG("sngc2");
- if (goToCommander())
- return;
- LOG("sngr");
- findRandomPoint();
- }
- };
- class MyScout : public MyTrooper
- {
- virtual void recalculateMission()
- {
- LOG("Soldier recalculateMission");
- if (getCommandFromCoordinationCenter())
- return;
- if (findEnemy())
- return;
- if (getAway())
- return;
- const Trooper *self = findTeamTrooper(teammateIndex);
- Point selfPoint = Point(*self);
- if (getDanger(*self, selfPoint) > 0 || estimateDanger(Point(*self), self->getType()) > 20.0)
- {
- const Trooper * commander = findTeamTrooperByType(COMMANDER);
- const Trooper * soldier = findTeamTrooperByType(SOLDIER);
- int minDist = 1000;
- if (commander)
- {
- int md = selfPoint.sqDist(Point(*commander));
- if (md < minDist)
- minDist = md;
- }
- if (soldier)
- {
- int md = selfPoint.sqDist(Point(*soldier));
- if (md < minDist)
- minDist = md;
- }
- if (minDist >= 2)
- {
- if (goToSafePlace())
- return;
- }
- }
- const Trooper * commander = findTeamTrooperByType(COMMANDER);
- if (commander && g_myTroopers[commander->getTeammateIndex()]->needBackup())
- {
- LOG("sngc");
- if (goToCommander())
- return;
- }
- const Trooper * soldier = findTeamTrooperByType(SOLDIER);
- if (soldier && g_myTroopers[soldier->getTeammateIndex()]->needBackup())
- {
- LOG("scgs");
- if (goToSoldier())
- return;
- }
- const Trooper * sniper = findTeamTrooperByType(SNIPER);
- if (sniper && g_myTroopers[sniper->getTeammateIndex()]->needBackup())
- {
- LOG("scgsn");
- if (goToSniper())
- return;
- }
- const Trooper * medic = findTeamTrooperByType(FIELD_MEDIC);
- if (medic && g_myTroopers[medic->getTeammateIndex()]->needBackup())
- {
- LOG("scgm");
- if (goToMedic())
- return;
- }
- if (findBonus())
- return;
- if (self->getHitpoints() < self->getMaximalHitpoints())
- {
- LOG("scgm");
- if (goToMedic())
- return;
- }
- LOG("scgc2");
- if (goToCommander())
- return;
- LOG("scgr");
- findRandomPoint();
- }
- };
- void initialize()
- {
- LOG("Initialize");
- initializeNearDistDeltas();
- fieldMap.initialize();
- trooperDistributionMap.initialize();;
- #if ENABLE_LOGGING
- //g_world->saveMap();
- #endif
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- g_myTroopers[i] = NULL;
- }
- ENEMY_TROOPERSN = 0;
- const vector<Trooper>& troopers = g_world->getTroopers();
- for (int i = 0; i < troopers.size(); ++i)
- {
- const Trooper &trooper = troopers[i];
- if (trooper.isTeammate())
- {
- ENEMY_TROOPERSN++;
- TrooperType type = trooper.getType();
- MyTrooperPtr myTooper = NULL;
- if (type == COMMANDER)
- {
- myTooper = new MyCommander;
- }
- else if (type == FIELD_MEDIC)
- {
- myTooper = new MyMedic;
- }
- else if(type == SOLDIER)
- {
- myTooper = new MySoldier;
- }
- else if(type == SNIPER)
- {
- myTooper = new MySniper;
- }
- else if(type == SCOUT)
- {
- myTooper = new MyScout;
- }
- if (myTooper)
- {
- myTooper->teammateIndex = trooper.getTeammateIndex();
- g_myTroopers[trooper.getTeammateIndex()] = myTooper;
- }
- }
- }
- ENEMY_TROOPERSN *= 3;
- }
- void newMove()
- {
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- g_myTroopersOrdered[i] = NULL;
- }
- for (int i = 0 ; i < TOOPERS_COUNT; ++i)
- {
- MyTrooperPtr myTrooper = g_myTroopers[i];
- if (myTrooper)
- {
- const Trooper *trooper = findTeamTrooper(myTrooper->teammateIndex);
- if (trooper != NULL)
- {
- TrooperType type = trooper->getType();
- if (moveOrder.count(type))
- {
- g_myTroopersOrdered[moveOrder[type]] = myTrooper;
- }
- }
- else
- {
- delete g_myTroopers[i];
- g_myTroopers[i] = NULL;
- }
- }
- }
- for (int i = 0; i < TOOPERS_COUNT; ++i)
- {
- if (g_myTroopersOrdered[i])
- {
- g_myTroopersOrdered[i]->recalculateMission();
- }
- }
- }
- bool g_newMove;
- void updateMoveIndex()
- {
- g_newMove = false;
- static TrooperType oldType = UNKNOWN_TROOPER;
- static int oldMoveIndex = -1;
- if (moveIndex == -1)
- {
- initialize();
- }
- moveIndex = g_world->getMoveIndex();
- if (oldMoveIndex != moveIndex)
- {
- oldMoveIndex = moveIndex;
- g_newMove = true;
- }
- if (moveIndex == 0)
- {
- if (oldType == UNKNOWN_TROOPER)
- {
- trooperMoveOrderIndex = 0;
- }
- else if (g_self->getType() != oldType)
- {
- trooperMoveOrderIndex++;
- }
- oldType = g_self->getType();
- moveOrder[oldType] = trooperMoveOrderIndex;
- }
- else
- {
- trooperMoveOrderIndex = moveOrder[g_self->getType()];
- }
- }
- void updateTroopersMap()
- {
- for (int i = 0; i < W * H; ++i)
- troopersMap[i] = NULL;
- const vector<Trooper>& troopers = g_world->getTroopers();
- for (int i = 0; i < troopers.size(); ++i)
- {
- const Trooper &trooper = troopers[i];
- troopersMap[trooper.getY() * W + trooper.getX()] = &trooper;
- }
- }
- void logMove()
- {
- if (!ENABLE_LOGGING)
- return;
- ActionType actionType = g_move->getAction();
- string actionName;
- if (actionType == END_TURN)
- actionName = "END_TURN";
- else if (actionType == MOVE)
- actionName = "MOVE";
- else if (actionType == SHOOT)
- actionName = "SHOOT";
- else if (actionType == RAISE_STANCE)
- actionName = "RAISE_STANCE";
- else if (actionType == LOWER_STANCE)
- actionName = "LOWER_STANCE";
- else if (actionType == THROW_GRENADE)
- actionName = "THROW_GRENADE";
- else if (actionType == USE_MEDIKIT)
- actionName = "USE_MEDIKIT";
- else if (actionType == EAT_FIELD_RATION)
- actionName = "EAT_FIELD_RATION";
- else if (actionType == HEAL)
- actionName = "HEAL";
- else if (actionType == REQUEST_ENEMY_DISPOSITION)
- actionName = "REQUEST_ENEMY_DISPOSITION";
- LOG("Action " << actionName << " " << g_move->getX() << " " << g_move->getY());
- }
- void makeMove()
- {
- LOG("actionPoints " << g_self->getActionPoints());
- MyTrooperPtr myTrooper = g_myTroopers[g_self->getTeammateIndex()];
- if (myTrooper)
- {
- if (myTrooper->useMedikit())
- return;
- if (myTrooper->heal())
- return;
- myTrooper->recalculateMission();
- if (myTrooper->getMission())
- {
- if (!myTrooper->getMission()->perform())
- myTrooper->goToSafePlace();
- }
- }
- }
- #if ENABLE_LOGGING
- struct Env
- {
- Env()
- {
- }
- int moveIndex;
- std::vector<Player> players;
- std::vector<Trooper> troopers;
- std::vector<Bonus> bonuses;
- std::vector<std::vector<CellType> > cells;
- std::vector<bool> cellVisibilities;
- } env;
- void makeEnv()
- {
- Trooper commander = Trooper(1, 5, 15, 1, 0, true, COMMANDER, STANDING,
- 100, 100, 10, 10, 9.0, 8.0, 3, 25, 30, 35, 30, false, false, false);
- env.troopers.push_back(commander);
- Trooper soldier = Trooper(1, 5, 16, 1, 1, true, SOLDIER, STANDING,
- 100, 100, 10, 10, 9.0, 8.0, 3, 25, 30, 35, 30, false, false, false);
- env.troopers.push_back(soldier);
- env.cells.resize(30);
- for (int x = 0; x < 30; ++x)
- {
- env.cells[x].resize(20);
- for (int y = 0; y < 20; ++y)
- {
- env.cells[x][y] = FREE;
- if (x > 10 && x < 15 && y > 7 && y < 12)
- env.cells[x][y] = HIGH_COVER;
- }
- }
- env.cellVisibilities.resize(30 * 20 * 30 * 20 * 3);
- for (int i = 0; i < env.cellVisibilities.size(); ++i)
- {
- env.cellVisibilities[i] = true;
- }
- Bonus b = Bonus(1, 25, 15, MEDIKIT);
- env.bonuses.push_back(b);
- g_world = new World(1, 30, 20, env.players, env.troopers, env.bonuses, env.cells, env.cellVisibilities);
- g_game = new Game(50,
- 100, 100,
- 100, 100,
- 2, 2, 4, 6,
- 2, 5.0,
- 9, 5,
- 2, 50, 50,
- 0, 1, 2,
- 12, 10,
- 2.0, 1.0,
- 5, 5, 80, 60,
- 2, 50, 30,
- 2, 5);
- g_self = &g_world->getTroopers()[0];
- }
- void test()
- {
- makeEnv();
- troopersMap.resize(W * H);
- updateTroopersMap();
- updateMoveIndex();
- fieldMap.update();
- coordinationCenter.updateMissions();
- logMap(NULL);
- }
- #endif
- void MyStrategy::move(const Trooper& self, const World& world, const Game& game, Move& move) {
- g_self = &self;
- g_world = &world;
- g_game = &game;
- g_move = &move;
- LOG("BNS M" << self.isHoldingMedikit() << " G" << self.isHoldingGrenade() << " F" << self.isHoldingFieldRation());
- troopersMap.resize(W * H);
- updateTroopersMap();
- updateMoveIndex();
- fieldMap.update();
- trooperDistributionMap.update();
- coordinationCenter.updateMissions();
- if (g_newMove)
- {
- g_newMove = false;
- newMove();
- }
- makeMove();
- logMap(NULL);
- logMove();
- fieldMap.updateAfterMove();
- coordinationCenter.updateState();
- trooperDistributionMap.log();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement