From adafc6d033f1fad9350d821dcd586dcf5bedeb8f Mon Sep 17 00:00:00 2001 From: Alexander Puck Neuwirth Date: Fri, 2 Jan 2026 18:28:51 +0100 Subject: [PATCH 1/5] init strap debug mode --- CMakeLists.txt | 2 +- make/Makefile-debug.linux | 2 +- make/Makefile-debug.osx | 2 +- make/Makefile-debug.windows | 2 +- make/Makefile-test.linux | 2 +- make/Makefile-test.windows | 2 +- make/Makefile.intel | 2 +- make/Makefile.linux | 4 ++-- make/Makefile.osx | 2 +- make/Makefile.windows | 2 +- sim.cpp | 43 +++++++++++++++++++++++++++++++++++++ tyrant.cpp | 1 + tyrant.h | 10 +++++++++ tyrant_optimize.cpp | 4 ++++ 14 files changed, 69 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f6dc666..c651dfe1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.12) # partial module - included by src/cmake/CMakeLists.txt #set(TGT test-${PKG}-cmake) -set( CMAKE_CXX_STANDARD 14 ) +set( CMAKE_CXX_STANDARD 17 ) if (CMAKE_GENERATOR MATCHES "Visual Studio") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /W3 /wd4061 /wd4100 /wd4820 /wd4514") else() diff --git a/make/Makefile-debug.linux b/make/Makefile-debug.linux index e9c67711..77e8eae7 100644 --- a/make/Makefile-debug.linux +++ b/make/Makefile-debug.linux @@ -10,7 +10,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++14 -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' +CPPFLAGS := -Wall -Werror -std=gnu++17 -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -lpthread all: $(MAIN) diff --git a/make/Makefile-debug.osx b/make/Makefile-debug.osx index fe618ef2..4c41b900 100644 --- a/make/Makefile-debug.osx +++ b/make/Makefile-debug.osx @@ -11,7 +11,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=c++14 -stdlib=libc++ -Ofast -g -I/usr/local/include -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' +CPPFLAGS := -Wall -Werror -std=c++17 -stdlib=libc++ -Ofast -g -I/usr/local/include -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' LDFLAGS := -L/usr/local/lib -lboost_system-mt -lboost_thread-mt -lboost_filesystem-mt -lboost_regex-mt -lboost_timer-mt all: $(MAIN) diff --git a/make/Makefile-debug.windows b/make/Makefile-debug.windows index daf465ae..2bbad57e 100644 --- a/make/Makefile-debug.windows +++ b/make/Makefile-debug.windows @@ -10,7 +10,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -g -DNTIMER -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' +CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -g -DNTIMER -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer all: $(MAIN) diff --git a/make/Makefile-test.linux b/make/Makefile-test.linux index 9370e59a..cf2ca90a 100644 --- a/make/Makefile-test.linux +++ b/make/Makefile-test.linux @@ -10,7 +10,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--test"' -DTEST -DNQUEST -fprofile-arcs -ftest-coverage +CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--test"' -DTEST -DNQUEST -fprofile-arcs -ftest-coverage LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -fprofile-arcs -lpthread all: $(MAIN) diff --git a/make/Makefile-test.windows b/make/Makefile-test.windows index 0425dc4c..9adea0eb 100644 --- a/make/Makefile-test.windows +++ b/make/Makefile-test.windows @@ -10,7 +10,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--test"' -DTEST -DNQUEST -DNTIMER -fprofile-arcs -ftest-coverage +CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--test"' -DTEST -DNQUEST -DNTIMER -fprofile-arcs -ftest-coverage LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -lboost_unit_test_framework -fprofile-arcs all: $(MAIN) diff --git a/make/Makefile.intel b/make/Makefile.intel index e85e5e7f..21df906d 100644 --- a/make/Makefile.intel +++ b/make/Makefile.intel @@ -11,7 +11,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -xHost +CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -xHost LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer all: $(MAIN) diff --git a/make/Makefile.linux b/make/Makefile.linux index 18a6964c..104888bd 100644 --- a/make/Makefile.linux +++ b/make/Makefile.linux @@ -12,10 +12,10 @@ endif endif -CPPFLAGSN := -Wall -Werror -std=gnu++14 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -fopenmp -DNTIMER +CPPFLAGSN := -Wall -Werror -std=gnu++17 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -fopenmp -DNTIMER LDFLAGSN := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -lpthread -lgomp -CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -DNTIMER +CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -DNTIMER LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -lpthread all: $(MAIN) diff --git a/make/Makefile.osx b/make/Makefile.osx index c619214d..dcc238f8 100644 --- a/make/Makefile.osx +++ b/make/Makefile.osx @@ -11,7 +11,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=c++14 -stdlib=libc++ -Ofast -I/usr/local/include -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' +CPPFLAGS := -Wall -Werror -std=c++17 -stdlib=libc++ -Ofast -I/usr/local/include -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' LDFLAGS := -L/usr/local/lib -lboost_system-mt -lboost_thread-mt -lboost_filesystem-mt -lboost_regex-mt -lboost_timer-mt all: $(MAIN) diff --git a/make/Makefile.windows b/make/Makefile.windows index 696e537f..fce4cee8 100644 --- a/make/Makefile.windows +++ b/make/Makefile.windows @@ -11,7 +11,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -DNDEBUG -DNTIMER -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' +CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -DNDEBUG -DNTIMER -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer all: $(MAIN) diff --git a/sim.cpp b/sim.cpp index 16be9c56..ea8e5beb 100644 --- a/sim.cpp +++ b/sim.cpp @@ -61,6 +61,12 @@ inline std::string status_description(const CardStatus* status) return status->description(); } //------------------------------------------------------------------------------ +inline std::string strap_string(const CardStatus* status) +{ + // Replace ' ' with '_' for strap key + return boost::replace_all_copy(status->m_card->m_name, " ", "_"); +} +//------------------------------------------------------------------------------ template inline unsigned Field::make_selection_array(CardsIter first, CardsIter last, Functor f) { @@ -138,6 +144,14 @@ inline void Field::finalize_action() if (barrier_base) { unsigned protect_value = barrier_base * unit_it->second; + _DEBUG_STRAP( + "turn", turn, + "active_player", tapi, + "barrier_"+strap_string(dmg_status), 1.0, + "barrier_protect", protect_value, + "barrier_base", barrier_base, + "barrier_times", unit_it->second + ); _DEBUG_MSG(1, "%s protects itself for %u (barrier %u x %u damage taken)\n", status_description(dmg_status).c_str(), protect_value, barrier_base, unit_it->second); dmg_status->m_protected += protect_value; @@ -566,6 +580,13 @@ void prepend_on_death(Field* fd, bool paybacked=false) { avenge_value = (avenge_value + 1) / 2; } + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "avenge_"+strap_string(adj_status), 1.0, + "avenge_value", avenge_value, + "avenge_half", (std::abs((signed)from_idx - (signed)host_idx) > 1 ? 1 : 0) + ); _DEBUG_MSG(1, "%s activates %sAvenge %u\n", status_description(adj_status).c_str(), (std::abs((signed)from_idx - (signed)host_idx) > 1 ? "Half-" : ""), @@ -1891,6 +1912,13 @@ struct PerformAttack if(!reduced_desc.empty()) { desc += "-[" + reduced_desc + "]"; } if(!desc.empty()) { desc += "=" + tuo::to_string(att_dmg); } else { assert(att_dmg == pre_modifier_dmg); } + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "attacker_"+strap_string(att_status), 1.0, + "defender_"+strap_string(def_status), 1.0, + "pre_modifier_dmg", pre_modifier_dmg + ); _DEBUG_MSG(1, "%s attacks %s for %u%s damage\n", status_description(att_status).c_str(), status_description(def_status).c_str(), pre_modifier_dmg, desc.c_str()); @@ -2634,6 +2662,14 @@ inline bool check_and_perform_skill(Field* fd, CardStatus* src, CardStatus* dst, status_description(dst).c_str()); return(false); } + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "skill_source_"+strap_string(src), + "skill_target_"+strap_string(dst), + "skill_"+skill_names[s.id], + "skill_x", s.x + ); _DEBUG_MSG(1, "%s %s on %s\n", status_description(src).c_str(), skill_short_description(fd->cards, s).c_str(), status_description(dst).c_str()); @@ -2810,6 +2846,13 @@ void perform_counter(Field* fd, CardStatus* att_status, CardStatus* def_status) fd->inc_counter(QuestType::skill_damage, Skill::counter, 0, counter_dmg); } #endif + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "counter_attacker_"+strap_string(att_status), 1.0, + "counter_defender_"+strap_string(def_status), 1.0, + "counter_damage", counter_dmg + ); _DEBUG_MSG(1, "%s takes %u counter damage from %s\n", status_description(att_status).c_str(), counter_dmg, status_description(def_status).c_str()); diff --git a/tyrant.cpp b/tyrant.cpp index 84df0e58..715cfc8f 100644 --- a/tyrant.cpp +++ b/tyrant.cpp @@ -78,4 +78,5 @@ std::string decktype_names[DeckType::num_decktypes]{"Deck", "Mission", "Raid", " signed debug_print(0); unsigned debug_cached(0); bool debug_line(false); +bool debug_strap(false); std::string debug_str(""); diff --git a/tyrant.h b/tyrant.h index bcaba134..40c07264 100644 --- a/tyrant.h +++ b/tyrant.h @@ -13,6 +13,7 @@ #include #include #include +#include #ifdef _MSC_VER #define __builtin_expect(x, y) (x) @@ -462,13 +463,21 @@ inline uint8_t byte_bits_count(uint8_t i) i = (i & 0x33) + ((i >> 2) & 0x33); return (i + (i >> 4)) & 0x0F; } +template +inline void strap(const T& first, const Ts&... rest) { + std::cout << "@strap " << first; + ((std::cout << ' ' << rest), ...); + std::cout << std::endl << std::flush; +} //---------------------- Debugging stuff --------------------------------------- extern signed debug_print; extern unsigned debug_cached; extern bool debug_line; +extern bool debug_strap; extern std::string debug_str; #ifndef NDEBUG +#define _DEBUG_STRAP(...) if(debug_strap)strap(__VA_ARGS__); #define _DEBUG_MSG(v, format, ...) \ { \ if(__builtin_expect(debug_print >= v, false)) \ @@ -494,6 +503,7 @@ extern std::string debug_str; } #define _DEBUG_ASSERT(expr) { assert(expr); } #else +#define _DEBUG_STRAP(...) #define _DEBUG_MSG(v, format, ...) #define _DEBUG_SELECTION(format, ...) #define _DEBUG_ASSERT(expr) diff --git a/tyrant_optimize.cpp b/tyrant_optimize.cpp index 28eb1d5f..e8da2af2 100644 --- a/tyrant_optimize.cpp +++ b/tyrant_optimize.cpp @@ -3146,6 +3146,10 @@ DeckResults run(int argc, const char **argv) { ++debug_print; } + else if (strcmp(argv[argIndex], "strap") == 0) + { + debug_strap = true; + } else if (strcmp(argv[argIndex], "vip") == 0) { if (check_input_amount(argc, argv, argIndex, 1)) From 5e996e93f69fce4630ff86442b596e27219887dc Mon Sep 17 00:00:00 2001 From: Alexander Puck Neuwirth Date: Fri, 2 Jan 2026 21:37:13 +0100 Subject: [PATCH 2/5] strap more data --- sim.cpp | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 130 insertions(+), 9 deletions(-) diff --git a/sim.cpp b/sim.cpp index ea8e5beb..b6c8a614 100644 --- a/sim.cpp +++ b/sim.cpp @@ -64,7 +64,9 @@ inline std::string status_description(const CardStatus* status) inline std::string strap_string(const CardStatus* status) { // Replace ' ' with '_' for strap key - return boost::replace_all_copy(status->m_card->m_name, " ", "_"); + std::string result = boost::replace_all_copy(status->m_card->m_name, " ", "_"); + boost::replace_all(result, "'", "_"); + return result; } //------------------------------------------------------------------------------ template @@ -820,6 +822,12 @@ void evaluate_skills(Field* fd, CardStatus* status, const std::vector fd->inc_counter(QuestType::skill_use, Skill::flurry); } #endif + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "flurry_"+strap_string(status), 1.0, + "flurry_count", status->skill_base_value(Skill::flurry) + ); _DEBUG_MSG(1, "%s activates Flurry x %d\n", status_description(status).c_str(), status->skill_base_value(Skill::flurry)); num_actions += status->skill_base_value(Skill::flurry); @@ -1512,12 +1520,24 @@ void turn_end_phase(Field* fd) fd->inc_counter(QuestType::skill_damage, Skill::poison, 0, poison_dmg); } #endif + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "poison_damage_"+strap_string(&status), 1.0, + "poison_damage", poison_dmg + ); _DEBUG_MSG(1, "%s takes poison damage %u\n", status_description(&status).c_str(), poison_dmg); remove_hp(fd, &status, poison_dmg); // simultaneous } } else { unsigned poison_dmg = status.m_poisoned; + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "poison_damage_"+strap_string(&status), 1.0, + "poison_damage", poison_dmg + ); _DEBUG_MSG(1, "%s takes poison damage %u\n", status_description(&status).c_str(), poison_dmg); remove_hp(fd, &status, poison_dmg); // simultaneous status.m_poisoned = status.m_poisoned - (poison_dmg+1)/2; @@ -1915,9 +1935,9 @@ struct PerformAttack _DEBUG_STRAP( "turn", fd->turn, "active_player", fd->tapi, - "attacker_"+strap_string(att_status), 1.0, - "defender_"+strap_string(def_status), 1.0, - "pre_modifier_dmg", pre_modifier_dmg + "attack_attacker_"+strap_string(att_status), 1.0, + "attack_defender_"+strap_string(def_status), 1.0, + "attack_damage", pre_modifier_dmg ); _DEBUG_MSG(1, "%s attacks %s for %u%s damage\n", status_description(att_status).c_str(), @@ -2657,6 +2677,14 @@ inline bool check_and_perform_skill(Field* fd, CardStatus* src, CardStatus* dst, if (is_evadable && (dst->m_evaded < dst->skill(Skill::evade))) { ++ dst->m_evaded; + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "evade_source_"+strap_string(src),1.0, + "evade_destination_"+strap_string(dst),1.0, + "evade_skill_"+skill_names[s.id],1.0, + "evade_skill_x",s.x, + ); _DEBUG_MSG(1, "%s %s on %s but it evades\n", status_description(src).c_str(), skill_short_description(fd->cards, s).c_str(), status_description(dst).c_str()); @@ -2665,9 +2693,9 @@ inline bool check_and_perform_skill(Field* fd, CardStatus* src, CardStatus* dst, _DEBUG_STRAP( "turn", fd->turn, "active_player", fd->tapi, - "skill_source_"+strap_string(src), - "skill_target_"+strap_string(dst), - "skill_"+skill_names[s.id], + "skill_source_"+strap_string(src),1.0, + "skill_target_"+strap_string(dst),1.0, + "skill_"+skill_names[s.id],1.0, "skill_x", s.x ); _DEBUG_MSG(1, "%s %s on %s\n", @@ -2686,6 +2714,14 @@ inline bool check_and_perform_skill(Field* fd, CardStatus* src, CardStatus* dst, && skill_check(fd, src, src)) { ++ dst->m_tributed; + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "tribute_source_"+strap_string(dst),1.0, + "tribute_destination_"+strap_string(src),1.0, + "tribute_skill_"+skill_names[s.id],1.0, + "tribute_skill_x",s.x, + ); _DEBUG_MSG(1, "%s tributes %s back to %s\n", status_description(dst).c_str(), skill_short_description(fd->cards, s).c_str(), status_description(src).c_str()); @@ -2750,6 +2786,13 @@ void perform_mark(Field* fd, CardStatus* att_status, CardStatus* def_status) // Increase Mark-counter unsigned mark_base = att_status->skill(Skill::mark); if(mark_base && skill_check(fd,att_status,def_status)) { + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "mark_attacker_"+strap_string(att_status), 1.0, + "mark_defender_"+strap_string(def_status), 1.0, + "mark_value", mark_base + ); _DEBUG_MSG(1, "%s marks %s for %u\n", status_description(att_status).c_str(), status_description(def_status).c_str(), mark_base); def_status->m_marked += mark_base; @@ -2809,6 +2852,13 @@ void perform_poison(Field* fd, CardStatus* att_status, CardStatus* def_status) if (is_alive(att_status) && def_status->has_skill(Skill::poison)) { unsigned poison_value = def_status->skill(Skill::poison); + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "poison_attacker_"+strap_string(att_status),1.0, + "poison_defender_"+strap_string(def_status),1.0, + "poison_value", poison_value + ); _DEBUG_MSG(1, "%s gets poisoned by %u from %s\n", status_description(att_status).c_str(), poison_value, status_description(def_status).c_str()); @@ -2824,6 +2874,13 @@ void perform_corrosive(Field* fd, CardStatus* att_status, CardStatus* def_status if (corrosive_value > att_status->m_corroded_rate) { // perform_skill_corrosive + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "corrosive_attacker_"+strap_string(att_status), 1.0, + "corrosive_defender_"+strap_string(def_status), 1.0, + "corrosive_value", corrosive_value + ); _DEBUG_MSG(1, "%s corrodes %s by %u\n", status_description(def_status).c_str(), status_description(att_status).c_str(), corrosive_value); @@ -2928,6 +2985,13 @@ void PerformAttack::perform_swipe_drain(Field* fd, CardStatus // def_status->protected_value()); unsigned remaining_dmg = remove_absorption(fd,adj_status,swipe_value + drain_value + adj_status->m_enfeebled); remaining_dmg = safe_minus(remaining_dmg,adj_status->protected_value()); + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "swipe_attacker_"+strap_string(att_status),1.0, + "swipe_defender_"+strap_string(adj_status),1.0, + "swipe_damage", remaining_dmg + ); _DEBUG_MSG(1, "%s swipes %s for %u damage\n", status_description(att_status).c_str(), status_description(adj_status).c_str(), remaining_dmg); @@ -2937,6 +3001,12 @@ void PerformAttack::perform_swipe_drain(Field* fd, CardStatus } if (drain_value && skill_check(fd, att_status, nullptr)) { + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "drain_attacker_"+strap_string(att_status),1.0, + "drain_amount", drain_total_dmg + ); _DEBUG_MSG(1, "%s drains %u hp\n", status_description(att_status).c_str(), drain_total_dmg); att_status->add_hp(drain_total_dmg); @@ -2961,6 +3031,13 @@ void perform_hunt(Field* fd, CardStatus* att_status, CardStatus* def_status) { { unsigned remaining_dmg = remove_absorption(fd,hunted_status,hunt_value + hunted_status->m_enfeebled); remaining_dmg = safe_minus(remaining_dmg,hunted_status->protected_value()); + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "hunt_attacker_"+strap_string(att_status),1.0, + "hunt_defender_"+strap_string(hunted_status),1.0, + "hunt_damage", remaining_dmg + ); _DEBUG_MSG(1, "%s hunts %s for %u damage\n", status_description(att_status).c_str(), status_description(hunted_status).c_str(), remaining_dmg); @@ -2985,6 +3062,7 @@ void perform_subdue(Field* fd, CardStatus* att_status, CardStatus* def_status) unsigned subdue_value = def_status->skill(Skill::subdue); if (__builtin_expect(subdue_value, false)) { + _DEBUG_MSG(1, "%s subdues %s by %u\n", status_description(def_status).c_str(), status_description(att_status).c_str(), subdue_value); @@ -2994,6 +3072,14 @@ void perform_subdue(Field* fd, CardStatus* att_status, CardStatus* def_status) { att_status->m_temp_attack_buff -= att_status->calc_attack_power(); } + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "subdue_attacker_"+strap_string(att_status),1.0, + "subdue_defender_"+strap_string(def_status),1.0, + "subdue_value", subdue_value, + "subdue_hp_loss", safe_minus(att_status->m_hp , att_status->max_hp()) + ); if (att_status->m_hp > att_status->max_hp()) { _DEBUG_MSG(1, "%s loses %u HP due to subdue (max hp: %u)\n", @@ -3087,6 +3173,13 @@ bool check_and_perform_inhibit(Field* fd, CardStatus* att_status,CardStatus* def unsigned inhibit_value = att_status->skill(Skill::inhibit); if (inhibit_value > def_status->m_inhibited && skill_check(fd, att_status, def_status)) { + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "inhibit_attacker_"+strap_string(att_status),1.0, + "inhibit_defender_"+strap_string(def_status),1.0, + "inhibit_value", inhibit_value + ); _DEBUG_MSG(1, "%s inhibits %s by %u\n", status_description(att_status).c_str(), status_description(def_status).c_str(), inhibit_value); @@ -3100,6 +3193,13 @@ bool check_and_perform_sabotage(Field* fd, CardStatus* att_status, CardStatus* d unsigned sabotage_value = att_status->skill(Skill::sabotage); if (sabotage_value > def_status->m_sabotaged && skill_check(fd, att_status, def_status)) { + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "sabotage_attacker_"+strap_string(att_status),1.0, + "sabotage_defender_"+strap_string(def_status),1.0, + "sabotage_value", sabotage_value + ); _DEBUG_MSG(1, "%s sabotages %s by %u\n", status_description(att_status).c_str(), status_description(def_status).c_str(), sabotage_value); @@ -3112,6 +3212,13 @@ bool check_and_perform_disease(Field* fd, CardStatus* att_status,CardStatus* def { unsigned disease_base = att_status->skill(Skill::disease); if(disease_base && skill_check(fd, att_status, def_status)) { + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "disease_attacker_"+strap_string(att_status),1.0, + "disease_defender_"+strap_string(def_status),1.0, + "disease_value", disease_base + ); _DEBUG_MSG(1, "%s diseases %s for %u\n", status_description(att_status).c_str(), status_description(def_status).c_str(), disease_base); def_status->m_diseased += disease_base; @@ -3412,11 +3519,17 @@ void perform_targetted_hostile_fast(Field* fd, CardStatus* src, const SkillSpec& } // apply revenged skill -#ifndef NDEBUG + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "revenger_"+strap_string(pb_status), 1.0, + "revenged_target_"+strap_string(target_status), 1.0, + "revenged_skill_"+skill_names[skill_id], 1.0, + "revenged_skill_value", s.x + ); _DEBUG_MSG(1, "%s Revenge (to %s) %s on %s\n", status_description(pb_status).c_str(), target_desc, skill_short_description(fd->cards, s).c_str(), status_description(target_status).c_str()); -#endif perform_skill(fd, pb_status, target_status, s); ++ revenged_count; @@ -3465,6 +3578,14 @@ void perform_targetted_hostile_fast(Field* fd, CardStatus* src, const SkillSpec& } // apply paybacked skill + _DEBUG_STRAP( + "turn", fd->turn, + "active_player", fd->tapi, + "paybacker_"+strap_string(pb_status), 1.0, + "paybacked_target_"+strap_string(src), 1.0, + "paybacked_skill_"+skill_names[skill_id], 1.0, + "paybacked_skill_value", s.x + ); _DEBUG_MSG(1, "%s Payback %s on %s\n", status_description(pb_status).c_str(), skill_short_description(fd->cards, s).c_str(), status_description(src).c_str()); perform_skill(fd, pb_status, src, s); From 2cb7564880ed313f8a62ccbb3b24131ccb9c005e Mon Sep 17 00:00:00 2001 From: Alexander Puck Neuwirth Date: Fri, 2 Jan 2026 21:45:44 +0100 Subject: [PATCH 3/5] fix typpo --- sim.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim.cpp b/sim.cpp index b6c8a614..8522e9be 100644 --- a/sim.cpp +++ b/sim.cpp @@ -2683,7 +2683,7 @@ inline bool check_and_perform_skill(Field* fd, CardStatus* src, CardStatus* dst, "evade_source_"+strap_string(src),1.0, "evade_destination_"+strap_string(dst),1.0, "evade_skill_"+skill_names[s.id],1.0, - "evade_skill_x",s.x, + "evade_skill_x",s.x ); _DEBUG_MSG(1, "%s %s on %s but it evades\n", status_description(src).c_str(), skill_short_description(fd->cards, s).c_str(), From 9e0ab86a738dee5b690266afc55098a288258fde Mon Sep 17 00:00:00 2001 From: Alexander Puck Neuwirth Date: Fri, 2 Jan 2026 21:51:27 +0100 Subject: [PATCH 4/5] typo2 --- sim.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sim.cpp b/sim.cpp index 8522e9be..a757bbd6 100644 --- a/sim.cpp +++ b/sim.cpp @@ -2720,7 +2720,7 @@ inline bool check_and_perform_skill(Field* fd, CardStatus* src, CardStatus* dst, "tribute_source_"+strap_string(dst),1.0, "tribute_destination_"+strap_string(src),1.0, "tribute_skill_"+skill_names[s.id],1.0, - "tribute_skill_x",s.x, + "tribute_skill_x",s.x ); _DEBUG_MSG(1, "%s tributes %s back to %s\n", status_description(dst).c_str(), skill_short_description(fd->cards, s).c_str(), From 624ffc3848dffdb74f8de0618a01bc982eaf47a0 Mon Sep 17 00:00:00 2001 From: Alexander Puck Neuwirth Date: Fri, 2 Jan 2026 22:05:01 +0100 Subject: [PATCH 5/5] no more need for std-17 --- make/Makefile-debug.linux | 2 +- make/Makefile-debug.osx | 2 +- make/Makefile-debug.windows | 2 +- make/Makefile-test.linux | 2 +- make/Makefile-test.windows | 2 +- make/Makefile.intel | 2 +- make/Makefile.linux | 4 ++-- make/Makefile.osx | 2 +- make/Makefile.windows | 2 +- tyrant.h | 8 +++++++- 10 files changed, 17 insertions(+), 11 deletions(-) diff --git a/make/Makefile-debug.linux b/make/Makefile-debug.linux index 77e8eae7..e9c67711 100644 --- a/make/Makefile-debug.linux +++ b/make/Makefile-debug.linux @@ -10,7 +10,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++17 -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' +CPPFLAGS := -Wall -Werror -std=gnu++14 -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -lpthread all: $(MAIN) diff --git a/make/Makefile-debug.osx b/make/Makefile-debug.osx index 4c41b900..fe618ef2 100644 --- a/make/Makefile-debug.osx +++ b/make/Makefile-debug.osx @@ -11,7 +11,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=c++17 -stdlib=libc++ -Ofast -g -I/usr/local/include -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' +CPPFLAGS := -Wall -Werror -std=c++14 -stdlib=libc++ -Ofast -g -I/usr/local/include -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' LDFLAGS := -L/usr/local/lib -lboost_system-mt -lboost_thread-mt -lboost_filesystem-mt -lboost_regex-mt -lboost_timer-mt all: $(MAIN) diff --git a/make/Makefile-debug.windows b/make/Makefile-debug.windows index 2bbad57e..daf465ae 100644 --- a/make/Makefile-debug.windows +++ b/make/Makefile-debug.windows @@ -10,7 +10,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -g -DNTIMER -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' +CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -g -DNTIMER -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--debug"' LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer all: $(MAIN) diff --git a/make/Makefile-test.linux b/make/Makefile-test.linux index cf2ca90a..9370e59a 100644 --- a/make/Makefile-test.linux +++ b/make/Makefile-test.linux @@ -10,7 +10,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--test"' -DTEST -DNQUEST -fprofile-arcs -ftest-coverage +CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--test"' -DTEST -DNQUEST -fprofile-arcs -ftest-coverage LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -fprofile-arcs -lpthread all: $(MAIN) diff --git a/make/Makefile-test.windows b/make/Makefile-test.windows index 9adea0eb..0425dc4c 100644 --- a/make/Makefile-test.windows +++ b/make/Makefile-test.windows @@ -10,7 +10,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--test"' -DTEST -DNQUEST -DNTIMER -fprofile-arcs -ftest-coverage +CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -g -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)--test"' -DTEST -DNQUEST -DNTIMER -fprofile-arcs -ftest-coverage LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -lboost_unit_test_framework -fprofile-arcs all: $(MAIN) diff --git a/make/Makefile.intel b/make/Makefile.intel index 21df906d..e85e5e7f 100644 --- a/make/Makefile.intel +++ b/make/Makefile.intel @@ -11,7 +11,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -xHost +CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -xHost LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer all: $(MAIN) diff --git a/make/Makefile.linux b/make/Makefile.linux index 104888bd..18a6964c 100644 --- a/make/Makefile.linux +++ b/make/Makefile.linux @@ -12,10 +12,10 @@ endif endif -CPPFLAGSN := -Wall -Werror -std=gnu++17 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -fopenmp -DNTIMER +CPPFLAGSN := -Wall -Werror -std=gnu++14 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -fopenmp -DNTIMER LDFLAGSN := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -lpthread -lgomp -CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -DNTIMER +CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' -DNTIMER LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer -lpthread all: $(MAIN) diff --git a/make/Makefile.osx b/make/Makefile.osx index dcc238f8..c619214d 100644 --- a/make/Makefile.osx +++ b/make/Makefile.osx @@ -11,7 +11,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=c++17 -stdlib=libc++ -Ofast -I/usr/local/include -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' +CPPFLAGS := -Wall -Werror -std=c++14 -stdlib=libc++ -Ofast -I/usr/local/include -DNDEBUG -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' LDFLAGS := -L/usr/local/lib -lboost_system-mt -lboost_thread-mt -lboost_filesystem-mt -lboost_regex-mt -lboost_timer-mt all: $(MAIN) diff --git a/make/Makefile.windows b/make/Makefile.windows index fce4cee8..696e537f 100644 --- a/make/Makefile.windows +++ b/make/Makefile.windows @@ -11,7 +11,7 @@ ${warning "VERSION is not set (USING NO VERSION instead), use make VERSION=vX.XX endif endif -CPPFLAGS := -Wall -Werror -std=gnu++17 -Ofast -DNDEBUG -DNTIMER -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' +CPPFLAGS := -Wall -Werror -std=gnu++14 -Ofast -DNDEBUG -DNTIMER -DNQUEST -DTYRANT_OPTIMIZER_VERSION='"$(VERSION)"' LDFLAGS := -lboost_system -lboost_thread -lboost_filesystem -lboost_regex -lboost_timer all: $(MAIN) diff --git a/tyrant.h b/tyrant.h index 40c07264..46a1992b 100644 --- a/tyrant.h +++ b/tyrant.h @@ -457,16 +457,22 @@ std::string to_string(const T val) return s.str(); } } + inline uint8_t byte_bits_count(uint8_t i) { i = i - ((i >> 1) & 0x55); i = (i & 0x33) + ((i >> 2) & 0x33); return (i + (i >> 4)) & 0x0F; } + template inline void strap(const T& first, const Ts&... rest) { std::cout << "@strap " << first; - ((std::cout << ' ' << rest), ...); + // Trick to expand the parameter pack without fold expressions + // same as: ((std::cout << ' ' << rest), ...); + // but that does not work unless >C++17 + using expander = int[]; + (void)expander{0, ((std::cout << ' ' << rest), 0)...}; std::cout << std::endl << std::flush; }