@@ -32,51 +32,48 @@ namespace Gambit {
3232// class StrategySupportProfile
3333// ===========================================================================
3434
35- StrategySupportProfile::StrategySupportProfile (const Game &p_nfg ) : m_nfg(p_nfg )
35+ StrategySupportProfile::StrategySupportProfile (const Game &p_game ) : m_game(p_game )
3636{
37- for (auto player : m_nfg->GetPlayers ()) {
38- for (auto strategy : player->GetStrategies ()) {
39- m_support[player].push_back (strategy);
40- }
37+ m_game->BuildComputedValues ();
38+ m_strategies.m_space = &p_game->m_pureStrategies ;
39+ m_strategies.m_allowedDigits .resize (p_game->NumPlayers ());
40+
41+ for (size_t i = 0 ; i < p_game->NumPlayers (); ++i) {
42+ const int radix = p_game->m_pureStrategies .m_radices [i];
43+ auto &digits = m_strategies.m_allowedDigits [i];
44+ digits.resize (radix);
45+ std::iota (digits.begin (), digits.end (), 0 );
4146 }
4247}
4348
44- Array<int > StrategySupportProfile::NumStrategies () const
45- {
46- Array<int > dim (m_support.size ());
47- std::transform (
48- m_support.cbegin (), m_support.cend (), dim.begin (),
49- [](std::pair<GamePlayer, std::vector<GameStrategy>> a) { return a.second .size (); });
50- return dim;
51- }
52-
5349int StrategySupportProfile::MixedProfileLength () const
5450{
55- return std::accumulate (m_support.cbegin (), m_support.cend (), 0 ,
56- [](size_t tot, std::pair<GamePlayer, std::vector<GameStrategy>> a) {
57- return tot + a.second .size ();
58- });
51+ return sum_function (m_strategies.m_allowedDigits , [](const std::vector<int > &digits) {
52+ return static_cast <int >(digits.size ());
53+ });
5954}
6055
6156template <> MixedStrategyProfile<double > StrategySupportProfile::NewMixedStrategyProfile () const
6257{
63- return m_nfg ->NewMixedStrategyProfile (0.0 , *this );
58+ return m_game ->NewMixedStrategyProfile (0.0 , *this );
6459}
6560
6661template <> MixedStrategyProfile<Rational> StrategySupportProfile::NewMixedStrategyProfile () const
6762{
68- return m_nfg ->NewMixedStrategyProfile (Rational (0 ), *this );
63+ return m_game ->NewMixedStrategyProfile (Rational (0 ), *this );
6964}
7065
71- bool StrategySupportProfile::IsSubsetOf (const StrategySupportProfile &p_support ) const
66+ bool StrategySupportProfile::IsSubsetOf (const StrategySupportProfile &p_other ) const
7267{
73- for (auto player : m_nfg->GetPlayers ()) {
74- if (!std::includes (p_support.m_support .at (player).begin (),
75- p_support.m_support .at (player).end (), m_support.at (player).begin (),
76- m_support.at (player).end (),
77- [](const GameStrategy &s, const GameStrategy &t) {
78- return s->GetNumber () < t->GetNumber ();
79- })) {
68+ if (m_game != p_other.m_game ) {
69+ return false ;
70+ }
71+ const auto &A = m_strategies.m_allowedDigits ;
72+ const auto &B = p_other.m_strategies .m_allowedDigits ;
73+ const size_t n = A.size ();
74+
75+ for (size_t i = 0 ; i < n; ++i) {
76+ if (!std::includes (B[i].begin (), B[i].end (), A[i].begin (), A[i].end ())) {
8077 return false ;
8178 }
8279 }
@@ -85,8 +82,8 @@ bool StrategySupportProfile::IsSubsetOf(const StrategySupportProfile &p_support)
8582
8683void StrategySupportProfile::WriteNfgFile (std::ostream &p_file) const
8784{
88- auto players = m_nfg ->GetPlayers ();
89- p_file << " NFG 1 R " << std::quoted (m_nfg ->GetTitle ()) << ' '
85+ auto players = m_game ->GetPlayers ();
86+ p_file << " NFG 1 R " << std::quoted (m_game ->GetTitle ()) << ' '
9087 << FormatList (players, [](const GamePlayer &p) { return QuoteString (p->GetLabel ()); })
9188 << std::endl
9289 << std::endl;
@@ -97,7 +94,7 @@ void StrategySupportProfile::WriteNfgFile(std::ostream &p_file) const
9794 }) << std::endl;
9895 }
9996 p_file << " }" << std::endl;
100- p_file << std::quoted (m_nfg ->GetComment ()) << std::endl << std::endl;
97+ p_file << std::quoted (m_game ->GetComment ()) << std::endl << std::endl;
10198
10299 for (auto iter : StrategyContingencies (*this )) {
103100 p_file << FormatList (
@@ -112,25 +109,32 @@ void StrategySupportProfile::WriteNfgFile(std::ostream &p_file) const
112109
113110void StrategySupportProfile::AddStrategy (const GameStrategy &p_strategy)
114111{
115- auto &support = m_support[p_strategy->GetPlayer ()];
116- auto pos = std::find_if (support.begin (), support.end (), [p_strategy](const GameStrategy &s) {
117- return s->GetNumber () >= p_strategy->GetNumber ();
118- });
119- if (pos == support.end () || *pos != p_strategy) {
120- // Strategy is not in the support for the player; add at this location to keep sorted by number
121- support.insert (pos, p_strategy);
112+ if (p_strategy->GetGame () != m_game) {
113+ throw MismatchException ();
114+ }
115+ const size_t index = p_strategy->GetPlayer ()->GetNumber () - 1 ;
116+ const int digit = p_strategy->GetNumber () - 1 ;
117+ auto &digits = m_strategies.m_allowedDigits [index];
118+ auto pos = std::lower_bound (digits.begin (), digits.end (), digit);
119+ if (pos == digits.end () || *pos != digit) {
120+ digits.insert (pos, digit);
122121 }
123122}
124123
125124bool StrategySupportProfile::RemoveStrategy (const GameStrategy &p_strategy)
126125{
127- auto &support = m_support[p_strategy->GetPlayer ()];
128- if (support.size () == 1 ) {
126+ if (p_strategy->GetGame () != m_game) {
127+ throw MismatchException ();
128+ }
129+ const size_t index = p_strategy->GetPlayer ()->GetNumber () - 1 ;
130+ const int digit = p_strategy->GetNumber () - 1 ;
131+ auto &digits = m_strategies.m_allowedDigits [index];
132+ if (digits.size () == 1 ) {
129133 return false ;
130134 }
131- auto pos = std::find (support .begin (), support .end (), p_strategy );
132- if (pos != support .end ()) {
133- support .erase (pos);
135+ auto pos = std::lower_bound (digits .begin (), digits .end (), digit );
136+ if (pos != digits .end () && *pos == digit ) {
137+ digits .erase (pos);
134138 return true ;
135139 }
136140 return false ;
@@ -263,7 +267,7 @@ bool UndominatedForPlayer(const StrategySupportProfile &p_support,
263267StrategySupportProfile StrategySupportProfile::Undominated (bool p_strict, bool p_external) const
264268{
265269 StrategySupportProfile newSupport (*this );
266- for (auto player : m_nfg ->GetPlayers ()) {
270+ for (auto player : m_game ->GetPlayers ()) {
267271 UndominatedForPlayer (*this , newSupport, player, p_strict, p_external);
268272 }
269273 return newSupport;
0 commit comments