From 715aa24dbd7da826a5180a20129b8e67a0c56365 Mon Sep 17 00:00:00 2001 From: APN-Pucky Date: Wed, 7 Oct 2020 22:26:38 +0200 Subject: [PATCH] Add Scaling opts --- tyrant_optimize.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++ tyrant_optimize.h | 6 ++++++ xml.cpp | 23 ++++++++++++++++++-- 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/tyrant_optimize.cpp b/tyrant_optimize.cpp index 8e2b8608..db0c771f 100644 --- a/tyrant_optimize.cpp +++ b/tyrant_optimize.cpp @@ -178,6 +178,14 @@ void init() eval_iter=8; eval_turn=8; requirement.num_cards.clear(); + for(unsigned i(0); i < Skill::num_skills;++i){ + auto s = static_cast(i); + x_skill_scale[s]=1.0; + n_skill_scale[s]=1.0; + c_skill_scale[s]=1.0; + } + hp_scale = 1.0; + atk_scale = 1.0; #ifndef NQUEST //quest = new Quest(); //TODO Quest bugged in Android now here #endif @@ -2329,6 +2337,49 @@ DeckResults run(int argc, const char** argv) opt_do_reorder = true; argIndex += 1; } + else if (strncmp(argv[argIndex], "scale-opts:", 11) == 0) { + std::string climb_opts_str(argv[argIndex] + 11); + boost::tokenizer> climb_opts{climb_opts_str, boost::char_delimiters_separator{false, ",", ""}}; + for (const auto & opt : climb_opts) + { + const auto dot_pos = opt.find("."); + const auto slash_pos = opt.find("/"); + const bool has_value = (dot_pos != std::string::npos); + if(slash_pos == std::string::npos) + throw std::runtime_error("scale-opts:" + opt + " requires an argument"); + const std::string & opt_type = has_value ? opt.substr(0, dot_pos) : ""; + const std::string opt_name{has_value ? opt.substr(dot_pos + 1,slash_pos-dot_pos-1) : opt.substr(0,slash_pos)}; + const std::string opt_value{ opt.substr(slash_pos + 1) }; + if ((opt_name == "hp") ) + { + hp_scale = atof(opt_value.c_str()); + } + else if ((opt_name == "atk")) + { + atk_scale = atof(opt_value.c_str()); + } + else if (opt_name == "x") + { + x_skill_scale[skill_name_to_id(opt_type)] = atof(opt_value.c_str()); + } + else if (opt_name == "n") + { + n_skill_scale[skill_name_to_id(opt_type)] = atof(opt_value.c_str()); + } + else if (opt_name == "c") + { + c_skill_scale[skill_name_to_id(opt_type)] = atof(opt_value.c_str()); + } + else + { + std::cerr << "Error: Unknown scale option " << opt_name << " of " << opt_type; + if (has_value) + { std::cerr << " (value is: " << opt_value << ")"; } + std::cerr << std::endl; + exit(1); + } + } + } // climbing options else if (strncmp(argv[argIndex], "climb-opts:", 11) == 0) { diff --git a/tyrant_optimize.h b/tyrant_optimize.h index 70e47f00..4ffa326a 100644 --- a/tyrant_optimize.h +++ b/tyrant_optimize.h @@ -24,6 +24,7 @@ struct Requirement #else #define EXTERN extern #endif + namespace tuo { EXTERN Cards all_cards; EXTERN unsigned opt_num_threads; @@ -61,6 +62,11 @@ namespace tuo { EXTERN unsigned eval_iter; EXTERN unsigned eval_turn; EXTERN Requirement requirement; + EXTERN double hp_scale; + EXTERN double atk_scale; + EXTERN std::map x_skill_scale; + EXTERN std::map n_skill_scale; + EXTERN std::map c_skill_scale; #ifndef NQUEST EXTERN Quest quest; #endif diff --git a/xml.cpp b/xml.cpp index 401cb856..735c44f9 100644 --- a/xml.cpp +++ b/xml.cpp @@ -12,6 +12,7 @@ #include "cards.h" #include "deck.h" #include "tyrant.h" +#include "tyrant_optimize.h" //---------------------- $20 cards.xml parsing --------------------------------- // Sets: 1 enclave; 2 nexus; 3 blight; 4 purity; 5 homeworld; // 6 phobos; 7 phobos aftermath; 8 awakening @@ -152,6 +153,7 @@ bool parse_file(const std::string & filename, std::vector& buffer, xml_doc //------------------------------------------------------------------------------ void parse_card_node(Cards& all_cards, Card* card, xml_node<>* card_node) { + double eps = 1e-4; xml_node<>* id_node(card_node->first_node("id")); xml_node<>* card_id_node = card_node->first_node("card_id"); assert(id_node || card_id_node); @@ -171,8 +173,15 @@ void parse_card_node(Cards& all_cards, Card* card, xml_node<>* card_node) if (name_node) { card->m_name = name_node->value(); } if (level_node) { card->m_level = atoi(level_node->value()); } if (fusion_level_node) { card->m_fusion_level = atoi(fusion_level_node->value()); } - if (attack_node) { card->m_attack = atoi(attack_node->value()); } - if (health_node) { card->m_health = atoi(health_node->value()); } + if (attack_node) { card->m_attack = atoi(attack_node->value()); + if(abs(1-atk_scale)>eps) + card->m_attack = ceil(card->m_attack/(atk_scale)); +} + if (health_node) { card->m_health = atoi(health_node->value()); + if(abs(1-hp_scale)>eps) + card->m_health = ceil(card->m_health/(hp_scale)); + + } if (cost_node) { card->m_delay = atoi(cost_node->value()); } if (id_node) { @@ -314,6 +323,16 @@ void parse_card_node(Cards& all_cards, Card* card, xml_node<>* card_node) auto s2 = skill_target_skill(skill_node, "s2"); bool all = skill_node->first_attribute("all"); auto card_id = node_value(skill_node, "card_id", 0); + //scaling + if(abs(1-x_skill_scale[Skill::no_skill]*x_skill_scale[skill_id])>eps) + x = ceil(x/(x_skill_scale[Skill::no_skill]*x_skill_scale[skill_id])); + if(abs(1-n_skill_scale[Skill::no_skill]*n_skill_scale[skill_id])>eps) + n = ceil(n/(n_skill_scale[Skill::no_skill]*n_skill_scale[skill_id])); + if(abs(1-c_skill_scale[Skill::no_skill]*c_skill_scale[skill_id])>eps) + c = ceil(c/(c_skill_scale[Skill::no_skill]*c_skill_scale[skill_id])); + + + card->add_skill(trig, skill_id, x, y, n, c, s, s2, all, card_id); } all_cards.all_cards.push_back(card);