Created
December 5, 2011 22:58
-
-
Save hc5/1435803 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include "goonMicro.h" | |
| #include <string> | |
| #include <windows.h> | |
| #include <time.h> | |
| #include <iostream> | |
| #include <fstream> | |
| #define RETREAT_HP -14 | |
| #define RETREAT_DIST 150 | |
| #define RETREAT_MIN_SP 2.0 | |
| #define LENGTH 5000 | |
| using namespace BWAPI; | |
| static int CLOSEST_DISTANCE =145; | |
| static int MIN_HP =89; | |
| static int MIN_VISIBLE = 3; | |
| static int MOST_TARGETTED =2; | |
| static int CANCEL_FRAME= 23; | |
| static bool finishedFormation = false; | |
| static int restarted; | |
| static int populated = 0; | |
| struct Traits { | |
| int closest_distance; | |
| int min_hp; | |
| int most_targetted; | |
| int cancelFrame; | |
| } traits [LENGTH]; | |
| int currentTrait; | |
| void goonMicro::onStart() | |
| { | |
| FILE *pop=NULL; | |
| pop = fopen("pop.txt","r"); | |
| if(pop!=NULL){ | |
| for(int i =0;i<LENGTH;i++){ | |
| fscanf(pop,"%d",&(traits[i].closest_distance)); | |
| fscanf(pop,"%d",&(traits[i].min_hp)); | |
| fscanf(pop,"%d",&(traits[i].most_targetted)); | |
| fscanf(pop,"%d",&(traits[i].cancelFrame)); | |
| } | |
| //populated = 1; | |
| fclose(pop); | |
| } | |
| //srand((unsigned)time(0)); | |
| currentTrait = rand()%LENGTH; | |
| restarted = 0; | |
| if(populated == 1){ | |
| CLOSEST_DISTANCE = traits[currentTrait].closest_distance; | |
| MIN_HP = traits[currentTrait].min_hp; | |
| MOST_TARGETTED = traits[currentTrait].most_targetted; | |
| CANCEL_FRAME = traits[currentTrait].cancelFrame; | |
| } | |
| // Enable some cheat flags | |
| Broodwar->enableFlag(Flag::UserInput); | |
| // Uncomment to enable complete map information | |
| // Broodwar->enableFlag(Flag::CompleteMapInformation); | |
| hppos = 0; | |
| movepos = 0; | |
| nFrame = 0; | |
| Broodwar->setLocalSpeed(0); | |
| } | |
| void bubbleSort(int num[12]) | |
| { | |
| int i, j, flag = 1; // set flag to 1 to start first pass | |
| int temp; // holding variable | |
| int numLength = 12; | |
| for(i = 1; (i <= numLength) && flag; i++) | |
| { | |
| flag = 0; | |
| for (j=0; j < (numLength -1); j++) | |
| { | |
| if (num[j+1] > num[j]) // ascending order simply changes to < | |
| { | |
| temp = num[j]; // swap elements | |
| num[j] = num[j+1]; | |
| num[j+1] = temp; | |
| flag = 1; // indicates that a swap occurred. | |
| } | |
| } | |
| } | |
| return; //arrays are passed to functions by address; nothing is returned | |
| } | |
| int find(int a[],int n){ | |
| for(int i =0;i<12;i++) | |
| if(a[i]==n) | |
| return i; | |
| return 0; | |
| } | |
| void goonMicro::getCols(){ | |
| //get a list of all the X values | |
| int Xs[12]; | |
| int j = 0; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()){ | |
| Xs[j] = (*i)->getPosition().x(); | |
| j++; | |
| } | |
| //sort them | |
| bubbleSort(Xs); | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()){ | |
| int x = (*i)->getPosition().x(); | |
| //find the x in the array | |
| switch((int)floor(find(Xs,x)/3.0)){ | |
| case 0: col1.insert(*i); | |
| break; | |
| case 1:col2.insert(*i); | |
| break; | |
| case 2:col3.insert(*i); | |
| break; | |
| case 3:col4.insert(*i); | |
| break; | |
| } | |
| } | |
| int col1X = 0; | |
| int col2X = 0; | |
| int col3X = 0; | |
| int col4X = 0; | |
| for(std::set<Unit*>::iterator i=col1.begin();i!=col1.end();i++) | |
| col1X+=(*i)->getPosition().x(); | |
| for(std::set<Unit*>::iterator i=col2.begin();i!=col2.end();i++) | |
| col2X+=(*i)->getPosition().x(); | |
| for(std::set<Unit*>::iterator i=col3.begin();i!=col3.end();i++) | |
| col3X+=(*i)->getPosition().x(); | |
| for(std::set<Unit*>::iterator i=col4.begin();i!=col4.end();i++) | |
| col4X+=(*i)->getPosition().x(); | |
| col1X/=3; | |
| col2X/=3; | |
| col3X/=3; | |
| col4X/=3; | |
| for(std::set<Unit*>::iterator i=col1.begin();i!=col1.end();i++) | |
| move((*i),col1X,(*i)->getPosition().y()); | |
| for(std::set<Unit*>::iterator i=col2.begin();i!=col2.end();i++) | |
| move((*i),col2X,(*i)->getPosition().y()); | |
| for(std::set<Unit*>::iterator i=col3.begin();i!=col3.end();i++) | |
| move((*i),col3X,(*i)->getPosition().y()); | |
| for(std::set<Unit*>::iterator i=col4.begin();i!=col4.end();i++) | |
| move((*i),col4X,(*i)->getPosition().y()); | |
| } | |
| int goonMicro::inBetween(int x, int y){ | |
| return nFrame>=x&&nFrame<=y; | |
| } | |
| void goonMicro::formCircle(){ | |
| if(nFrame/2==1) | |
| getCols(); | |
| if(inBetween(5,33)){ | |
| moveForward(11,col1); | |
| } | |
| if(inBetween(15,53)){ | |
| moveForward(-12,col2); | |
| } | |
| if(inBetween(25,60)){ | |
| moveForward(11,col3); | |
| } | |
| if(inBetween(35,78)){ | |
| moveForward(-12,col4); | |
| } | |
| if(inBetween(80,100)){ | |
| straighten(); | |
| } | |
| if(nFrame > 1&&nFrame<130){ | |
| if(nFrame %30==0){ | |
| stopAll(); | |
| } | |
| //singleFile(); | |
| } | |
| if(nFrame==101||nFrame==102){ | |
| pack(); | |
| } | |
| if(nFrame>125&&(!firstShot()||nFrame<250)){ | |
| //Broodwar->printf("moving forward!"); | |
| moveForward(0); | |
| } | |
| } | |
| void goonMicro::formArc(){ | |
| if(opCenter->x()==0||opCenter->y()==0){ | |
| return; | |
| } | |
| if(Broodwar->enemy()->getUnits().size()>=4||nFrame>390){ | |
| finishedFormation=true; | |
| return; | |
| } | |
| //add the force fields to shape the group | |
| forceFields.insert(std::make_pair(opCenter,0));//first force field is the primary one coming from the opponent | |
| forceFields.find(opCenter)->second=320-nFrame/10; | |
| //calculate the position of the second force field, which is within the group and pushes the dragoons | |
| //at the back forward | |
| //find the back most 2 dragoons | |
| int distances[12]; | |
| int j = 0; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++){ | |
| distances[j]=(*i)->getDistance(*opCenter); | |
| j++; | |
| } | |
| bubbleSort(distances); | |
| Unit *one=NULL; | |
| Unit *two=NULL; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++){ | |
| if(find(distances,(*i)->getDistance(*opCenter))==0) | |
| one = (*i); | |
| if(find(distances,(*i)->getDistance(*opCenter))==1) | |
| two = (*i); | |
| } | |
| //get coordinates of the force field | |
| if(one!=NULL&&two!=NULL){ | |
| int fx = (one->getPosition().x()+two->getPosition().x())/2; | |
| int fy = (one->getPosition().y()+two->getPosition().y())/2; | |
| int fx1 = one->getPosition().x(); | |
| int fy1 = one->getPosition().y(); | |
| int fx2 = two->getPosition().x(); | |
| int fy2 = two->getPosition().y(); | |
| Position *field = new Position(fx,fy); | |
| double dist = 0+nFrame/10; | |
| double dir; | |
| int dist_x, dist_y; | |
| Position delta = *field - *opCenter; | |
| if (delta.y()) | |
| { | |
| dir = atan(1.0 * delta.y() / delta.x()); | |
| dist_x = (int) (dist * (delta.x() > 0 ? 1.0 : -1.0) * abs(cos(dir))); | |
| dist_y = (int) (dist * (delta.y() > 0 ? 1.0 : -1.0) * abs(sin(dir))); | |
| } | |
| else | |
| { | |
| dist_x = (int) (dist * (delta.x() > 0 ? 1.0 : -1.0)); | |
| dist_y = 0; | |
| } | |
| Position destination = *field + Position(dist_x,dist_y); | |
| //Position *field1 = new Position(fx1,fy1); | |
| //Position *field2 = new Position(fx2,fy2); | |
| //add the force field | |
| forceFields.insert(std::make_pair(&destination,0)); | |
| forceFields.find(&destination)->second=nFrame/1.0; | |
| // forceFields.insert(std::make_pair(field1,0)); | |
| //forceFields.find(field1)->second=50; | |
| //forceFields.insert(std::make_pair(field2,0)); | |
| //forceFields.find(field2)->second=50; | |
| } | |
| //make sure the goons move away from the force fields | |
| for(std::map<Position*, int>::iterator p=forceFields.begin();p!=forceFields.end();p++){ | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++){ | |
| if((*i)->getDistance(*(p->first))<=p->second){ | |
| //Broodwar->printf("moving back!"); | |
| //if(p->first==opCenter) | |
| //moveBackFrom((*i),*(p->first),60); | |
| //else | |
| if(find(distances,(*i)->getDistance(*opCenter))<6&&p->first!=opCenter) | |
| moveBackFrom((*i),*(p->first),30); | |
| if(find(distances,(*i)->getDistance(*opCenter))>=6&&p->first==opCenter) | |
| moveBackFrom((*i),*(p->first),30); | |
| } | |
| } | |
| } | |
| //draw the force fields | |
| for(std::map<Position*, int>::iterator p=forceFields.begin();p!=forceFields.end();p++){ | |
| Broodwar->drawCircleMap((p->first)->x(),(p->first)->y(),p->second,BWAPI::Colors::Red,false); | |
| } | |
| //clear the force fields | |
| forceFields.clear(); | |
| } | |
| void goonMicro::onFrame() | |
| { | |
| nFrame++; // increment the frame counter | |
| if(((myUnits.size()==0||Broodwar->enemy()->getUnits().size()==0)&&nFrame>400)||nFrame>5000){ | |
| restart(); | |
| } | |
| myUnits = Broodwar->self()->getUnits(); | |
| //checkFormation(); | |
| drawStats(); | |
| drawStates(); | |
| if(nFrame%2==0){ | |
| //Broodwar->restartGame(); | |
| if(!firstShot()){ | |
| formCircle(); | |
| } | |
| if(firstShot()&&!finishedFormation){ | |
| formArc(); | |
| } | |
| if(firstShot()&&finishedFormation){ | |
| tagWounded(); | |
| retreatWounded(); | |
| } | |
| } | |
| opCenter = new Position(0,0); | |
| } | |
| void goonMicro::enclose(){ | |
| int x=0; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++){ | |
| x+=(*i)->getPosition().x(); | |
| } | |
| int y=0; | |
| x/=12; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++){ | |
| y+=(*i)->getPosition().y(); | |
| } | |
| y/=12; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| move((*i),x,y); | |
| } | |
| void goonMicro::pack(){ | |
| int minY=99999; | |
| int maxY=-99999; | |
| //find the center of the group&&radius | |
| int x=0; | |
| int y =0; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++){ | |
| if((*i)->getPosition().y()<minY) | |
| minY=(*i)->getPosition().y(); | |
| if((*i)->getPosition().y()>maxY) | |
| maxY=(*i)->getPosition().y(); | |
| if((*i)->getPosition().y()<minY) | |
| minY=(*i)->getPosition().y(); | |
| if((*i)->getPosition().y()>maxY) | |
| maxY=(*i)->getPosition().y(); | |
| x+=(*i)->getPosition().x(); | |
| y+=(*i)->getPosition().y(); | |
| } | |
| x/=12; | |
| y/=12; | |
| //draw the circle | |
| int centerX = x; | |
| int centerY = y; | |
| int radius = (maxY-minY)/2+1; | |
| Broodwar->printf("%d %d %d",x,y,radius); | |
| for(std::set<Unit*>::iterator i=col1.begin();i!=col1.end();i++) | |
| move((*i),sqrt(abs(radius*radius-pow(((*i)->getPosition().y()-centerY)*1.0,2)))+centerX,(*i)->getPosition().y()); | |
| for(std::set<Unit*>::iterator i=col2.begin();i!=col2.end();i++) | |
| move((*i),sqrt(abs(radius*radius-pow(((*i)->getPosition().y()-centerY)*1.0,2)))+centerX,(*i)->getPosition().y()); | |
| for(std::set<Unit*>::iterator i=col3.begin();i!=col3.end();i++) | |
| move((*i),0-sqrt(abs(radius*radius-pow(((*i)->getPosition().y()-centerY)*1.0,2)))+centerX,(*i)->getPosition().y()); | |
| for(std::set<Unit*>::iterator i=col4.begin();i!=col4.end();i++) | |
| move((*i),0-sqrt(abs(radius*radius-pow(((*i)->getPosition().y()-centerY)*1.0,2)))+centerX,(*i)->getPosition().y()); | |
| } | |
| void goonMicro::straighten(){ | |
| std::set<Unit*> rows[6]; | |
| int Ys[12]; | |
| int j = 0; | |
| int minY = 99999; | |
| int maxY=-99999; | |
| //get the list of Y coords as well as max and min Y | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()){ | |
| Ys[j] = (*i)->getPosition().y(); | |
| if(Ys[j]<minY) | |
| minY=Ys[j]; | |
| if(Ys[j]>maxY) | |
| maxY=Ys[j]; | |
| j++; | |
| } | |
| //sort them | |
| bubbleSort(Ys); | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()){ | |
| //find the Y coord in the array | |
| rows[find(Ys,(*i)->getPosition().y())/2].insert(*i); | |
| } | |
| //order the rows | |
| for(int k = 0;k<6;k++){ | |
| for(std::set<Unit*>::iterator i=rows[k].begin();i!=rows[k].end();i++) | |
| if(!(*i)->getType().isBuilding()){ | |
| move((*i),(*i)->getPosition().x(),minY+34*(5-k)); | |
| } | |
| } | |
| } | |
| void goonMicro::remove(int n){ | |
| for(int i = 0;i<n;i++){ | |
| srand((unsigned)time(0)); | |
| for(int c = 0;c<LENGTH;c++){ | |
| if( traits[c].closest_distance==traits[currentTrait].closest_distance&& | |
| traits[c].min_hp==traits[currentTrait].min_hp&& | |
| traits[c].most_targetted==traits[currentTrait].most_targetted&& | |
| traits[currentTrait].cancelFrame==traits[c].cancelFrame){ | |
| int n = rand()%LENGTH; | |
| traits[c].closest_distance=traits[n].closest_distance; | |
| traits[c].min_hp=traits[n].min_hp; | |
| traits[c].most_targetted=traits[n].most_targetted; | |
| traits[c].cancelFrame=traits[n].cancelFrame; | |
| //traits[c].cancelFrame=0; | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| void goonMicro::restart(){ | |
| int totalHP = 0; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()) | |
| totalHP += ((*i)->getHitPoints()+(*i)->getShields())>>8; | |
| FILE *f; | |
| f=fopen("log1.txt","a"); | |
| if(restarted==0){ | |
| if(populated==1){ | |
| srand((unsigned)time(0)); | |
| int children[10]; | |
| int numChildren = (myUnits.size()-7)*10; | |
| if(numChildren<0)numChildren =0; | |
| for(int i =0;i<numChildren;i++) { | |
| int c = rand()%LENGTH; | |
| traits[c].closest_distance=traits[currentTrait].closest_distance; | |
| traits[c].min_hp=traits[currentTrait].min_hp; | |
| traits[c].most_targetted=traits[currentTrait].most_targetted; | |
| traits[c].cancelFrame=traits[currentTrait].cancelFrame; | |
| } | |
| if(numChildren==0){//failed trait | |
| remove((7-myUnits.size())*3); | |
| } | |
| FILE *pop; | |
| pop=fopen("pop.txt","w"); | |
| for(int i =0;i<LENGTH;i++) | |
| fprintf(pop,"%d %d %d %d\n",traits[i].closest_distance,traits[i].min_hp,traits[i].most_targetted,traits[i].cancelFrame); | |
| fclose(pop); | |
| } | |
| fprintf(f,"%d %d %d\n",myUnits.size(),totalHP,myUnits.size()>0?1:0); | |
| restarted = 1; | |
| } | |
| fclose(f); | |
| /*INPUT input[10]; | |
| memset(input, 0, sizeof(input)); | |
| input[0].type = INPUT_KEYBOARD; | |
| input[0].ki.wVk = 0xA4; | |
| input[0].ki.dwFlags = 0; | |
| input[0].ki.time = 0; | |
| input[0].ki.dwExtraInfo = 0; | |
| //Sleep(50); | |
| input[1].type = INPUT_KEYBOARD; | |
| input[1].ki.wVk = 0x4D; // ASCI value of m | |
| input[1].ki.dwFlags = 0; | |
| input[1].ki.time = 0; | |
| input[1].ki.dwExtraInfo = 0; | |
| input[2].type= INPUT_KEYBOARD; | |
| input[2].ki.wVk = 0x4D; // ASCI value of m | |
| input[2].ki.dwFlags = KEYEVENTF_KEYUP; | |
| input[2].ki.time = 0; | |
| input[2].ki.dwExtraInfo = 0; | |
| input[3].type=INPUT_KEYBOARD; | |
| input[3].ki.wVk = 0xA4; | |
| input[3].ki.dwFlags = KEYEVENTF_KEYUP; | |
| input[3].ki.time = 0; | |
| input[3].ki.dwExtraInfo = 0; | |
| input[4].type = INPUT_KEYBOARD; | |
| input[4].ki.wVk = 0x45; // ASCI value of e | |
| input[4].ki.dwFlags = 0; | |
| input[4].ki.time = 0; | |
| input[4].ki.dwExtraInfo = 0; | |
| input[5].type= INPUT_KEYBOARD; | |
| input[5].ki.wVk = 0x45; // ASCI value of e | |
| input[5].ki.dwFlags = KEYEVENTF_KEYUP; | |
| input[5].ki.time = 0; | |
| input[5].ki.dwExtraInfo = 0; | |
| input[6].type = INPUT_KEYBOARD; | |
| input[6].ki.wVk = 0x52 ; // ASCI value of r | |
| input[6].ki.dwFlags = 0; | |
| input[6].ki.time = 0; | |
| input[6].ki.dwExtraInfo = 0; | |
| input[7].type= INPUT_KEYBOARD; | |
| input[7].ki.wVk = 0x52 ; // ASCI value of r | |
| input[7].ki.dwFlags = KEYEVENTF_KEYUP; | |
| input[7].ki.time = 0; | |
| input[7].ki.dwExtraInfo = 0; | |
| input[8].type = INPUT_KEYBOARD; | |
| input[8].ki.wVk = 0x52 ; // ASCI value of r | |
| input[8].ki.dwFlags = 0; | |
| input[8].ki.time = 0; | |
| input[8].ki.dwExtraInfo = 0; | |
| input[8].type= INPUT_KEYBOARD; | |
| input[9].ki.wVk = 0x52 ; // ASCI value of r | |
| input[9].ki.dwFlags = KEYEVENTF_KEYUP; | |
| input[9].ki.time = 0; | |
| input[9].ki.dwExtraInfo = 0; | |
| SendInput(10,input,sizeof(INPUT));*/ | |
| //SetForegroundWindow(temp); | |
| //restarted = 1; | |
| Broodwar->restartGame(); | |
| } | |
| void goonMicro::stopAll(){ | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()) | |
| (*i)->stop(); | |
| } | |
| void goonMicro::singleFile(){ | |
| // move into a row | |
| int currentY [6]; | |
| int X[2]; | |
| for(int i =0;i<6;i++){ | |
| currentY[i] = 1200-i*30; | |
| X[0] = 500; | |
| } | |
| for(int i =0;i<6;i++){ | |
| X[1] = 530; | |
| } | |
| int counter = 0; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()) | |
| { | |
| move((*i),X[counter/6],currentY[counter/2]); | |
| counter++; | |
| } | |
| } | |
| bool goonMicro::isStuck(Unit* u) | |
| { | |
| if (dpos.find(u) == dpos.end() || | |
| status.find(u) == status.end() || | |
| status[u].what != ORDER_RETREAT) | |
| return(false); | |
| int time = nFrame - status[u].n; | |
| int moved = (int) abs(u->getDistance(status[u].origin)); | |
| double speed = abs(dpos[u].getLength()); | |
| // if ( (time > 2) && (moved < 2*time) ) | |
| if ( (time > 2) && (speed < RETREAT_MIN_SP) ) | |
| { | |
| // Broodwar->printf("[%x] stuck (%d) moved:%d speed:%d",u,time,moved,speed); | |
| Position pos = u->getPosition(); | |
| int textX = pos.x(); | |
| int textY = pos.y(); | |
| Broodwar->drawBox(CoordinateType::Map, pos.x() - u->getType().dimensionLeft(), | |
| pos.y() - u->getType().dimensionUp(), | |
| pos.x() + u->getType().dimensionRight(), | |
| pos.y() + u->getType().dimensionDown(), | |
| Color(BWAPI::Colors::Red), false); | |
| // unstick it :D | |
| return(true); | |
| } | |
| return(false); | |
| } | |
| Unit* goonMicro::getMostWounded(Unit *u){ | |
| int hp = 500000; | |
| Unit* mostWounded=u; | |
| std::set<Unit*> opUnits = Broodwar->enemy()->getUnits(); | |
| for(std::set<Unit*>::iterator i=opUnits.begin(); i!=opUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()){ | |
| if((*i)->getHitPoints()+(*i)->getShields()<hp){ | |
| hp = (*i)->getHitPoints()+(*i)->getShields(); | |
| mostWounded = *i; | |
| } | |
| } | |
| //if(getClosestEnemy(u)->getDistance(mostWounded)<50&&mostWounded!=u) | |
| if((u)->getDistance(mostWounded)-getClosestEnemyDist(u)<50&&mostWounded!=u) | |
| return mostWounded; | |
| return getClosestEnemy(u); | |
| } | |
| Unit* goonMicro::getClosestEnemy(Unit* u) | |
| { | |
| Unit* closest=u; | |
| double dist = 1000000; | |
| std::set<Unit*> opUnits = Broodwar->enemy()->getUnits(); | |
| for(std::set<Unit*>::iterator i=opUnits.begin(); i!=opUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()) | |
| if (u->getDistance(*i) < dist) | |
| { | |
| closest = *i; | |
| dist = u->getDistance(*i); | |
| } | |
| //if(getMostWounded()->getDistance(closest)<100) | |
| // return getMostWounded(); | |
| return(closest); | |
| } | |
| void goonMicro::attack(Unit* u, statusOrder o) | |
| { | |
| // if (!u->isIdle()) | |
| if ((status.find(u) != status.end()) && (status[u].what == ORDER_ATTACK)) // if already attacking, don't mess with it | |
| return; | |
| std::set<Unit*> opUnits = Broodwar->enemy()->getUnits(); | |
| if(opUnits.size()==0) | |
| return; | |
| Position destination = getMostWounded(u)->getPosition(); | |
| u->attackUnit(getMostWounded(u)); | |
| Broodwar->drawCircle(CoordinateType::Map, destination.x(), destination.y(), 3, Color(BWAPI::Colors::Red), true); | |
| Broodwar->drawLine(CoordinateType::Map,u->getPosition().x(), u->getPosition().y(),destination.x() , destination.y(), Color(BWAPI::Colors::Red)); | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| // Update the status table | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| status[u].n = nFrame; | |
| status[u].what = ORDER_ATTACK; | |
| status[u].origin = u->getPosition(); | |
| status[u].pos = destination; | |
| /* Position pos = u->getPosition(); | |
| int textX = pos.x() - u->getType().dimensionLeft() - 2; | |
| int textY = pos.y() + u->getType().dimensionDown() + 2; | |
| Broodwar->drawText(CoordinateType::Map, textX, textY, "%cA%c", 0x11, 7);*/ | |
| } | |
| bool goonMicro::isMoveable(Unit *u,Position p){ | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()&&(*i)!=u){ | |
| if((*i)->getDistance(p)<15) | |
| return false; | |
| } | |
| return true; | |
| } | |
| bool goonMicro::firstShot(){ | |
| //Broodwar->printf("%d",Broodwar->enemy()->getUnits().size()); | |
| if(Broodwar->enemy()->getUnits().size()==0) | |
| return false; | |
| return true; | |
| } | |
| void goonMicro::moveBack(Unit* u) | |
| { | |
| if((u)->getGroundWeaponCooldown()>CANCEL_FRAME){ | |
| return; | |
| } | |
| if(((u)->getGroundWeaponCooldown()==0||(u)->getGroundWeaponCooldown()==1)&&getHP(u)>MIN_HP){ | |
| attack(u); | |
| return; | |
| } | |
| if(status[u].what==ORDER_RETREAT){ | |
| if(nFrame-status[u].n>10) | |
| attack(u); | |
| return; | |
| } | |
| std::string currentCmd = u->getOrder().getName(); | |
| //if(u->getGroundWeaponCooldown()<10) | |
| // attack(u); | |
| double dist = RETREAT_DIST;//-(getHP(u)-80)/180.0*70; // how much should we move back ? | |
| double dir; | |
| int dist_x, dist_y; | |
| Unit* e = getClosestEnemy(u); | |
| Position delta = u->getPosition() - e->getPosition(); // in which direction and how close is closest enemy ? | |
| if (delta.y()) | |
| { | |
| dir = atan(1.0 * delta.y() / delta.x()); | |
| dist_x = (int) (dist * (delta.x() > 0 ? 1.0 : -1.0) * abs(cos(dir))); | |
| dist_y = (int) (dist * (delta.y() > 0 ? 1.0 : -1.0) * abs(sin(dir))); | |
| } | |
| else | |
| { | |
| dist_x = (int) (dist * (delta.x() > 0 ? 1.0 : -1.0)); | |
| dist_y = 0; | |
| } | |
| Position destination = u->getPosition() + Position(dist_x,dist_y); | |
| if(isMoveable(u,destination)) | |
| move(u,destination.x(),destination.y()); | |
| else | |
| return; | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| // Update the status table | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| status[u].n = nFrame; | |
| status[u].what = ORDER_RETREAT; | |
| status[u].origin = u->getPosition(); | |
| status[u].pos = destination; | |
| } | |
| void goonMicro::moveBackFrom(Unit* u,Position p,int distance) | |
| { | |
| if(status[u].n-nFrame>5){ | |
| status[u].what=ORDER_NONE; | |
| status[u].pos=*(new Position(0,0)); | |
| } | |
| double dist = distance; // how much should we move back ? | |
| double dir; | |
| int dist_x, dist_y; | |
| Position delta = u->getPosition() - p; // in which direction and how close is closest enemy ? | |
| if (delta.y()) | |
| { | |
| dir = atan(1.0 * delta.y() / delta.x()); | |
| dist_x = (int) (dist * (delta.x() > 0 ? 1.0 : -1.0) * abs(cos(dir))); | |
| dist_y = (int) (dist * (delta.y() > 0 ? 1.0 : -1.0) * abs(sin(dir))); | |
| } | |
| else | |
| { | |
| dist_x = (int) (dist * (delta.x() > 0 ? 1.0 : -1.0)); | |
| dist_y = 0; | |
| } | |
| Position destination = u->getPosition() + Position(dist_x,dist_y); | |
| if(status[u].what==ORDER_RETREAT&&destination.getDistance(status[u].pos)<10) | |
| return; | |
| else{ | |
| destination +=status[u].pos; | |
| } | |
| if(destination.x()<2000&&destination.y()<2000) | |
| move((u),destination.x(),destination.y()); | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| // Update the status table | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| status[u].n = nFrame; | |
| status[u].what = ORDER_RETREAT; | |
| status[u].origin = u->getPosition(); | |
| status[u].pos = destination; | |
| } | |
| void goonMicro::moveForward(int n){ | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()){ | |
| move((*i),(*i)->getPosition().x()+60,(*i)->getPosition().y()+n); | |
| } | |
| } | |
| void goonMicro::moveForward(int n,std::set<Unit*> s){ | |
| for(std::set<Unit*>::iterator i=s.begin();i!=s.end();i++) | |
| if(!(*i)->getType().isBuilding()){ | |
| move((*i),(*i)->getPosition().x()+30,(*i)->getPosition().y()+n*1.5); | |
| } | |
| } | |
| void goonMicro::checkFormation(int x, int y, int r){ | |
| int centerX = x; | |
| int centerY = y; | |
| int radius = r; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()){ | |
| move((*i),0-sqrt(radius*radius-pow(((*i)->getPosition().y()-centerY)*1.0,2))+centerX,(*i)->getPosition().y()); | |
| } | |
| } | |
| int goonMicro::getClosestEnemyDist(Unit* u){ | |
| return u->getDistance(getClosestEnemy(u)); | |
| } | |
| void goonMicro::move(Unit *u,int x,int y){ | |
| Position *destination = new Position(x,y); | |
| Broodwar->drawCircle(CoordinateType::Map, destination->x(), destination->y(), 3, Color(BWAPI::Colors::White), true); | |
| Broodwar->drawLine(CoordinateType::Map,u->getPosition().x(), u->getPosition().y(),destination->x() , destination->y(), Color(BWAPI::Colors::White)); | |
| u->rightClick(*destination); | |
| } | |
| int goonMicro::getHP(Unit* u){ | |
| return (u->getHitPoints()+u->getShields())>>8; | |
| } | |
| void goonMicro::retreatWounded() | |
| { | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()) | |
| { | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| // Process special status | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| if((*i)->getGroundWeaponCooldown()==0){ | |
| attack(*i); | |
| continue; | |
| } | |
| if((*i)->getGroundWeaponCooldown()>CANCEL_FRAME){ | |
| continue; | |
| } | |
| if (status.find(*i) != status.end()) | |
| switch (status[*i].what) | |
| { | |
| case ORDER_STUCK: // If unit was marked as stuck, leave it alone for now | |
| attack(*i); | |
| continue; | |
| case ORDER_CD_RETREAT: // ordered to retreat when cooldown is not almost over | |
| if((*i)->getPosition()==status[*i].pos){ | |
| attack(*i); | |
| continue; | |
| } | |
| if ((*i)->getGroundWeaponCooldown() > 10&&(*i)->getGroundWeaponCooldown() < CANCEL_FRAME) | |
| { | |
| continue; | |
| } | |
| else{ | |
| attack(*i); | |
| continue; | |
| } | |
| default: | |
| break; | |
| } | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| // Check if unit is stuck. | |
| // If it is, the call to isStuck will call attack to unstick it | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| if((*i)->isIdle()){ | |
| attack(*i); | |
| } | |
| if(getClosestEnemyDist(*i)<CLOSEST_DISTANCE){ | |
| // moveBack(*i); | |
| // continue; | |
| } | |
| if(targeted[*i]>=MOST_TARGETTED){ | |
| moveBack(*i); | |
| continue; | |
| } | |
| if(((*i)->getHitPoints()+(*i)->getShields())>>8 <MIN_HP&&targeted[*i]>=1){ | |
| // Broodwar->printf("%d",((*i)->getType().groundWeapon()->maxRange())); | |
| moveBack(*i); | |
| continue; | |
| } | |
| if(getClosestEnemyDist(*i)>CLOSEST_DISTANCE){ | |
| attack(*i); | |
| continue; | |
| } | |
| attack(*i); | |
| } | |
| } | |
| void goonMicro::tagWounded() | |
| { | |
| Unit* target; | |
| int lasthp, lastmove; | |
| std::set<Unit*> opUnits = Broodwar->enemy()->getUnits(); | |
| movepos = (movepos + 1) % POS_MEM; | |
| lastmove = (movepos + 1) % POS_MEM; | |
| hppos = (hppos + 1) % HP_MEM; // iterate the pointer in the HP circular buffer | |
| lasthp = (hppos + 1) % HP_MEM; // pointer in the HP circular buffer, (HP_MEM-1) frames ago | |
| HP[hppos].clear(); | |
| dHP.clear(); | |
| targeted.clear(); | |
| // **************************************************************************************************************** | |
| // Step 1 : Loop through all our units for various purposes : | |
| // - take note of the HP of all our units, to be able to get a trend on their HP loss rate | |
| // - take note of the position of all our units, to be able to get their real speed | |
| // - take note if they're idle | |
| // **************************************************************************************************************** | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| // Step 1.1 : Loop through all our units | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()) | |
| { | |
| HP[hppos][*i] = (*i)->getHitPoints() + (*i)->getShields(); | |
| pos[movepos][*i] = (*i)->getPosition(); | |
| if ((*i)->isIdle()) | |
| { | |
| status[*i].n = nFrame; | |
| status[*i].what = ORDER_NONE; | |
| status[*i].origin = (*i)->getPosition(); | |
| status[*i].pos = Position(0,0); | |
| } | |
| } | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| // Step 1.2a : Then deduce the HP loss rate over (HP_MEM-1) frames | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| for(std::map<Unit*,int>::iterator i=HP[hppos].begin();i!=HP[hppos].end();i++) | |
| if ( HP[lasthp].find(i->first) != HP[lasthp].end()) | |
| dHP[i->first] = (i->second - HP[lasthp][i->first]) / 256; | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| // Step 1.2b : Calculate the movement speed over the last few frames | |
| // ---------------------------------------------------------------------------------------------------------------- | |
| for(std::map<Unit*,Position>::iterator i=pos[movepos].begin();i!=pos[movepos].end();i++) | |
| if ( pos[lastmove].find(i->first) != pos[lastmove].end()) | |
| dpos[i->first] = i->second - pos[lastmove][i->first]; | |
| // **************************************************************************************************************** | |
| // Step 2 : Find by how many enemy units our units are targeted. | |
| // | |
| // Using getTarget() doesn't give the intented result. It shows when units are targeted from a distance | |
| // with an attackMove type of order. But once the enemy gets to contact, the order is finished maybe and | |
| // this target is reset. | |
| // | |
| // tec27 mentioned getOrderTarget() should give the intended result. | |
| // **************************************************************************************************************** | |
| for(std::set<Unit*>::iterator i=opUnits.begin(); i!=opUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()) { | |
| target = (*i)->getOrderTarget(); | |
| if (targeted.find(target) == targeted.end()) | |
| targeted.insert(std::make_pair(target,1)); | |
| else | |
| targeted.find(target)->second++; | |
| } | |
| for(std::set<Unit*>::iterator i=opUnits.begin(); i!=opUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()) { | |
| int currentHP = ((*i)->getHitPoints()+(*i)->getShields())>>8; | |
| if(currentHP!=0) | |
| Broodwar->drawBox(CoordinateType::Map,(*i)->getPosition().x()-10,(*i)->getPosition().y()-10,(*i)->getPosition().x()+10,(*i)->getPosition().y()+10,BWAPI::Color(191-(180-currentHP)/(16.363)),true); | |
| } | |
| } | |
| void goonMicro::drawStates() | |
| { | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| { | |
| if(!(*i)->getType().isBuilding()) { | |
| Position pos = (*i)->getPosition(); | |
| int textX = pos.x() - (*i)->getType().dimensionLeft() - 2; | |
| int textY = pos.y() + (*i)->getType().dimensionDown() + 2; | |
| // # of times targeted by enemy units | |
| // if (status.find(*i) != status.end()) | |
| // Broodwar->drawText(CoordinateType::Map, textX, textY, "%cT%c%d %c%c", 0x11, 4, targeted[*i], statusText[status[*i].what], 7); | |
| /* if (dpos.find(*i) != dpos.end()) | |
| { | |
| textY+=8; | |
| Broodwar->drawText(CoordinateType::Map, textX, textY, "%cs%c%.0f%c", 0x11, 4, dpos[*i].getLength(), 7); | |
| }*/ | |
| /* if (dHP.find(*i) != dHP.end()) | |
| Broodwar->drawText(CoordinateType::Map, textX, textY, "%cdHP:%c%d%c", 0x11, 4, dHP[*i], 7);*/ | |
| // Cooldown | |
| //textY+=8; | |
| //Broodwar->drawText(CoordinateType::Map, textX, textY, "%cC:%c%d%c", 0x11, 4, (*i)->getGroundWeaponCooldown(), 7); | |
| /* textY+=8; | |
| Broodwar->drawText(CoordinateType::Map, textX, textY, "%cSH:%c%d%c", 0x11, 4, (*i)->getShields()/256, 7);*/ | |
| } | |
| } | |
| } | |
| void goonMicro::onUnitCreate(BWAPI::Unit* unit) | |
| { | |
| } | |
| void goonMicro::onUnitDestroy(BWAPI::Unit* u) | |
| { | |
| int i; | |
| for (i=0; i<HP_MEM; i++) | |
| HP[i].erase(u); | |
| dHP.erase(u); | |
| for (i=0; i<POS_MEM; i++) | |
| pos[i].erase(u); | |
| dpos.erase(u); | |
| targeted.erase(u); | |
| status.erase(u); | |
| } | |
| void goonMicro::onUnitMorph(BWAPI::Unit* unit) | |
| { | |
| } | |
| void goonMicro::onUnitShow(BWAPI::Unit* unit) | |
| { | |
| } | |
| void goonMicro::onUnitHide(BWAPI::Unit* unit) | |
| { | |
| } | |
| bool goonMicro::onSendText(std::string text) | |
| { | |
| if(text=="/populate"){ | |
| srand((unsigned)time(0)); | |
| for(int i =0;i<LENGTH;i++){ | |
| traits[i].closest_distance=130+rand()%30; | |
| traits[i].min_hp=65+rand()%50; | |
| traits[i].most_targetted=1+rand()%5; | |
| traits[i].cancelFrame=13+rand()%17; | |
| } | |
| populated = 1; | |
| } | |
| if(text=="/avg"){ | |
| if(populated==1){ | |
| int avgDist = 0; | |
| int avghp= 0; | |
| int avgTarget = 0; | |
| int avgFrames = 0; | |
| for(int i =0;i<LENGTH;i++){ | |
| avgDist+=traits[i].closest_distance; | |
| avghp+=traits[i].min_hp; | |
| avgTarget+=traits[i].most_targetted; | |
| avgFrames+=traits[i].cancelFrame; | |
| } | |
| avgDist/=LENGTH; | |
| avghp/=LENGTH; | |
| avgTarget/=LENGTH; | |
| avgFrames/=LENGTH; | |
| Broodwar->printf("%d = average distance",avgDist); | |
| Broodwar->printf("%d = average hp",avghp); | |
| Broodwar->printf("%d = average num of targets",avgTarget); | |
| Broodwar->printf("%d = average frame",avgFrames); | |
| } | |
| else{ | |
| Broodwar->printf("not populated"); | |
| Broodwar->printf("%d",CLOSEST_DISTANCE); | |
| Broodwar->printf("%d",MIN_HP); | |
| Broodwar->printf("%d",MOST_TARGETTED); | |
| } | |
| } | |
| if(text=="/current"){ | |
| Broodwar->printf("%d",CLOSEST_DISTANCE); | |
| Broodwar->printf("%d",MIN_HP); | |
| Broodwar->printf("%d",MOST_TARGETTED); | |
| Broodwar->printf("%d",CANCEL_FRAME); | |
| } | |
| if (text=="/show players") | |
| { | |
| showPlayers(); | |
| return false; | |
| } else if (text=="/show forces") | |
| { | |
| showForces(); | |
| return false; | |
| } else | |
| { | |
| Broodwar->printf("You typed '%s'!",text.c_str()); | |
| } | |
| return true; | |
| } | |
| void goonMicro::drawStats() | |
| { | |
| int line=1; | |
| char stats[100]; | |
| char morestats[20]; | |
| int hp; | |
| int totalHP = 0, totalHPopp = 0; | |
| Unit *u; | |
| lastOrder *s; | |
| int x=0; | |
| int y =0; | |
| //draw our center | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++){ | |
| x+=(*i)->getPosition().x(); | |
| y+=(*i)->getPosition().y(); | |
| } | |
| x/=12; | |
| y/=12; | |
| //draw their center | |
| int ox=0; | |
| int oy=0; | |
| std::set<Unit*> opUnits = Broodwar->enemy()->getUnits(); | |
| if(opUnits.size()!=0){ | |
| for(std::set<Unit*>::iterator i=opUnits.begin();i!=opUnits.end();i++){ | |
| ox+=(*i)->getPosition().x(); | |
| oy+=(*i)->getPosition().y(); | |
| } | |
| ox/=opUnits.size(); | |
| oy/=opUnits.size(); | |
| opCenter = new Position(ox,oy); | |
| Broodwar->drawCircleMap(ox,oy,5,BWAPI::Colors::Red,true); | |
| } | |
| Broodwar->drawCircleMap(x,y,5,BWAPI::Colors::Blue,true); | |
| Broodwar->drawTextScreen(5,0,"%d %d %d %d %d", nFrame, CLOSEST_DISTANCE,MIN_HP,MOST_TARGETTED,CANCEL_FRAME); | |
| // **************************************************************************************************************** | |
| // Step 1 : Loop all our units to find how many of each unit type we have | |
| // **************************************************************************************************************** | |
| std::map<UnitType, int> unitTypeCounts; | |
| for(std::set<Unit*>::iterator i=myUnits.begin();i!=myUnits.end();i++) | |
| { | |
| if (unitTypeCounts.find((*i)->getType())==unitTypeCounts.end()) | |
| { | |
| unitTypeCounts.insert(std::make_pair((*i)->getType(),0)); | |
| } | |
| unitTypeCounts.find((*i)->getType())->second++; | |
| } | |
| // **************************************************************************************************************** | |
| // Step 2 : Display (number of units) (unit type) for all unit types | |
| // **************************************************************************************************************** | |
| /* for(std::map<UnitType,int>::iterator i=unitTypeCounts.begin();i!=unitTypeCounts.end();i++) | |
| { | |
| Broodwar->drawTextScreen(5,16*line,"- %d %ss",(*i).second, (*i).first.getName().c_str()); | |
| line++; | |
| }*/ | |
| /* for(std::map<Unit*,int>::iterator i=dHP.begin();i!=dHP.end();i++) | |
| { | |
| Broodwar->drawTextScreen(5,16*line,"%x %d", i->first, i->second); | |
| line++; | |
| }*/ | |
| // **************************************************************************************************************** | |
| // Step 3 : For all our units, let's see what they're (supposed to be) doing | |
| // **************************************************************************************************************** | |
| for(std::map<Unit*,lastOrder>::iterator i=status.begin();i!=status.end();i++) | |
| { | |
| u = i->first; | |
| s = &i->second; | |
| hp = (u->getHitPoints() + u->getShields()) >> 8; | |
| sprintf_s(stats,100,"%c cd:%2d hp:%d", | |
| statusText[s->what] , | |
| u->getGroundWeaponCooldown(), | |
| hp ); | |
| // Show unit speed | |
| /* if (dpos.find(i->first) != dpos.end()) | |
| { | |
| sprintf_s(morestats,20," s:(%d,%d)->%.1f", dpos[u].x(), dpos[u].y(), dpos[u].getLength()); | |
| strncat_s(stats,100,morestats,20); | |
| }*/ | |
| // Show last unit positions | |
| /* for (j=0; j < POS_MEM; j++) | |
| if (pos[j].find(i->first) != pos[j].end()) | |
| { | |
| sprintf_s(morestats,20," (%d,%d)",pos[j][u].x(),pos[j][u].y()); | |
| strncat_s(stats,100,morestats,20); | |
| }*/ | |
| Broodwar->drawTextScreen(5,16*line,stats); | |
| totalHP += hp; | |
| line++; | |
| } | |
| // Get opponents total HP | |
| for(std::set<Unit*>::iterator i=opUnits.begin(); i!=opUnits.end();i++) | |
| if(!(*i)->getType().isBuilding()) | |
| totalHPopp += ((*i)->getHitPoints() + (*i)->getShields()) >> 8; | |
| Broodwar->drawTextScreen(5,16*line,"total HP: %d %c %d",totalHP,(totalHP > totalHPopp ? '>' : totalHP==totalHPopp ? '=' : '<'),totalHPopp); | |
| } | |
| void goonMicro::showPlayers() | |
| { | |
| std::set<Player*> players=Broodwar->getPlayers(); | |
| for(std::set<Player*>::iterator i=players.begin();i!=players.end();i++) | |
| { | |
| Broodwar->printf("Player [%d]: %s is in force: %s",(*i)->getID(),(*i)->getName().c_str(), (*i)->getForce()->getName().c_str()); | |
| } | |
| } | |
| void goonMicro::showForces() | |
| { | |
| std::set<Force*> forces=Broodwar->getForces(); | |
| for(std::set<Force*>::iterator i=forces.begin();i!=forces.end();i++) | |
| { | |
| std::set<Player*> players=(*i)->getPlayers(); | |
| Broodwar->printf("Force %s has the following players:",(*i)->getName().c_str()); | |
| for(std::set<Player*>::iterator j=players.begin();j!=players.end();j++) | |
| { | |
| Broodwar->printf(" - Player [%d]: %s",(*j)->getID(),(*j)->getName().c_str()); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #pragma once | |
| #include <BWAPI.h> | |
| #include <windows.h> | |
| #include <math.h> | |
| #define HP_MEM 20 | |
| #define POS_MEM 3 | |
| typedef struct _lastOrder | |
| { | |
| unsigned int n; // frame # order was issued | |
| int what; // what was issued ? | |
| BWAPI::Position origin; // original position | |
| BWAPI::Position pos; // target for some orders | |
| } lastOrder; | |
| enum statusOrder {ORDER_NONE, ORDER_RETREAT, ORDER_ATTACK, ORDER_STUCK, ORDER_CD_RETREAT}; | |
| const char statusText[] = {'N','R','A','S', 'r'}; | |
| class goonMicro : public BWAPI::AIModule | |
| { | |
| public: | |
| virtual void onStart(); | |
| virtual void onFrame(); | |
| virtual bool onSendText(std::string text); | |
| virtual void onUnitCreate(BWAPI::Unit* unit); | |
| virtual void onUnitDestroy(BWAPI::Unit* u); | |
| virtual void onUnitMorph(BWAPI::Unit* unit); | |
| virtual void onUnitShow(BWAPI::Unit* unit); | |
| virtual void onUnitHide(BWAPI::Unit* unit); | |
| private: | |
| void drawStats(); //not part of BWAPI::AIModule | |
| void drawStates(); | |
| void showPlayers(); | |
| void showForces(); | |
| void goonMicro::stopAll(); | |
| void retreatWounded(); | |
| void tagWounded(); | |
| void singleFile(); | |
| void moveBack(BWAPI::Unit* u); | |
| void attack(BWAPI::Unit* u, statusOrder o = ORDER_ATTACK); | |
| bool isStuck(BWAPI::Unit* u); | |
| void goonMicro::move(BWAPI::Unit *u,int x,int y); | |
| void goonMicro::moveForward(int n); | |
| BWAPI::Unit* goonMicro::getMostWounded(BWAPI::Unit* u); | |
| bool goonMicro::isMoveable(BWAPI::Unit *u,BWAPI::Position p); | |
| void checkFormation(int x, int y, int r); | |
| int getClosestEnemyDist(BWAPI::Unit* u); | |
| void restart(); | |
| bool firstShot(); | |
| void remove(int n); | |
| void getCols(); | |
| void straighten(); | |
| void pack(); | |
| void goonMicro::enclose(); | |
| void goonMicro::formArc(); | |
| void goonMicro::moveForward(int n,std::set<BWAPI::Unit*> s); | |
| void goonMicro::moveBackFrom(BWAPI::Unit* u,BWAPI::Position p,int distance); | |
| int goonMicro::inBetween(int x, int y); | |
| int goonMicro::getHP(BWAPI::Unit *u); | |
| bool isEarlyGame(); | |
| void formCircle(); | |
| BWAPI::Unit* goonMicro::getClosestEnemy(BWAPI::Unit* u); | |
| // Class members --------------------------------------------------------------------------------------------------------------- | |
| unsigned int nFrame; | |
| std::set<BWAPI::Unit*> myUnits; | |
| std::set<BWAPI::Unit*> col1; | |
| std::set<BWAPI::Unit*> col2; | |
| std::set<BWAPI::Unit*> col3; | |
| std::set<BWAPI::Unit*> col4; | |
| std::map<BWAPI::Unit*, lastOrder> status; | |
| BWAPI::Position* opCenter; | |
| int hppos; // position in the units HP circular buffer | |
| std::map<BWAPI::Unit*, int> HP[HP_MEM]; // units HP circular buffer: 1 element of the table per frame for the last HP_MEM frames | |
| std::map<BWAPI::Unit*, int> dHP; // d(HP)/dt | |
| std::map<BWAPI::Position*,int> forceFields; | |
| int movepos; | |
| std::map<BWAPI::Unit*, BWAPI::Position> pos[POS_MEM]; | |
| std::map<BWAPI::Unit*, BWAPI::Position> dpos; // instant speed | |
| std::map<BWAPI::Unit*, int> opTargeted; | |
| std::map<BWAPI::Unit*, int> targeted; // # of times our units are targeted by enemy units | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment