/** @file /ai/Strategizer/strategygraph.h @brief Header grafu strategicke disponibility. Header grafu strategicke disponibility. @author PZ @version 0.1 */ #ifndef __PETR_ZITA_STRATEGY_GRAPH__ #define __PETR_ZITA_STRATEGY_GRAPH__ #pragma warning( disable : 4290 ) #define VERTEX_CONTAINER vector #define EDGE_CONTAINER vector #define THREAT_CONTAINER list #define NEEDS_CONTAINER list #define SOURCES_CONTAINER list #define HELPS_CONTAINER list #define NON_DEFENDING_TARGETS_CONTAINER list #define NOT_USED_SOURCES_CONTAINER list #include #include #include #include #include #include #include "common/exc.h" #include "common/mm.h" #include "common/types.h" #include "common/utils.h" #include "ai/ai_makra.h" #include "ai/aiscriptids.h" #include "ai/aiscriptcaller.h" #include "ai/Strategizer/strategytypes.h" #include "ai/Strategizer/planning.h" #include "world/useful.h" #include "world/plan/plan.h" #include "world/buildings/building.h" #include "world/units/unit.h" namespace ai_ns { namespace strategizer_ns { using namespace World; class CStrEdge; // forward deklarace tridy hrany (CStrEdge) - deklarovana v hlavicce tridy vrcholu (CStrVertex) /** Datovy typ urcujici prislusnost entity v strategickem grafu. */ typedef enum { My, ///< entita AI hrace Neutral, ///< neutralni entita Ally, ///< spojenecka entita Truce, ///< entita hrace, se kterym je AI hrac v primeri Enemy, ///< entita nepratelskeho hrace War, ///< entita hrace, se kterym je AI hrac ve valce DoesntMatter ///< blize neurcena prislusnost entity } TDipOwnership; /** Datovy typ pro reprezentaci hrozby ve strategickem grafu. */ typedef struct type_threat { int threat_weight; ///< vaha (ciselne vyjadreni) hrozby int threat_disponibility; ///< casova disponibilita hrozby (za jak dlouho bude naplnena) int attacker_vertex_id; ///< ID vrcholu strategickeho grafu, jenz hrozbu reprezentuje int defended_entity_vertex_id; ///< ID vrcholu strategickeho grafu, na nejz je hrozba vztazena int defended_entity_price; ///< cena (cislene vyjadreni) branene entity int edge_id; ///< ID hrany strategickeho grafu mezi vercholem hrozby a cilem hrozby int attacker_range; ///< dosah utoku utocnika, jenz reprezentuje hrozbu bool operator<(const struct type_threat& t2); ///< operator pro trideni hrozeb } TThreat; /** Datovy typ pro reprezentaci potreby braneni nebranenych nebo nedostatecne branenych zdroju ve strateguickem grafu. */ typedef struct type_help_needed { int time; ///< maximalni cas nutny pro zazehnani hrozby int help_power; ///< velikost sily potrebneho braneni, jenz muze hrozbu zazehnat int importance; ///< dulezitost pro zazehnani hrozby int defended_entity_id; ///< ID vrcholu strategickeho grafu, na nejz je hrozba vztazena (ktery je potreba branit) bool operator<(const struct type_help_needed& thn); ///< operator pro trideni potreb braneni } THelpNeeded; /** Trida, jenz reprezentuje obecny vrchol ve strategickem grafu. */ class CStrVertex { public: /** Konstruktor (bezparametricky). */ CStrVertex(); /** Konstruktor. @param dip prislusnost vrcholem reprezentovane entity */ CStrVertex(TDipOwnership dip); /** Destruktor. */ ~CStrVertex(); /** Vrati ID tohoto vrcholu ve strategickem grafu. */ int getID() const { return id; }; /** Nastavi ID tohoto vrcholu ve strategickem grafu. @param id nove ID tohoto vrcholu ve strategickem grafu */ void setID(int id) { this->id=id; }; /** Vrati X-ovou souradnici entity reprezentovane timto vrcholem na mape. */ int getPosX() const { return posX; }; /** Vrati Y-ovou souradnici entity reprezentovane timto vrcholem na mape. */ int getPosY() const { return posY; }; /** Nastavi X-ovou souradnici entity reprezentovane timto vrcholem na mape. @param posX nova X-ova pozice entity reprezentovane timto vrcholem na mape */ void setPosX(int posX) { this->posX=posX; }; /** Nastavi Y-ovou souradnici entity reprezentovane timto vrcholem na mape. @param posY nova Y-ova pozice entity reprezentovane timto vrcholem na mape */ void setPosY(int posY) { this->posY=posY; }; /** Vrati prislusnost entity reprezentovane ve vrcholu. */ TDipOwnership getDipOwnership() const { return dipo; }; /** Nastavi prislusnost entity reprezentovane ve vrcholu. @param dipo nova prislusnost entity reprezentovane timto vrcholem na mape */ void setDipOwnership(TDipOwnership dipo) { this->dipo=dipo; }; /** Vytvori hranu (spravny typ) od tohoto vrcholu k jinemu vrcholu. @param vref cilovy vrchol strategickeho grafu, se kterym se bude vytvaret hrana @return (CStrEdge*) ukazatel na dynamicky vytvoreny objekt hrany */ virtual CStrEdge* createEdge(CStrVertex* vref); #ifdef _K_EDITOR_ /** Vrati jmeno tridy vrcholu ve strategickem hranu, jenz urcuje i typ entity, kterou vrchol reprezentuje. @return (char*) popis jmena tridy */ const char* getClassName(); #endif // TODO: odstranit pokud jde virtual void foo() {}; private: int id; ///< ID vrcholu ve strategickem grafu int posX; ///< X-ova souradnice pozice entity na mape, jenz je reprezentovana timto vrcholem int posY; ///< Y-ova souradnice pozice entity na mape, jenz je reprezentovana timto vrcholem TDipOwnership dipo; ///< prislusnost entity, jenz je reprezentovana timto vrcholem }; /** Trida, jenz reprezentuje statickou entitu ve strategickem grafu. */ class CStaticEntity : public CStrVertex { public: /** Konstruktor (bezparametricky). */ CStaticEntity(); /** Konstruktor. @param dip prislusnost vrcholem reprezentovane entity */ CStaticEntity(TDipOwnership dip); bool operator<(const CStaticEntity* & ose); ///< operator pro trideni /** Vrati cenu (ciselna hodnota), na kolik si entity AI hrac ceni. */ int getPrice() const { return price; }; /** Nastavi cenu (ciselna hodnota), na kolik si entity AI hrac ceni. @param price nova cena */ void setPrice(int price) { this->price=price; }; /** Vrati cenovy pomer ceny entity a ceny souctu vsech entit AI hrace. */ double getPriceRatio() const { return price_ratio; }; /** Nastavi cenovy pomer ceny entity a ceny souctu vsech entit AI hrace. @param price_ratio nova cenovy pomer */ void setPriceRatio(double price_ratio) { this->price_ratio=price_ratio; }; /** Vrati pocet volnych mist pro braneni staticke entity. */ int getFreeDefendingPlaces() const { return free_defending_places; }; /** Nastavi pocet volnych mist pro braneni staticke entity. @param free_defending_places nova hodnota poctu volnych mist pro braneni staticke entity */ void setFreeDefendingPlaces(int free_defending_places) { this->free_defending_places=free_defending_places; }; /** Vrati priznak braneni staticke entity. */ bool getGuardedIndicator() const { return guarded; }; /** Nastavi priznak braneni staticke entity. @param guarded nova hodnota priznaku braneni staticke entity */ void setGuardedIndicator(bool guarded) { this->guarded=guarded; }; // TODO: odstranit pokud jde virtual void foo() {}; protected: int price; ///< cena (ciselna hodnota), na kolik si entity AI hrac ceni double price_ratio; ///< pomer ceny teto entity ku souctu pres vsechny entity, co AI hrac vlastni int free_defending_places; ///< pocet volnych mist pro braneni staticke entity bool guarded; ///< priznak braneni staticke entity }; /** Trida, jenz reprezentuje mesto ve strategickem grafu. */ class CCity : public CStaticEntity { public: /** Konstruktor (bezparametricky). */ CCity(); /** Konstruktor. @param dip prislusnost vrcholem reprezentovaneho mesta */ CCity(TDipOwnership dip); int position[MAX_CITY_SIZE]; ///< seznam pozic mesta reprezentovaneho timto vrcholem /** Vrati velikost mesta reprezentovaneho timto vrcholem. */ int getCitySize() const { return citysize; }; /** Nastavi velikost mesta reprezentovaneho timto vrcholem. @param citysize nova hodnota velikosti mesta reprezentovaneho timto vrcholem */ void setCitySize(int citysize) { this->citysize=citysize; }; // TODO: odstranit pokud jde virtual void foo() {}; protected: int citysize; ///< velikost mesta reprezentovaneho timto vrcholem }; /** Trida, jenz reprezentuje budovu ve strategickem grafu. */ class CBuilding : public CStaticEntity { public: /** Konstruktor (bezparametricky). */ CBuilding(); /** Konstruktor. @param dip prislusnost vrcholem reprezentovane budovy */ CBuilding(TDipOwnership dip); /** Vrati World ID budovy reprezentovane timto vrcholem. */ int getWorldID() const { return world_building_id; }; /** Nastavi World ID budovy reprezentovane timto vrcholem. @param world_building_id nova hodnota World ID budovy reprezentovane timto vrcholem */ void setWorldID(int world_building_id) { this->world_building_id=world_building_id; }; /** Vrati typ budovy reprezentovane timto vrcholem. */ int getBuildingType() const { return building_type; }; /** Nastavi typ budovy reprezentovane timto vrcholem. @param bt nova hodnota typu budovy reprezentovane timto vrcholem */ void setBuildingType(int bt) { this->building_type=bt; }; /** Vrati cenu (ciselnou hodnotu) - na kolik si budovy reprezentovane timto vrcholem AI hrac ceni. */ int getBuildingCost() const { return building_cost; }; /** Nastavi cenu (ciselnou hodnotu) - na kolik si budovy reprezentovane timto vrcholem AI hrac ceni. @param bc nova hodnota oceneni budovy reprezentovane timto vrcholem hracem AI */ void setBuildingCost(int bc) { this->building_cost=bc; }; // TODO: odstranit pokud jde virtual void foo() {}; protected: int world_building_id; ///< World ID budovy reprezentovane timto vrcholem int building_type; ///< typ budovy reprezentovane timto vrcholem int building_cost; ///< cena (ciselna hodnota) - na kolik si budovy reprezentovane timto vrcholem AI hrac ceni }; /** Trida, jenz reprezentuje dynamickou (pohybujici se) entitu ve strategickem grafu. */ class CDynamicEntity : public CStrVertex { public: /** Konstruktor (bezparametricky). */ CDynamicEntity(); /** Konstruktor. @param dip prislusnost vrcholem reprezentovane entity */ CDynamicEntity(TDipOwnership dip); /** Vytvori hranu (spravny typ) od tohoto vrcholu k jinemu vrcholu. @param vref cilovy vrchol strategickeho grafu, se kterym se bude vytvaret hrana @return (CStrEdge*) ukazatel na dynamicky vytvoreny objekt hrany */ virtual CStrEdge* createEdge(CStrVertex* vref); // TODO: odstranit pokud jde virtual void foo() {}; }; /** Trida, jenz reprezentuje jednotku ve strategickem grafu. */ class CUnit : public CDynamicEntity { public: /** Konstruktor (bezparametricky). */ CUnit(); /** Konstruktor. @param dip prislusnost vrcholem reprezentovane jednotky */ CUnit(TDipOwnership dip); TDefendingUnitDesire DefenceDesire; ///< zpusob, jakym jednotka brani braneni /** Vrati World ID jednotky reprezentovane timto vrcholem. */ int getWorldID() const { return world_unit_id; }; /** Nastavi World ID jednotky reprezentovane timto vrcholem. @param world_unit_id nova hodnota World ID jednotky reprezentovane timto vrcholem */ void setWorldID(int world_unit_id) { this->world_unit_id=world_unit_id; }; /** Vrati dosah utoku jednotky reprezentovane timto vrcholem. */ int getFireRange() const { return firerange; }; /** Nastavi dosah utoku jednotky reprezentovane timto vrcholem. @param firerange nova hodnota dosahu utoku jednotky reprezentovane timto vrcholem */ void setFireRange(int firerange) { this->firerange=firerange; }; /** Vrati utocnou silu jednotky reprezentovane timto vrcholem. */ int getAttackPower() const { return attack_power; }; /** Nastavi utocnou silu jednotky reprezentovane timto vrcholem. @param attack_power nova hodnota utocne sily jednotky reprezentovane timto vrcholem */ void setAttackPower(int attack_power) { this->attack_power=attack_power; }; /** Vrati obrannou silu jednotky reprezentovane timto vrcholem. */ int getDefendPower() const { return defend_power; }; /** Nastavi obrannou silu jednotky reprezentovane timto vrcholem. @param defend_power nova hodnota obranne sily jednotky reprezentovane timto vrcholem */ void setDefendPower(int defend_power) { this->defend_power=defend_power; }; /** Vrati celkovou silu jednotky reprezentovane timto vrcholem. */ int getOverallPower() const { return overall_power; }; /** Nastavi celkovou silu jednotky reprezentovane timto vrcholem. @param overall_power nova hodnota celkove sily jednotky reprezentovane timto vrcholem */ void setOverallPower(int overall_power) { this->overall_power=overall_power; }; /** Vrati pomer sily jednotky reprezentovane timto vrcholem vuci sile cele sve armady. */ double getPowerRatio() const { return power_ratio; }; /** Nastavi pomer sily jednotky reprezentovane timto vrcholem vuci sile cele sve armady. @param power_ratio nova hodnota pomeru sily jednotky reprezentovane timto vrcholem vuci sile cele sve armady */ void setPowerRatio(double power_ratio) { this->power_ratio=power_ratio; }; // TODO: odstranit pokud jde virtual void foo() {}; protected: int world_unit_id; ///< World ID jednotky reprezentovane timto vrcholem int firerange; ///< dosah utoku jednotky reprezentovane timto vrcholem int attack_power; ///< utocna sila jednotky reprezentovane timto vrcholem int defend_power; ///< obranna sila jednotky reprezentovane timto vrcholem int overall_power; ///< celkova sila jednotky reprezentovane timto vrcholem double power_ratio; ///< pomer sily jednotky reprezentovane timto vrcholem vuci sile cele sve armady }; /** Trida, jenz reprezentuje obecnou orientovanou hranu mezi dvema vrcholy ve strategickem grafu. */ class CStrEdge { public: int vertex_from; ///< ID zdrojoveho vrcholu hrany ve strategickem grafu int vertex_to; ///< ID ciloveho vrcholu hrany ve strategickem grafu /** Vrati ID teto hrany ve strategickem grafu. */ int getID() const { return id; }; /** Nastavi ID teto hrany ve strategickem grafu. @param id nove ID teto hrany ve strategickem grafu */ void setID(int id) { this->id=id; }; /** Vrati casovou disponibilitu teto hrany ve strategickem grafu. */ int getTimeDisponibility() const { return time_disponibility; }; /** Nastavi casovou disponibilitu teto hrany ve strategickem grafu. @param td nova hodnota casove disponibility teto hrany ve strategickem grafu */ void setTimeDisponibility(int td) { this->time_disponibility=td; }; #ifdef _K_EDITOR_ /** Vrati textovy identifikator dynamickeho jmena instanciovane tridy. */ const char* getClassName(); #endif // TODO: odstranit pokud jde virtual void foo() {}; private: int id; ///< ID teto hrany ve strategickem grafu int time_disponibility; ///< casova disponibilita teto hrany ve strategickem grafu }; /** Trida, jenz reprezentuje utocnou hranu (tj. moznost utoku mezi entitami ve vrcholech, jenz spouje) mezi dvema vrcholy ve strategickem grafu. */ class CAttackEdge : public CStrEdge { public: /** Vrati X-ovou souradnici action pointu teto hrany. */ int getActionPointX() const { return actionPointX; }; /** Nastavi X-ovou souradnici action pointu teto hrany. @param actionPointX nova hodnota X-ove souradnice action pointu teto hrany */ void setActionPointX(int actionPointX) { this->actionPointX=actionPointX; }; /** Vrati Y-ovou souradnici action pointu teto hrany. */ int getActionPointY() const { return actionPointY; }; /** Nastavi Y-ovou souradnici action pointu teto hrany. @param actionPointY nova hodnota Y-ove souradnice action pointu teto hrany */ void setActionPointY(int actionPointY) { this->actionPointY=actionPointY; }; // TODO: odstranit pokud jde virtual void foo() {}; private: int actionPointX; ///< X-ova souradnice action pointu (tj.nejvhodnejsiho bodu, ze ktereho lze utocit entitou v prvnim vrcholu na entitu v druhem vrcholu) hrany ve strategickem grafu int actionPointY; ///< Y-ova souradnice action pointu (tj.nejvhodnejsiho bodu, ze ktereho lze utocit entitou v prvnim vrcholu na entitu v druhem vrcholu) hrany ve strategickem grafu }; /** Trida reprezentujici strategicky graf. */ class CStrGraph { public: /** Konstruktor. @param initPackage sada ukazatelu na struktury Worldu @param player_id World ID AI hrace, pro nejz je graf budovan @param ai_level obtiznost AI hrace, pro nejz je graf budovan */ CStrGraph(TPacket_AI_LetsGo* initPackage,int player_id,PLAYER_TYPE ai_level); /** Destruktor. */ ~CStrGraph(); int enlistVertex(CStrVertex* v); void enlistVertexWithID(CStrVertex* v,int id) throw(E_8K_AI_Strategy_NotUniqueVertexID); void removeVertex(int vertexID) throw(E_8K_AI_Strategy_VertexIDNotFound); int enlistEdge(CStrEdge* e); void enlistEdgeWithID(CStrEdge* e,int id) throw(E_8K_AI_Strategy_NotUniqueEdgeID); void removeEdge(int edgeID) throw(E_8K_AI_Strategy_EdgeIDNotFound); void createEdgesForAllVertices(); void computeGraphEdgesValues(int playerID); CStrEdge* findEdge(int vertex_from_id,int vertex_to_id); CStrVertex* getVertexPointer(int vertexID) throw(E_8K_AI_Strategy_VertexIDNotFound); CStrEdge* getEdgePointer(int edgeID) throw(E_8K_AI_Strategy_EdgeIDNotFound); std::VERTEX_CONTAINER* getVertices(); std::EDGE_CONTAINER* getEdges(); CPlan* generateDefencePlan(int player_ID); int getWholeWealthPrice() const { return whole_wealth_price; }; void setWholeWealthPrice(int whole_wealth_price) { this->whole_wealth_price=whole_wealth_price; }; int getWholePower() const { return whole_power; }; void setWholePower(int whole_power) { this->whole_power=whole_power; }; int countWholePower(); int countWholeWealthPrice(); void computeRatios(); int countMyCities(); int countMyCitiesPayment(); int countMyBuildingsByType(int bType); int* getLandForDefence(int playerID); private: /// Whether to use computer floodfill int rememberFloodFilledMap; /// For which unit_id I do remember the info int rememberedFloodFillForUnit; /// Fills the PrivMarkMap void fillMarkMap(int playerID); ai_ns::pathfind_ns::FLOOD_MASK PrivAllocatedFloodMask;///< Was often reallocated, so I moved it here ai_ns::pathfind_ns::PF_MARKMAP PrivAllocatedMarkMap; ///< dtto int player_id; ///< World ID AI hrace, pro nejz je graf budovan int ai_level_difficulty_constant; ///< obtiznost AI hrace, pro nejz je graf budovan TPacket_AI_LetsGo* SIP; ///< sada ukazatelu na struktury Worldu std::VERTEX_CONTAINER vertices; ///< kontajner s vrcholy reprezentujici jednotlive entity na mape std::EDGE_CONTAINER edges; ///< kontajner s hranami mezi jednotlivymi entitami na mape /** Vytvori hrany v grafu pro dany vrchol. @param verticeID ID vrcholu, pro nejz jsou hrany vytvareny @param both_directions priznak, zdali maji byt vytvareny pouze hrany v jednom smeru, nebo v obema @throw E_8K_AI_Strategy_VertexIDNotFound */ void createEdges(int verticeID,bool both_directions) throw(E_8K_AI_Strategy_VertexIDNotFound); /** Kontroluje, zdali je ID vrcholu pro graf unikatni (tedy, zdali se tam jiz u nejakeho vrcholu nevyskytuje). @param id ID vrcholu return bool priznak, zdali je id vrcholu pro graf unikatni */ bool checkUniqueVerticeID(int id); /** Kontroluje, zdali je ID hrany pro graf unikatni (tedy, zdali se tam jiz u nejake hrany nevyskytuje). @param id ID vrcholu return bool priznak, zdali je id hrany pro graf unikatni */ bool checkUniqueEdgeID(int id); /** Nalezne pro danou jednotku nejvhodnejsi pozici pro braneni staticke entity. @param hexid ID hexu s jednotkou, se kterou se hleda pozice pro braneni @param stEntity ukazatel na vrchol reprezentujici nejakou statickou entitu return int ID hexu nejvhodnejsi pozice pro braneni staticke entity */ int getBestStaticDefensePlaceForUnitOnHexID(int hexid,CStaticEntity* stEntity) throw(E_8K_AI_Strategy_NoUnitPresent); /** Naplni kontajner vsemi hrozbami, ktere zjisti ze strategickeho grafu. */ void fillThreats(); /** Naplni kontajnery potreb a zdroju, ktere zjisti ze strategickeho grafu. */ void fillNeedsAndSources(); /** Provede jednu iteraci prirazeni potrebam zdrojum a zazehnani pripadnych hrozeb. @param threat_disponibility casova disponibilita hrozby (za jak dlouho bude naplnena) @param iteration_no iteracni cyklus (zdali jiz prirazuji v ramci pomeru ceny staticke entity k celkovemu bohatstvi nebo doplnkove) @param current_need potreba (staticka entita), jenz je potreba branit @param current_threat_iterator iterator ukazujici na aktualne resenou hrozbu @param given_plan predavany plan, jemuz jsou pridavany akce a jenz je v prubehu provaden */ void performDefensive(int threat_disponibility,int iteration_no,CStaticEntity* & current_need,std::THREAT_CONTAINER::iterator & current_threat_iterator,CPlan* given_plan); /** Provede doplnkove operace pro braneni. @param given_plan predavany plan, jemuz jsou pridavany akce a jenz je v prubehu provaden */ void performRestDefensive(CPlan* given_plan); std::THREAT_CONTAINER threats[MAX_THREAT_DISPONIBILITY]; ///< pole s kontajnery pro jednotlive hrozby ve strategickem grafu (indexy pole jsou dle casove disponibility hrozeb) std::NEEDS_CONTAINER needs; ///< kontajner pro potreby braneni ve strategickem grafu std::SOURCES_CONTAINER sources; ///< kontajner pro zdroje braneni ve strategickem grafu std::HELPS_CONTAINER needed_helps; ///< kontajner pro potreby pomoci nebranenych nebo nedostatecne branenych potreb ve strategickem grafu std::NON_DEFENDING_TARGETS_CONTAINER non_defending_targets; ///< kontajner s neutocicimi cizimi jednotkami std::NOT_USED_SOURCES_CONTAINER not_used_sources; ///< kontajner s nevyuzitymi zdroji int whole_wealth_price; ///< ciselna hodnota reprezentujici celkove hmotne bohatstvi AI hrace (soucet oceneni vsech jeho statickych entit) - nema nic do cineni s aktualnim stavem jeho penez int whole_power; ///< ciselna hodnota reprezentujici celkovou obrannou silu AI hrace (soucet oceneni sil vsech jeho jednotek urcenych pro obranu) /** Vrati seznam souradnic hexu, z nichz muze utocnik utocit na dany hex. @param playerID World ID AI hrace @param sh souradnice utocnika @param th souradnice hexu, na nejz chce utocnik utocit @throw E_8K_AI_Strategy_NoUnitPresent @return COORDS_ARRAY seznam souradnic hexu, z nichz muze utocnik utocit na dany hex */ COORDS_ARRAY getAttackPossibleHexes(int playerID,COORDS sh,COORDS th) throw(E_8K_AI_Strategy_NoUnitPresent); /** Zjisti souradnice nejblizsiho bodu (tzv. action pointu), ze kterych muze utocnik utocit na dany hex. @param playerID World ID AI hrace @param sh souradnice utocnika @param th souradnice hexu, na nejz chce utocnik utocit @throw E_8K_AI_Strategy_PlayerCantSeeTarget @return COORDS souradnice action pointu */ COORDS getActionPoint(int playerID,COORDS sh,COORDS th) throw(E_8K_AI_Strategy_PlayerCantSeeTarget); }; } // end of namespace "strategizer_ns" } // end of namespace "ai_ns" #endif