From bccda0375af970829208731feda2bb13aea1118a Mon Sep 17 00:00:00 2001 From: drdkad Date: Wed, 22 Jul 2026 10:22:52 +0100 Subject: [PATCH] Correct sparsity violation in representation of behaviour associated with a strategy --- ChangeLog | 3 +++ src/games/game.cc | 7 ++++--- src/games/gametree.cc | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9704c98b4..19e30ae56 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,9 @@ - Implemented bespoke XML parser that handles the subset in the de-facto legacy XML workbook .gbt format; removes dependency on tinyxml. (#897) +### Fixed +- Converting a behavior profile to a strategy profile, and computing pure-strategy payoffs + no longer inserts spurious entries into a strategy's internal action map. ## [16.7.0] - 2026-07-11 diff --git a/src/games/game.cc b/src/games/game.cc index f912c8179..79c5cd7dd 100644 --- a/src/games/game.cc +++ b/src/games/game.cc @@ -96,7 +96,7 @@ void GamePlayerRep::MakeStrategy(const std::map &behav) strategy->m_behav = behav; for (const auto &infoset : m_infosets) { strategy->m_label += (contains(strategy->m_behav, infoset.get())) - ? std::to_string(strategy->m_behav[infoset.get()]) + ? std::to_string(strategy->m_behav.at(infoset.get())) : "*"; } if (strategy->m_label.empty()) { @@ -305,8 +305,9 @@ MixedStrategyProfile::MixedStrategyProfile(const MixedBehaviorProfile &p_p for (const auto &strategy : player->m_strategies) { auto prob = static_cast(1); for (const auto &infoset : player->m_infosets) { - if (strategy->m_behav[infoset.get()] > 0) { - prob *= p_profile[infoset->GetAction(strategy->m_behav[infoset.get()])]; + if (contains(strategy->m_behav, infoset.get()) && + strategy->m_behav.at(infoset.get()) > 0) { + prob *= p_profile[infoset->GetAction(strategy->m_behav.at(infoset.get()))]; } } (*m_rep)[strategy] = prob; diff --git a/src/games/gametree.cc b/src/games/gametree.cc index 535d1db19..84d6ec0fd 100644 --- a/src/games/gametree.cc +++ b/src/games/gametree.cc @@ -1741,7 +1741,7 @@ Rational TreePureStrategyProfileRep::GetPayoff(const GamePlayer &p_player) const for (const auto &player : m_game->GetPlayers()) { for (const auto &infoset : player->GetInfosets()) { try { - behav.SetAction(infoset->GetAction(GetStrategy(player)->m_behav[infoset.get()])); + behav.SetAction(infoset->GetAction(GetStrategy(player)->m_behav.at(infoset.get()))); } catch (std::out_of_range &) { }