Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Player.hh"
- #include "State.hh"
- #include <list>
- #include <algorithm>
- #include <map>
- #include <set>
- #include <string>
- #include <cmath>
- #include <limits.h>
- /**
- * Write the name of your player and save this file
- * with the same name and .cc extension.
- */
- #define PLAYER_NAME EnfermeraJoy
- struct PLAYER_NAME : public Player {
- /**
- * Factory: returns a new instance of this class.
- * Do not modify this function.
- */
- static Player* factory () {
- return new PLAYER_NAME;
- }
- /**
- * Types and attributes for your player can be defined here.
- */
- //////////////////STRUCTS DEFINITION/////////////////
- struct CityInfo;
- struct PathInfo;
- struct OrkThoughts;
- ////////////////VARIABLES//////////////
- map<int,OrkThoughts> orkBrain;
- vector<CityInfo> cities;
- vector<PathInfo> paths;
- int orksPerCityAndPath;
- set<int> aliveOrks;
- //////////////////STRUCTS ////////////////
- enum targetType {
- T_ENEMY,
- T_CITY,
- T_PATH,
- T_CELL,
- T_NONE
- };
- struct CityInfo{
- Pos pos;
- Pos posCenter; //Center position, if uncentered wins TOP and/or RIGHT
- int id;
- int height;
- int width;
- vector<Pos> positions;
- vector<int> path;
- map<int, pair<Pos,Dir> > pathBegin;
- vector<int> nearCity;
- set<int> orksMine; //TODO update regularly
- };
- struct PathInfo{
- int cityBegin;
- int cityEnd;
- Dir beginDir;
- Dir endDir;
- int id;
- vector<Pos> positions;
- int length;
- set<int> orksMine;
- };
- struct Target {
- targetType type;
- int id;
- int cell;
- Pos pos;
- Target() : type(T_NONE) , id(-1) , cell(-1) {}
- };
- Pos targetPos(Target t){
- switch (t.type) {
- case T_CITY:
- return t.pos;
- break;
- case T_ENEMY:
- return unit(t.id).pos;
- break;
- case T_PATH:
- return t.pos;
- break;
- case T_CELL:
- return t.pos;
- break;
- default:
- //cerr << "Debug: Target pos unknown (targetType=" << t.type << ")" << endl;
- Pos p(30,30);
- return p;
- break;
- }
- }
- struct OrkThoughts{
- Target target;
- vector < vector<Unit> > enemyAtStepsAway;
- int sf; //Steps Followed an enemy
- };
- //////////////////////FUNCTIONS////////////////////
- Pos distance(Pos a, Pos b){
- if(b.i == 0 and b.j == 0) return b;
- b.i -= a.i;
- b.j -= a.j;
- return b;
- }
- Pos calcCityCenter(Pos pos, const int& width, const int& height){
- pos.j += width/2;
- pos.i += height/2;
- return pos;
- }
- CityInfo createCity(const vector<Pos>& positions, const int& id){
- CityInfo c;
- c.id = id;
- //auto result = minmax_element(positions.begin(), positions.end());
- //Pos size = distance(positions[result.first - positions.begin()], positions[result.second - positions.begin()]);
- Pos size;
- size = distance(positions[0], positions[positions.size()-1]); // alternative
- c.width = size.j;
- c.height = size.i;
- c.positions = positions;
- c.pos = positions[0];
- c.posCenter = calcCityCenter(positions[0], size.j, size.i);
- return c;
- }
- Dir closestCityCellIsAt(const Pos& p){
- vector<Dir> d;
- d.push_back(TOP);
- d.push_back(BOTTOM);
- d.push_back(RIGHT);
- d.push_back(LEFT);
- for (int i = 0; i < 4; i++) {
- if(cell(p+d[i]).type == CITY) return d[i];
- }
- return NONE;
- }
- Dir closestWaterCellIsAt(const Pos& p){
- vector<Dir> d;
- d.push_back(TOP);
- d.push_back(BOTTOM);
- d.push_back(RIGHT);
- d.push_back(LEFT);
- vector<int> r(4);
- r = random_permutation(4);
- for (int i = 0; i < (int)r.size(); i++) {
- if(cell(p+d[r[i]]).type == WATER) return d[r[i]];
- }
- return NONE;
- }
- bool hasWaterNear(const int& orkId){
- return closestWaterCellIsAt(unit(orkId).pos) != NONE;
- }
- PathInfo createPath(const pair< pair<int,int>, vector<Pos> >& positions, const int& id){
- PathInfo p;
- p.cityBegin = positions.first.first;
- p.cityEnd = positions.first.second;
- p.beginDir = closestCityCellIsAt(positions.second[0]);
- p.endDir = closestCityCellIsAt(positions.second[positions.second.size()-1]);
- p.id = id;
- p.positions = positions.second;
- p.length = positions.second.size();
- return p;
- }
- int distanceLength(const Pos& a){
- return abs(a.i) + abs(a.j);
- }
- bool isSafe(const Pos& p){
- return (cell(p).type == CITY) or (cell(p).type == PATH);
- }
- bool isSafe(const int& orkId){
- return (cell(unit(orkId).pos).type == CITY) or (cell(unit(orkId).pos).type == PATH);
- }
- bool isInAPath(const int& orkId){
- return cell(unit(orkId).pos).type == PATH;
- }
- bool isInACity(const int& orkId){
- return cell(unit(orkId).pos).type == CITY;
- }
- bool targetIsAPath(const int& orkId){
- return orkBrain[orkId].target.type == T_PATH;
- }
- bool targetIsACity(const int& orkId){
- return orkBrain[orkId].target.type == T_CITY;
- }
- bool targetIsACell(const int& orkId){
- return orkBrain[orkId].target.type == T_CELL;
- }
- int currentCity(const int& orkId){
- return cell(unit(orkId).pos).city_id;
- }
- int currentPath(const int& orkId){
- return cell(unit(orkId).pos).path_id;
- }
- Dir randDir(){
- if(random(0,50) == 0) return NONE;
- return random(0,1) ? randDir(TOP,BOTTOM) : randDir(LEFT,RIGHT);
- }
- Dir randDir(const Dir& a, const Dir& b){
- return random(0,1) ? a : b;
- }
- Dir randDir(const Dir& a, const Dir& b, const Dir& c){
- return random(0,1) ? randDir(a,b) : b;
- }
- Dir dominantDir(const Pos& p){
- double x = p.j;
- double y = -p.i;
- if(x==0.0 and y==0.0) return NONE; //also could be randDir()
- double aRad = atan2(y, x);
- double a = (aRad / M_PI) * 180.0;
- if(a<0) a += 360.0;
- switch((int)a){
- case 45: return randDir(TOP,RIGHT); break;
- case 135: return randDir(TOP,LEFT); break;
- case 225: return randDir(BOTTOM,LEFT); break;
- case 315: return randDir(BOTTOM,RIGHT); break;
- }
- if(a<45.0 or a>315.0) return RIGHT;
- if(a>45.0 and a<135.0) return TOP;
- if(a>135.0 and a<225.0) return LEFT;
- if(a>225.0 and a<315.0) return BOTTOM;
- return randDir();
- }
- Dir opositeDir(const Dir& d){
- switch (d) {
- case TOP: return BOTTOM; break;
- case BOTTOM: return TOP; break;
- case LEFT: return RIGHT; break;
- case RIGHT: return LEFT; break;
- default: return d; break;
- }
- }
- string dirName(const Dir& d){
- switch (d) {
- case TOP: return "TOP"; break;
- case BOTTOM: return "BOTTOM"; break;
- case RIGHT: return "RIGHT"; break;
- case LEFT: return "LEFT"; break;
- case NONE: return "NONE"; break;
- default: return "UNKNOWN"; break;
- }
- }
- void move(const int& orkId, const Dir& dir){
- avoidCloserEnemies(orkId,dir);
- move2(orkId, dir,0);
- }
- void move2(const int& orkId, const Dir& dir, int tryNum){
- Pos newPos = unit(orkId).pos + dir;
- if(tryNum<30){
- ++tryNum;
- if(pos_ok(newPos) and cell(newPos).type != WATER){
- int friendOrkId = cell(newPos).unit_id;
- if(isMyOrk(friendOrkId)){
- //cerr << "Debug: Ork " << orkId << " tried to walk on a friend by going to " << dirName(dir) << " at " << newPos << endl; //debug
- if (isSafe(newPos) and random(0,4)!=0) {
- execute(Command(orkId, dir));
- }else{
- move2(orkId, randDir(),tryNum);
- }
- orkBrain[orkId].target.type = T_NONE;
- }else{
- execute(Command(orkId, dir));
- //if(dir == NONE) cerr << "Debug: Ork " << orkId << " didn't move" << endl; //debug
- //else cerr << "Debug: Ork " << orkId << " moved " << dirName(dir) << " to " << newPos << endl; //debug
- }
- }else{
- //cerr << "Debug: Ork " << orkId << " tried to walk on water by going to " << dirName(dir) << " at " << newPos << endl; //debug
- move2(orkId, randDir(),tryNum);
- orkBrain[orkId].target.type = T_NONE;
- }
- }else{
- //cerr << "Debug: Ork " << orkId << " tried " << tryNum << " times to move, so he won't care about where to go" << endl; //debug
- execute(Command(orkId, dir));
- //if(dir == NONE) cerr << "Debug: Ork " << orkId << " didn't move" << endl; //debug
- //else cerr << "Debug: Ork " << orkId << " moved " << dirName(dir) << " to " << newPos << endl; //debug
- }
- }
- void avoidCloserEnemies(const int& orkId, const Dir& dir){
- Pos newPos = unit(orkId).pos + dir;
- vector<Unit> enemies = enemiesCloserThanWithMoreHealth(orkId,2);
- if(not enemies.empty()){
- //cerr << "Debug: Ork " << orkId << " has enemies with more health close" << endl;
- //cerr << "has enemies closer" << endl;
- set<Dir> dirToGo = {TOP,BOTTOM,RIGHT,LEFT};
- for (int i = 0; i < (int)enemies.size(); i++) {
- Pos enemyPos = enemies[i].pos;
- if(enemies[i].health >= unit(orkId).health){
- if(newPos == (enemyPos + BOTTOM)) dirToGo.erase(TOP);
- if(newPos == (enemyPos + LEFT)) dirToGo.erase(RIGHT);
- if(newPos == (enemyPos + TOP)) dirToGo.erase(BOTTOM);
- if(newPos == (enemyPos + RIGHT)) dirToGo.erase(LEFT);
- if(newPos == enemyPos) dirToGo.erase(dir);
- }
- }
- if(find(dirToGo.begin(), dirToGo.end(), dir) == dirToGo.end()){
- auto it = dirToGo.begin();
- advance(it,random(0, dirToGo.size()-1));
- //cerr << "Debug: Ork " << orkId << " dogged an enemy going to " << dirName(*it) << endl;
- move2(orkId, *it,0);
- orkBrain[orkId].target.type = T_NONE;
- }
- /*
- if(dirToGo.empty()){
- cerr << "Debug: Ork " << orkId << " is traped but will continue walking" << endl; //debug
- }else{
- set<Dir> safeDirToGo(dirToGo);
- for (auto it = safeDirToGo.begin(); it != safeDirToGo.end(); ++it) {
- if(not isSafe(unit(orkId).pos + *it)) safeDirToGo.erase(it);
- }
- if(safeDirToGo.empty()){
- cerr << "Debug: Ork " << orkId << " can't go to any safe cell" << endl; //debug
- auto it = dirToGo.begin();
- advance(it,random(0, dirToGo.size()-1));
- move2(orkId, *it,0);
- orkBrain[orkId].target.type = T_NONE;
- }else{
- if(find(safeDirToGo.begin(), safeDirToGo.end(), dir) == safeDirToGo.end()){
- auto it = safeDirToGo.begin();
- advance(it,random(0, safeDirToGo.size()-1));
- move2(orkId, *it,0);
- orkBrain[orkId].target.type = T_NONE;
- }
- }
- }*/
- }
- }
- void getTerrainInfo() {
- for (int i = 0; i < nb_cities(); i++) {
- cities[i] = createCity(city(i), i);
- }
- pair< pair<int,int>, vector<Pos> > p;
- for (int i = 0; i < nb_paths(); i++) {
- p = path(i);
- cities[p.first.first].nearCity.push_back(p.first.second);
- cities[p.first.first].path.push_back(i);
- cities[p.first.second].nearCity.push_back(p.first.first);
- cities[p.first.second].path.push_back(i);
- paths[i] = createPath(p,i);
- cities[p.first.first].pathBegin[i].first = p.second[0] + paths[i].beginDir;
- cities[p.first.first].pathBegin[i].second = opositeDir(paths[i].beginDir);
- cities[p.first.second].pathBegin[i].first = p.second[(int)p.second.size() -1] + paths[i].endDir;
- cities[p.first.second].pathBegin[i].second = opositeDir(paths[i].endDir);
- //cerr << "Debug: " << p.second[0] << "+" << paths[i].beginDir << "=" << cities[p.first.first].pathBegin[i].first << endl;
- //cerr << "Debug: City " << p.first.first << " connected to path " << i << " pos=" << cities[p.first.first].pathBegin[i].first << " dir=" << dirName(cities[p.first.first].pathBegin[i].second) << endl;
- //cerr << "Debug: " << p.second[(int)p.second.size() -1] << "+" << paths[i].endDir << "=" << cities[p.first.second].pathBegin[i].first << endl;
- //cerr << "Debug: City " << p.first.second << " connected to path " << i << " pos=" << cities[p.first.second].pathBegin[i].first << " dir=" << dirName(cities[p.first.second].pathBegin[i].second) << endl;
- }
- }
- void say(const vector<int>& v){
- cerr << "{ ";
- for (int i = 0; i < (int)v.size(); i++) {
- cerr << "(id=" << v[i] << " pos=" << unit(v[i]).pos << " hp=" << unit(v[i]).health << " target={type=" << orkBrain[v[i]].target.type << " pos=" << targetPos(orkBrain[v[i]].target) << " id=" << orkBrain[v[i]].target.id << " isCity=" << targetIsACity(v[i]) << " isPath=" << targetIsAPath(v[i]) << "})";
- }
- cerr << "}" << endl;
- }
- bool isNotMyOrk(const int& orkId){
- auto myOrks = orks(me());
- return orkId>=0 and find(myOrks.begin(), myOrks.end(), orkId) == myOrks.end();
- }
- bool isMyOrk(const int& orkId){
- auto myOrks = orks(me());
- return orkId>=0 and find(myOrks.begin(), myOrks.end(), orkId) != myOrks.end();
- }
- void findEnemies(const int& orkId, const int& stepsAway){
- orkBrain[orkId].enemyAtStepsAway.clear();
- orkBrain[orkId].enemyAtStepsAway.resize(stepsAway + 1);
- //cerr << "Debug : Finding enemies closer than " << stepsAway << " from ork " << orkId << endl;
- for (int i = -stepsAway; i < stepsAway; i++) {
- for (int j = -stepsAway; j < stepsAway; j++) {
- Pos p(i,j);
- Pos enemyPos = p + unit(orkId).pos;
- if(pos_ok(enemyPos) and distanceLength(p) <= stepsAway){
- int enemyId = cell(enemyPos).unit_id;
- if(isNotMyOrk(enemyId)){ //if has a ork and is not mine
- orkBrain[orkId].enemyAtStepsAway[distanceLength(p)].push_back(unit(enemyId));
- //cerr << "Debug: Found one enemy at " << enemyPos << " with id=" << enemyId << " and " << distanceLength(p) << " steps away in direction " << p << endl;
- }
- }
- //cerr << "Debug: Not found enemy at " << enemyPos << " in " << distanceLength(p) << " steps away in direction " << p << " with pos_ok=" << pos_ok(enemyPos) << " and enemyId=" << cell(enemyPos).unit_id << " notMine=" << isNotMyOrk(cell(enemyPos).unit_id) << endl;
- }
- }
- }
- vector<Unit> enemiesCloserThanWithMoreHealth(const int& orkId, const int& stepsAway){
- vector<Unit> p(0);
- vector< vector<Unit> > enemies = orkBrain[orkId].enemyAtStepsAway;
- for (int i=1; i < stepsAway; i++) {
- for(int j=0; j<(int)enemies[i].size(); j++){
- if(enemies[i][j].health >= unit(orkId).health) {
- p.push_back(enemies[i][j]);
- //cerr << "Debug: Ork " << orkId << " has enemy " << enemies[i].second[i].id << " at " << i << " steps away, with less health" << endl;
- }
- }
- }
- return p;
- }
- vector<Unit> enemiesCloserThanWithLessHealth(const int& orkId, const int& stepsAway){
- vector<Unit> p(0);
- vector< vector<Unit> > enemies = orkBrain[orkId].enemyAtStepsAway;
- for (int i=1; i < stepsAway; i++) {
- for(int j=0; j<(int)enemies[i].size(); j++){
- if(enemies[i][j].health < unit(orkId).health) {
- p.push_back(enemies[i][j]);
- //cerr << "Debug: Ork " << orkId << " has enemy " << enemies[i].second[i].id << " at " << i << " steps away, with less health" << endl;
- }
- }
- }
- return p;
- }
- void updateOrksMine(){
- for(int i = 0; i < (int)cities.size(); ++i) cities[i].orksMine.clear();
- for(int i = 0; i < (int)paths.size(); ++i) paths[i].orksMine.clear();
- for (int i = 0; i < (int) orks(me()).size(); i++) {
- int orkId = orks(me())[i];
- if (isInACity(orkId)) cities[currentCity(orkId)].orksMine.insert(orkId);
- if (isInAPath(orkId)) paths[currentPath(orkId)].orksMine.insert(orkId);
- }
- }
- void deleteDeadOrks(){
- auto it = orkBrain.begin();
- while(it != orkBrain.end()){
- if(isNotMyOrk(it->first)){
- for(int i = 0; i < (int)cities.size(); ++i) {
- cities[i].orksMine.erase(it->first);
- }
- for(int i = 0; i < (int)paths.size(); ++i) {
- paths[i].orksMine.erase(it->first);
- }
- //cerr << "Debug: Ork " << it->first << " died" << endl;
- it = orkBrain.erase(it);
- }else ++it;
- }
- }
- void updateOrksAlive(){
- set<int> deadOrks(aliveOrks);
- aliveOrks.clear();
- for (int playerId = 0; playerId < nb_players(); playerId++) {
- for (int i = 0; i < (int)orks(playerId).size(); i++) {
- aliveOrks.insert(orks(playerId)[i]);
- deadOrks.erase(orks(playerId)[i]);
- }
- }
- for (auto it = deadOrks.begin(); it != deadOrks.end(); ++it) {
- //cerr << "Debug: Enemy ork " << *it << " died" << endl;
- for (auto it2 = orkBrain.begin(); it2 != orkBrain.end(); it2++) {
- if((it2->second).target.type == T_ENEMY and (it2->second).target.id == (*it)){
- //cerr << "Debug: Ork " << it2->first << " was following enemy ork " << *it << " but now he's dead" << endl;
- (it2->second).target.type = T_NONE;
- (it2->second).target.id = -1;
- (it2->second).target.pos = Pos(0,0);
- }
- }
- }
- }
- void updateVariables(){
- deleteDeadOrks();
- updateOrksAlive();
- orksPerCityAndPath = max((nb_cities() + nb_paths()) / max((int)orks(me()).size(),1),2) ; //TODO implement
- updateOrksMine();
- for (int i = 0; i < (int) orks(me()).size(); i++){
- int orkId = orks(me())[i];
- findEnemies(orkId,5);
- if(orkBrain[orkId].target.type == T_ENEMY){
- if(isNotMyOrk(orkBrain[orkId].target.id)){
- orkBrain[orkId].target.pos = unit(orkBrain[orkId].target.id).pos;
- }else{
- orkBrain[orkId].target.type = T_NONE;
- orkBrain[orkId].target.id = -1;
- orkBrain[orkId].target.pos = Pos(35,35);
- //cerr << "Debug: ork followed died -----------------------------------------" << endl;
- }
- }
- }
- }
- void setTargetClosestSafeCell(const int& orkId){ //normally from a non safe cell
- vector<Pos> closestSafeCells;
- int closestSafeCellsIsStepsAway = cols() + rows() + 1;
- for(auto cit : cities){
- for(auto pos : cit.positions){
- int dist = distanceLength(distance(unit(orkId).pos,pos));
- if(dist < closestSafeCellsIsStepsAway){
- closestSafeCellsIsStepsAway = dist;
- closestSafeCells.clear();
- closestSafeCells.push_back(pos);
- }else{
- if(dist == closestSafeCellsIsStepsAway){
- closestSafeCells.push_back(pos);
- }
- }
- }
- }
- for(auto pa : paths){
- for(auto pos : pa.positions){
- int dist = distanceLength(distance(unit(orkId).pos,pos));
- if(dist < closestSafeCellsIsStepsAway){
- closestSafeCellsIsStepsAway = dist;
- closestSafeCells.clear();
- closestSafeCells.push_back(pos);
- }else{
- if(dist == closestSafeCellsIsStepsAway){
- closestSafeCells.push_back(pos);
- }
- }
- }
- }
- Pos randomClosestSafeCell = closestSafeCells[random(0, (int)closestSafeCells.size()-1)];
- if (cell(randomClosestSafeCell).type == CITY) {
- orkBrain[orkId].target.id = cell(randomClosestSafeCell).city_id;
- orkBrain[orkId].target.type = T_CITY;
- orkBrain[orkId].target.pos = randomClosestSafeCell;
- }else{
- orkBrain[orkId].target.id = cell(randomClosestSafeCell).path_id;
- orkBrain[orkId].target.type = T_PATH;
- orkBrain[orkId].target.pos = randomClosestSafeCell;
- }
- // cerr << "Debug: Ork " << orkId << " closest safe cells are: ";
- // for (int i = 0; i < (int)closestSafeCells.size(); i++) {
- // cerr << "(type=" << cell(closestSafeCells[i]).type << " pos=" << targetPos(orkBrain[orkId].target) << " idC=" << cell(closestSafeCells[i]).city_id << " idP=" << cell(closestSafeCells[i]).path_id << ") " ;
- // }
- // cerr << endl;
- // cerr << "Debug: Ork " << orkId << " decided to go to the cell " << randomClosestSafeCell << " because is one of the closest safe cells" << endl; //debug
- }
- void setTarget(const int& orkId, const targetType& type, const int& id, const Pos& pos){
- orkBrain[orkId].target.type = type;
- orkBrain[orkId].target.id = id;
- orkBrain[orkId].target.pos = pos;
- }
- void setTargetCenter(const int& orkId){
- orkBrain[orkId].target.type = T_CELL;
- orkBrain[orkId].target.id = -1;
- orkBrain[orkId].target.pos = Pos(30,30);
- }
- void decideCityOrPathToGo(const int& orkId){ //normaly from a safe cell, chose where to go //TODO if a near city dosen't have any coming and is from other team a go there fast
- if (isInACity(orkId)) {
- CityInfo city = cities[currentCity(orkId)];
- int currentCityOrks = city.orksMine.size() ;
- for (int i=0; i < (int) city.path.size(); i++) {
- int pathId = city.path[i];
- int targetPathOrks = paths[pathId].orksMine.size();
- if( me() != path_owner(pathId) or (targetPathOrks < (currentCityOrks-1))){
- orkBrain[orkId].target.type = T_PATH;
- orkBrain[orkId].target.id = pathId;
- orkBrain[orkId].target.pos = city.pathBegin[pathId].first + city.pathBegin[pathId].second;
- //cerr << "Debug: Ork " << orkId << " in city " << currentCity(orkId) << " decided to go to path " << pathId << endl;
- return;
- }
- //cerr << "Debug: Ork " << orkId << " in city " << currentCity(orkId) << " won't go the path " << pathId << endl;
- }
- //cerr << "Debug: Ork " << orkId << " in city " << currentCity(orkId) << " decided to stay" << endl;
- }else{
- int currentPathOrks = paths[currentPath(orkId)].orksMine.size() ;
- int cityBegin = paths[currentPath(orkId)].cityBegin;
- int cityEnd = paths[currentPath(orkId)].cityEnd;
- vector<int> ci(2,cityBegin);
- ci[1]=cityEnd;
- for (int i=0; i < (int) ci.size(); i++){
- if ( (int)cities[ci[i]].orksMine.size() < (currentPathOrks-1) or city_owner(ci[i])!=me()) {
- orkBrain[orkId].target.type = T_CITY;
- orkBrain[orkId].target.id = ci[i];
- orkBrain[orkId].target.pos = cities[ci[i]].pathBegin[currentPath(orkId)].first;
- //cerr << "Debug: Ork " << orkId << " in path " << currentPath(orkId) << " decided to go to city " << ci[i] << " because it has " << currentPathOrks - (int)cities[ci[i]].orksMine.size() << " orks less than his path" << endl;
- return;
- }
- }
- //if (currentPathOrks>orksPerCityAndPath) setTargetCenter(orkId);
- }
- }
- void improvePositionInCityOrPath(const int& orkId){ //TODO add interaction with enemies
- Pos pos = unit(orkId).pos;
- if (isInACity(orkId)) { //if it's in a city
- //cerr << "Debug: Ork " << orkId << " at " << pos << " is improving his position by going to the center " << cities[currentCity(orkId)].posCenter << " of the city " << currentCity(orkId) << endl; //debug
- move(orkId,dominantDir( distance( pos, cities[currentCity(orkId)].posCenter)));
- } else if(isInAPath(orkId)){ //if it's in a path
- int orksBeforeInPath = 0;
- int orkIndex = 0;
- PathInfo path = paths[currentPath(orkId)];
- for (int i = 0; i < path.length and cell(path.positions[i]).unit_id != orkId ; i++) {
- if(isMyOrk(cell(path.positions[i]).unit_id)) ++orksBeforeInPath;
- ++orkIndex;
- }
- int segment = path.length / ((int) path.orksMine.size() +1);
- int pathIndex = segment * orksBeforeInPath;
- Dir d = NONE;
- if(orkIndex<pathIndex){
- d = dominantDir( distance( pos, path.positions[orkIndex+1]));
- }else if(orkIndex>pathIndex){
- d = dominantDir( distance( pos, path.positions[orkIndex-1]));
- }
- //cerr << "Debug: Ork " << orkId << " at " << pos << " is improving his position by going " << dirName(d) << " to " << pos+d << ",that is the " << pathIndex << "/" << path.length << " cell of the path " << currentPath(orkId) << " because he is the " << orksBeforeInPath << "th ork, and each of the " << path.orksMine.size() << " orks is " << segment << " steps away" << endl; //debug
- move(orkId,d);
- }
- }
- void advanceTowardsCityOrPathToGo(const int& orkId){
- Pos pos = unit(orkId).pos;
- int targetId = orkBrain[orkId].target.id;
- if (isInACity(orkId)) {//if in a city going to path
- Pos pathBeginPos = cities[currentCity(orkId)].pathBegin[targetId].first;
- Dir pathBeginDir = cities[currentCity(orkId)].pathBegin[targetId].second;
- //cerr << "Debug: Ork " << orkId << " is going to path " << targetId << " begin at " << pathBeginPos << " to " << dirName(pathBeginDir) << endl;
- if(pos == pathBeginPos){//if is next to the path
- move(orkId, pathBeginDir);
- }else {//if is in the city
- move(orkId,dominantDir(distance(pos,pathBeginPos)));
- }
- } else{
- PathInfo path = paths[currentPath(orkId)];
- auto it = find(path.positions.begin(), path.positions.end(), pos);
- if (targetId == path.cityEnd) {
- if(pos == path.positions[path.length - 1]) {
- move(orkId,path.endDir);
- }else{
- move(orkId,dominantDir( distance( pos, *(++it) )));
- }
- }else{
- if(pos == path.positions[0]) {
- move(orkId,path.beginDir);
- }else {
- move(orkId,dominantDir( distance( pos, *(--it) )));
- }
- }
- }
- }
- bool followed(const int& enemyId){
- for (auto it = orkBrain.begin(); it != orkBrain.end(); it++) {
- if((it->second.target.type == T_ENEMY) and (it->second.target.id == enemyId)) return true;
- }
- return false;
- }
- void setTargetClosestEnemyWithLessHealth(const int& orkId, const int& stepsAway){
- vector< vector<Unit> > enemies = orkBrain[orkId].enemyAtStepsAway;
- for (int i = 1; i < stepsAway; i++) {
- for (int j = 0; j < (int)enemies[i].size(); j++) {
- if (enemies[i][j].health < unit(orkId).health and (not followed(enemies[i][j].id))) {
- orkBrain[orkId].target.type = T_ENEMY;
- orkBrain[orkId].target.id = enemies[i][j].id;
- orkBrain[orkId].target.pos = enemies[i][j].pos;
- return;
- }
- }
- }
- }
- void setTargetClosestEnemyWithLessHealthAndInASafeCell(const int& orkId, const int& stepsAway){
- vector< vector<Unit> > enemies = orkBrain[orkId].enemyAtStepsAway;
- for (int i = 1; i < stepsAway; i++) {
- for (int j = 0; j < (int)enemies[i].size(); j++) {
- if (enemies[i][j].health < unit(orkId).health and isSafe(enemies[i][j].pos) and (not followed(enemies[i][j].id))) {
- orkBrain[orkId].target.type = T_ENEMY;
- orkBrain[orkId].target.id = enemies[i][j].id;
- orkBrain[orkId].target.pos = enemies[i][j].pos;
- return;
- }
- }
- }
- }
- bool isInTarget(const int& orkId){
- return orkBrain[orkId].target.pos == unit(orkId).pos;
- }
- void goStraightLineToTarget(const int& orkId){
- //cerr << "Debug: Ork " << orkId << " at " << unit(orkId).pos << " is going in a straight line to the target, which is at " << targetPos(orkBrain[orkId].target) << endl; //debug
- move(orkId,dominantDir( distance( unit(orkId).pos, targetPos(orkBrain[orkId].target))));
- }
- /**
- * Play method, invoked once per each round.
- */
- virtual void play () {
- //cerr << "Player " << me() << " has " << orks(me()).size() <<" orks in round " << round() << endl;
- //cerr << "Debug: Player " << me() << " orks: " << endl; //debug
- //say(orks(me())); //debug
- if (round() == 0) {
- cities.resize(nb_cities());
- paths.resize(nb_paths());
- getTerrainInfo();
- }
- updateVariables();
- //cerr << "Debug: variables updated" << endl; //debug
- for (int i = 0; i < (int) orks(me()).size(); i++) { //for each of my orks
- int orkId = orks(me())[i];
- //if(isInTarget(orkId)) cerr << "Debug: Ork " << orkId << " is in target " << orkBrain[orkId].target.pos << endl;
- if(orkBrain[orkId].target.type == T_NONE){ //if ork's first round
- //cerr << "Debug: Ork " << orkId << " is lost in position " << unit(orkId).pos << endl; //debug
- setTargetClosestSafeCell(orkId);
- }
- if(isSafe(orkId)){
- setTargetClosestEnemyWithLessHealthAndInASafeCell(orkId,5);
- }else{
- setTargetClosestEnemyWithLessHealth(orkId,2);
- }
- if(orkBrain[orkId].target.type == T_ENEMY){
- goStraightLineToTarget(orkId);
- }
- if(targetIsACity(orkId) or targetIsAPath(orkId) or targetIsACell(orkId)){
- if (isSafe(orkId)) {
- decideCityOrPathToGo(orkId);
- if (isInTarget(orkId)) {
- improvePositionInCityOrPath(orkId);
- }else{
- advanceTowardsCityOrPathToGo(orkId);
- }
- }else{
- //cerr << "Debug: Ork " << orkId << " is not safe" << endl;
- goStraightLineToTarget(orkId);
- }
- }
- //cerr << endl;
- }
- }
- };
- /**
- * Do not modify the following line.
- */
- RegisterPlayer(PLAYER_NAME);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement