diff --git a/tyrant_optimize.cpp b/tyrant_optimize.cpp index f25bc189..bbda2628 100644 --- a/tyrant_optimize.cpp +++ b/tyrant_optimize.cpp @@ -209,42 +209,99 @@ std::string skill_names[num_skills] = "trigger_regen", "weaken", "weaken_all"}; -namespace CardType { -enum CardType { - action, - assault, - commander, - structure, - num_cardtypes -}; -} -std::string cardtype_names[CardType::num_cardtypes]{"action", "assault", "commander", "structure"}; - -enum gamemode_t -{ - fight, - surge, - tournament -}; +struct TargetsAssaults {}; +struct TargetsStructures {}; +struct TargetsCommmander {}; struct true_ {}; struct false_ {}; template -struct skillTriggersRegen { typedef false_ T; }; +struct SkillTraits +{ + // true: single, false: all + typedef true_ TargetsHow; + // true: self, false: opponent + typedef true_ TargetsWho; + typedef TargetsAssaults TargetsWhat; +}; -template<> -struct skillTriggersRegen { typedef true_ T; }; +struct SkillTraitsSelfAssaults +{ + typedef true_ TargetsHow; + typedef true_ TargetsWho; + typedef TargetsAssaults TargetsWhat; +}; -template<> -struct skillTriggersRegen { typedef true_ T; }; +struct SkillTraitsSelfAssaultsAll +{ + typedef false_ TargetsHow; + typedef true_ TargetsWho; + typedef TargetsAssaults TargetsWhat; +}; -template<> -struct skillTriggersRegen { typedef true_ T; }; +struct SkillTraitsEnemyAssaults +{ + typedef true_ TargetsHow; + typedef false_ TargetsWho; + typedef TargetsAssaults TargetsWhat; +}; -template<> -struct skillTriggersRegen { typedef true_ T; }; +struct SkillTraitsEnemyAssaultsAll +{ + typedef false_ TargetsHow; + typedef false_ TargetsWho; + typedef TargetsAssaults TargetsWhat; +}; + +struct SkillTraitsEnemyStructures +{ + typedef true_ TargetsHow; + typedef false_ TargetsWho; + typedef TargetsStructures TargetsWhat; +}; + +struct SkillTraitsEnemyStructuresAll +{ + typedef false_ TargetsHow; + typedef false_ TargetsWho; + typedef TargetsStructures TargetsWhat; +}; + +template<> struct SkillTraits : SkillTraitsSelfAssaults {}; +template<> struct SkillTraits : SkillTraitsSelfAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaults {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsSelfAssaults {}; +template<> struct SkillTraits : SkillTraitsSelfAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaults {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaults {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsSelfAssaults {}; +template<> struct SkillTraits : SkillTraitsSelfAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaults {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaults {}; +template<> struct SkillTraits : SkillTraitsSelfAssaults {}; +template<> struct SkillTraits : SkillTraitsSelfAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsSelfAssaults {}; +template<> struct SkillTraits : SkillTraitsSelfAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsSelfAssaults {}; +template<> struct SkillTraits : SkillTraitsEnemyStructures {}; +template<> struct SkillTraits : SkillTraitsEnemyStructuresAll {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaults {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaultsAll {}; +template<> struct SkillTraits : SkillTraitsSelfAssaults {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaults {}; +template<> struct SkillTraits : SkillTraitsEnemyAssaultsAll {}; + +template struct skillTriggersRegen { typedef false_ T; }; +template<> struct skillTriggersRegen { typedef true_ T; }; +template<> struct skillTriggersRegen { typedef true_ T; }; +template<> struct skillTriggersRegen { typedef true_ T; }; +template<> struct skillTriggersRegen { typedef true_ T; }; enum SkillSourceType { @@ -257,6 +314,24 @@ enum SkillSourceType typedef std::tuple SkillSpec; +namespace CardType { +enum CardType { + action, + assault, + commander, + structure, + num_cardtypes +}; +} +std::string cardtype_names[CardType::num_cardtypes]{"action", "assault", "commander", "structure"}; + +enum gamemode_t +{ + fight, + surge, + tournament +}; + class Card { public: @@ -2017,7 +2092,7 @@ inline bool skill_predicate(CardStatus* c) template<> inline bool skill_predicate(CardStatus* c) -{ return(c->m_faction != bloodthirsty); } +{ return(c->m_hp > 0 && c->m_faction != bloodthirsty); } template<> inline bool skill_predicate(CardStatus* c) @@ -2037,7 +2112,7 @@ inline bool skill_predicate(CardStatus* c) template<> inline bool skill_predicate(CardStatus* c) -{ return(c->m_delay > 0); } +{ return(c->m_hp > 0 && c->m_delay > 0); } template<> inline bool skill_predicate(CardStatus* c) @@ -2199,6 +2274,36 @@ inline unsigned select_fast(Field* fd, CardStatus* src_status, const std::vector return(array_head); } +template +inline unsigned fill_valid_targets_array(Field* fd, const std::vector& cards, const SkillSpec& s) +{ + unsigned array_head = 0; + if(std::get<2>(s) == allfactions) + { + for(auto card: cards) + { + if(skill_predicate(card)) + { + fd->selection_array[array_head] = card; + ++array_head; + } + } + } + else + { + for(auto card: cards) + { + if(card->m_faction == std::get<2>(s) && + skill_predicate(card)) + { + fd->selection_array[array_head] = card; + ++array_head; + } + } + } + return(array_head); +} + template inline unsigned select_rally_like(Field* fd, CardStatus* src_status, const std::vector& cards, const SkillSpec& s) { @@ -2312,6 +2417,39 @@ std::vector& skill_targets(Field* fd, CardStatus* src_status) assert(false); } +template +std::vector& blabla(Field* fd, CardStatus* src_status) +{ + assert(false); +} + +template<> std::vector& blabla(Field* fd, CardStatus* src_status) +{ + return(fd->players[src_status->m_player]->assaults.m_indirect); +} + +template<> std::vector& blabla(Field* fd, CardStatus* src_status) +{ + return(fd->players[src_status->m_chaos ? src_status->m_player : opponent(src_status->m_player)]->assaults.m_indirect); +} + +template<> std::vector& blabla(Field* fd, CardStatus* src_status) +{ + return(fd->players[src_status->m_player]->structures.m_indirect); +} + +template<> std::vector& blabla(Field* fd, CardStatus* src_status) +{ + return(fd->players[src_status->m_chaos ? src_status->m_player : opponent(src_status->m_player)]->structures.m_indirect); +} + +template +std::vector& skill_targets_bis(Field* fd, CardStatus* src_status) +{ + + return(blabla::TargetsWho, typename SkillTraits::TargetsWhat>(fd, src_status)); +} + template<> inline std::vector& skill_targets(Field* fd, CardStatus* src_status) { return(skill_targets_allied_assault(fd, src_status)); } @@ -2368,40 +2506,44 @@ void maybeTriggerRegen(Field* fd) fd->skill_queue.emplace_front(nullptr, std::make_tuple(trigger_regen, 0, allfactions)); } +void perform_skill_enemy(Field* fd, CardStatus* src_status, const SkillSpec& s) +{ +} + template CardStatus* get_target_hostile_fast(Field* fd, CardStatus* src_status, const SkillSpec& s) { - std::vector& cards(skill_targets(fd, src_status)); - unsigned array_head{select_fast(fd, src_status, cards, s)}; + CardStatus* target = nullptr; + std::vector& potential_targets = skill_targets_bis(fd, src_status); + unsigned array_head = fill_valid_targets_array(fd, potential_targets, s); if(array_head > 0) { unsigned rand_index(fd->rand(0, array_head - 1)); - CardStatus* c(fd->selection_array[rand_index]); + target = fd->selection_array[rand_index]; // intercept if(src_status && !src_status->m_chaos) { - CardStatus* intercept_card(nullptr); + bool intercepted = false; if(rand_index > 0) { CardStatus* left_status(fd->selection_array[rand_index-1]); - if(left_status->m_card->m_intercept && left_status->m_index == c->m_index-1) + if(left_status->m_card->m_intercept && left_status->m_index == target->m_index-1) { - intercept_card = left_status; + target = left_status; + intercepted = true; } } - if(rand_index+1 < array_head && !intercept_card) + if(rand_index+1 < array_head && !intercepted) { CardStatus* right_status(fd->selection_array[rand_index+1]); - if(right_status->m_card->m_intercept && right_status->m_index == c->m_index+1) + if(right_status->m_card->m_intercept && right_status->m_index == target->m_index+1) { - intercept_card = right_status; + target = right_status; } } - if(intercept_card) { c = intercept_card; } } - return(c); } - return(nullptr); + return(target); } template @@ -2443,7 +2585,7 @@ void perform_targetted_hostile_fast(Field* fd, CardStatus* src_status, const Ski template void perform_targetted_allied_fast(Field* fd, CardStatus* src_status, const SkillSpec& s) { - std::vector& cards(skill_targets(fd, src_status)); + std::vector& cards(skill_targets_bis(fd, src_status)); unsigned array_head{select_fast(fd, src_status, cards, s)}; if(array_head > 0) { @@ -2470,7 +2612,7 @@ void perform_targetted_allied_fast(Field* fd, CardStatus* src_status, const Skil template void perform_global_hostile_fast(Field* fd, CardStatus* src_status, const SkillSpec& s) { - std::vector& cards(skill_targets(fd, src_status)); + std::vector& cards(skill_targets_bis(fd, src_status)); unsigned array_head{select_fast(fd, src_status, cards, s)}; unsigned payback_count(0); for(unsigned s_index(0); s_index < array_head; ++s_index) @@ -2507,7 +2649,7 @@ void perform_global_hostile_fast(Field* fd, CardStatus* src_status, const SkillS template void perform_global_allied_fast(Field* fd, CardStatus* src_status, const SkillSpec& s) { - std::vector& cards(skill_targets(fd, src_status)); + std::vector& cards(skill_targets_bis(fd, src_status)); unsigned array_head{select_fast(fd, src_status, cards, s)}; for(unsigned s_index(0); s_index < array_head; ++s_index) { @@ -3883,9 +4025,9 @@ int main(int argc, char** argv) skill_table[shock] = perform_shock; skill_table[siege] = perform_targetted_hostile_fast; skill_table[siege_all] = perform_global_hostile_fast; - skill_table[supply] = perform_supply; skill_table[strike] = perform_targetted_hostile_fast; skill_table[strike_all] = perform_global_hostile_fast; + skill_table[supply] = perform_supply; skill_table[summon] = perform_summon; skill_table[trigger_regen] = perform_trigger_regen; skill_table[weaken] = perform_targetted_hostile_fast;