Skip to content

Instantly share code, notes, and snippets.

@omailson
Created April 22, 2012 15:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save omailson/2464570 to your computer and use it in GitHub Desktop.
Save omailson/2464570 to your computer and use it in GitHub Desktop.
Agente
#include "MeuAgentePrincipal.h"
#include <AgentePrincipal.h>
#include <Windows.h>
#include <BWAPI\Position.h>
#include <BWAPI\UnitType.h>
//blackboard!
bool GameOver = false;
Unidade* amigoDaVez = NULL;
//
void AITrabalhador (Unidade* u){
double distance = 99999;
Unidade* mineralPerto = NULL;
std::set<Unidade*> minerais = u->getMinerals();
for(std::set<Unidade*>::iterator it = minerais.begin(); it != minerais.end(); it++){
if(u->getDistance(*it) < distance){
distance = u->getDistance(*it);
mineralPerto = *it;
}//vai minerar no mineral mais perto
}
if(mineralPerto != NULL) u->rightClick(mineralPerto);
}
void AIGuerreiro (Unidade* u){
std::set<Unidade*> alvos = u->getEnemyUnits();
if(alvos.size() > 0)
u->attack((*alvos.begin())); //ataca uma unidade inimiga qualquer, caso exista.
}
bool indoconstruir = false;
bool construido = false;
void AIConstrutora (Unidade* u){
if(u->minerals() < 150 && !(construido|indoconstruir)){
return;
}
if(!indoconstruir){
BWAPI::TilePosition tp = u->getTilePosition();
int limite = 0;
int adi = 6;
//Construir um Barracks perto de onde estiver
bool conseguiu;
while(!(conseguiu = (u)->build(tp,BWAPI::UnitTypes::Terran_Barracks))){
if(((u->minerals()&0xF)>>2) < 2)
tp = BWAPI::TilePosition(tp.x(), tp.y()+adi);
else
tp = BWAPI::TilePosition(tp.x()+adi, tp.y());
tp.makeValid(); //metodo para forçar a nova posição que geramos a ser válida (dentro dos limites do mapa)
//ps: válida != construível
limite++;
if(limite > 50) break; //se tentar 50 vezes e nao conseguir, deixa para tentar no proximo turno.
//sem esse break, o loop pode rodar infinitamente em alguns casos de mal posicionamento, prejudicando muito
//o desempenho do jogo.
adi = -adi + (adi > 0 ? -2 : +2);
}
if(conseguiu){
indoconstruir = true;
}
}
else{
if(u->isIdle()){ //parou por que?
if(u->minerals() < 200) //(se demorarmos muito construindo, o que acontece?)
construido = true;
else
indoconstruir = false; //nao conseguiu, recomeçar o processo
if(construido){
amigoDaVez = NULL;
//andar para perto dos outros mineradores antes de escolher o mineral proximo
std::set<Unidade*> aliados = u->getAllyUnits();
for(std::set<Unidade*>::iterator it = aliados.begin(); it != aliados.end(); it++){
if((*it) != u && (*it)->getType().isWorker()){
u->rightClick( (*it)->getPosition() );
//se clicarmos na UNIDADE, ordenaremos que esta fique seguindo a outra, ao inves
//de apenas se deslocar para a posicao atual que o alvo se encontra
break;
}
}
}
}
}
}
void AICentroComando (Unidade* u){
if(u->getType() == BWAPI::UnitTypes::Terran_Barracks)
u->train(BWAPI::UnitTypes::Terran_Marine);
else
if(u->supplyUsed() < 10){ //10?! Cada supply no jogo conta por 2, logo 10 aqui = 5 no jogo
if(u->minerals() > 49){
u->train(BWAPI::UnitTypes::Terran_SCV);
}
}
}
bool primeiro = true;
DWORD WINAPI threadAgente(LPVOID param){
Unidade *u = (Unidade*) param;
while(true){
//Se houve algum problema (ex: o jogo foi fechado) ou a unidade estah morta, finalizar a thread
if(GameOver || u == NULL || !u->exists()) return 0;
//Enquanto a unidade ainda nao terminou de ser construida ou o seu comando ainda nao foi
//processado (ou seja, continua no mesmo turno), aguardar e poupar processamento
if(!u->isCompleted()){
if(primeiro){ //gambiarra
amigoDaVez = u;//o que acontece se ele morrer...?
primeiro = false;
}
Sleep(500);
continue;
}
if(!u->checkNovoTurno()){
Sleep(10);
continue;
}
//Inserir o codigo de voces a partir daqui//
if(u == amigoDaVez) AIConstrutora(u);
else if(u->isIdle()){ //nao ta fazendo nada, fazer algo util
if(u->getType().isWorker()) AITrabalhador(u);
else if(u->getType().canProduce()) AICentroComando(u);
else AIGuerreiro(u);
}
Sleep(10);//Sempre dormir pelo menos 10ms no final do loop, pois uma iteracao da thread é muito mais rápida do que um turno do bwapi.
}
}
void MeuAgentePrincipal::InicioDePartida(){
GameOver = false;
}
void MeuAgentePrincipal::onEnd(bool isWinner){
//sinalizar e aguardar o tempo necessario para todas as threads se terminarem antes do jogo sair, evitando erros.
GameOver = true;
Sleep(550);
}
void MeuAgentePrincipal::UnidadeCriada(Unidade* unidade){
//Uma nova unidade sua foi criada (isto inclui as do inicio da partida). Implemente aqui como quer tratar ela.
BWAPI::UnitType tipo = unidade->getType();
//Nao desperdicar threads com predios que nao fazem nada
if(tipo != BWAPI::UnitTypes::Terran_Supply_Depot){
CreateThread(NULL,0,threadAgente,(void*)unidade,0,NULL);
}
}
/*
Os outros eventos nao existem numa arquitetura orientada a Agentes Autonomos, pois eram relacionados ao Player do Broodwar
de maneira generica, nao sendo especificamente ligados a alguma unidade do jogador. Se desejado, seus comportamentos podem
ser simulados através de técnicas ou estruturas de comunicação dos agentes, como por exemplo Blackboards.
*/
#pragma once
#include <BWAPI.h>
#include <set>
//#include "Gerente.h"
class Unidade{
public:
BWAPI::Unit *unit;
BWAPI::UnitCommand comando;
std::map<BWAPI::Unit*, Unidade*> *mapa;
int index;
bool fow;
Unidade(BWAPI::Unit *unit, int index, std::map<BWAPI::Unit*, Unidade*> *m, bool fog);
BWAPI::UnitCommand getComando();
//instavel std::set<Unidade*> getUnitsOnTile(int tileX, int tileY);
//instavel bool canBuildHere(BWAPI::TilePosition position, BWAPI::UnitType type, bool checkExplored = false);
bool hasPower(int tileX, int tileY, int tileWidth, int tileHeight);
bool hasPower(BWAPI::TilePosition position, int tileWidth, int tileHeight);
bool isBuildable(int tileX, int tileY);
bool isBuildable(BWAPI::TilePosition position);
std::set<Unidade*> getMinerals();
std::set<Unidade*> getGeysers();
std::set<Unidade*> getEnemyUnits();
std::set<Unidade*> getAllyUnits();
bool isEnemy(Unidade* target);
bool isAlly(Unidade* target);
int minerals();
int gas();
int supplyTotal();
int supplyUsed();
std::set<Unidade*> filtrar(std::set<Unidade*> conjunto);
bool checar(BWAPI::UnitCommand comando);
bool attack(BWAPI::Position target);
bool attack(Unidade* target);
bool build(BWAPI::TilePosition target, BWAPI::UnitType type);
bool buildAddon(BWAPI::UnitType type);
bool train(BWAPI::UnitType type);
bool morph(BWAPI::UnitType type);
bool research(BWAPI::TechType tech);
bool upgrade(BWAPI::UpgradeType upgrade);
bool setRallyPoint(BWAPI::Position target);
bool setRallyPoint(Unidade* target);
bool move(BWAPI::Position P);
bool patrol(BWAPI::Position target);
bool holdPosition();
bool stop();
bool follow(Unidade* target);
bool gather(Unidade* target);
bool returnCargo();
bool repair(Unidade* target);
bool burrow();
bool unburrow();
bool cloak();
bool decloak();
bool siege();
bool unsiege();
bool lift();
bool land(BWAPI::TilePosition target);
bool load(Unidade* target);
bool unload(Unidade* target);
bool unloadAll();
bool unloadAll(BWAPI::Position target);
bool rightClick(Unidade *target);
bool rightClick(BWAPI::Position target);
bool haltConstruction();
bool cancelConstruction();
bool cancelAddon();
bool cancelTrain(int slot = -2);
bool cancelMorph();
bool cancelResearch();
bool cancelUpgrade();
bool useTech(BWAPI::TechType tech);
bool useTech(BWAPI::TechType tech, BWAPI::Position target);
bool useTech(BWAPI::TechType tech, Unidade* target);
bool checkNovoTurno();
bool isInGame();
bool isUnderAttack();
//BWAPI::Player* getPlayer();
BWAPI::UnitType getType();
BWAPI::Position getPosition();
BWAPI::TilePosition getTilePosition();
double getAngle();
double getVelocityX();
double getVelocityY();
int getHitPoints();
int getShields();
int getEnergy();
int getResources();
int getResourceGroup();
int getDistance(Unidade* target);
int getDistance(BWAPI::Position target);
bool hasPath(Unidade* target);
bool hasPath(BWAPI::Position target);
int getLastCommandFrame();
//BWAPI::UnitCommand getLastCommand();
int getUpgradeLevel(BWAPI::UpgradeType upgrade);
BWAPI::UnitType getInitialType();
BWAPI::Position getInitialPosition();
BWAPI::TilePosition getInitialTilePosition();
int getInitialHitPoints();
int getInitialResources();
int getKillCount();
int getAcidSporeCount();
int getInterceptorCount();
int getScarabCount();
int getSpiderMineCount();
int getGroundWeaponCooldown();
int getAirWeaponCooldown();
int getSpellCooldown();
int getDefenseMatrixPoints();
int getDefenseMatrixTimer();
int getEnsnareTimer();
int getIrradiateTimer();
int getLockdownTimer();
int getMaelstromTimer();
int getOrderTimer();
int getPlagueTimer();
int getRemoveTimer();
int getStasisTimer();
int getStimTimer();
BWAPI::UnitType getBuildType();
std::list<BWAPI::UnitType> getTrainingQueue();
BWAPI::TechType getTech();
BWAPI::UpgradeType getUpgrade();
int getRemainingBuildTime();
int getRemainingTrainTime();
int getRemainingResearchTime();
int getRemainingUpgradeTime();
Unidade* getBuildUnit();
std::set<Unidade*> getUnitsInRadius(int radius);
std::set<Unidade*> getUnitsInWeaponRange(BWAPI::WeaponType weapon);
Unidade* getTarget();
BWAPI::Position getTargetPosition();
BWAPI::Order getOrder();
Unidade* getOrderTarget();
BWAPI::Order getSecondaryOrder();
BWAPI::Position getRallyPosition();
Unidade* getRallyUnit();
Unidade* getAddon();
Unidade* getNydusExit();
Unidade* getPowerUp();
Unidade* getTransport();
std::set<Unidade*> getLoadedUnits();
Unidade* getCarrier();
std::set<Unidade*> getInterceptors();
Unidade* getHatchery();
std::set<Unidade*> getLarva();
bool exists();
bool hasNuke();
bool isAccelerating();
bool isAttacking();
bool isAttackFrame();
bool isBeingConstructed();
bool isBeingGathered();
bool isBeingHealed();
bool isBlind();
bool isBraking();
bool isBurrowed();
bool isCarryingGas();
bool isCarryingMinerals();
bool isCloaked();
bool isCompleted();
bool isConstructing();
bool isDefenseMatrixed();
bool isDetected();
bool isEnsnared();
bool isFollowing();
bool isGatheringGas();
bool isGatheringMinerals();
bool isHallucination();
bool isHoldingPosition();
bool isIdle();
bool isInterruptible();
bool isInvincible();
bool isInWeaponRange(Unidade *target);
bool isIrradiated();
bool isLifted();
bool isLoaded();
bool isLockedDown();
bool isMaelstrommed();
bool isMorphing();
bool isMoving();
bool isParasited();
bool isPatrolling();
bool isPlagued();
bool isRepairing();
bool isResearching();
bool isSelected();
bool isSieged();
bool isStartingAttack();
bool isStasised();
bool isStimmed();
bool isStuck();
bool isTraining();
bool isUnderStorm();
bool isUnderDarkSwarm();
bool isUnderDisruptionWeb();
bool isUnpowered();
bool isUpgrading();
bool isVisible();
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment