@@ -41,9 +41,11 @@ namespace Gambit {
4141// class GameOutcomeRep
4242// ========================================================================
4343
44- GameOutcomeRep::GameOutcomeRep (GameRep *p_game, int p_number)
45- : m_game(p_game), m_number(p_number), m_payoffs(m_game->NumPlayers ())
44+ GameOutcomeRep::GameOutcomeRep (GameRep *p_game, int p_number) : m_game(p_game), m_number(p_number)
4645{
46+ for (const auto &player : p_game->GetPlayers ()) {
47+ m_payoffs[player] = Number ();
48+ }
4749}
4850
4951// ========================================================================
@@ -121,8 +123,8 @@ void GamePlayerRep::MakeStrategy()
121123 Array<int > c (NumInfosets ());
122124
123125 for (int i = 1 ; i <= NumInfosets (); i++) {
124- if (m_infosets[i]->flag == 1 ) {
125- c[i] = m_infosets[i]->whichbranch ;
126+ if (m_infosets[i - 1 ]->flag == 1 ) {
127+ c[i] = m_infosets[i - 1 ]->whichbranch ;
126128 }
127129 else {
128130 c[i] = 0 ;
@@ -161,33 +163,33 @@ void GamePlayerRep::MakeReducedStrats(GameTreeNodeRep *n, GameTreeNodeRep *nn)
161163 }
162164
163165 if (n->NumChildren () > 0 ) {
164- if (n->infoset ->m_player == this ) {
165- if (n->infoset ->flag == 0 ) {
166+ if (n->m_infoset ->m_player == this ) {
167+ if (n->m_infoset ->flag == 0 ) {
166168 // we haven't visited this infoset before
167- n->infoset ->flag = 1 ;
169+ n->m_infoset ->flag = 1 ;
168170 for (i = 1 ; i <= n->NumChildren (); i++) {
169- GameTreeNodeRep *m = n->children [i];
171+ GameTreeNodeRep *m = n->m_children [i];
170172 n->whichbranch = m;
171- n->infoset ->whichbranch = i;
173+ n->m_infoset ->whichbranch = i;
172174 MakeReducedStrats (m, nn);
173175 }
174- n->infoset ->flag = 0 ;
176+ n->m_infoset ->flag = 0 ;
175177 }
176178 else {
177179 // we have visited this infoset, take same action
178- MakeReducedStrats (n->children [n->infoset ->whichbranch ], nn);
180+ MakeReducedStrats (n->m_children [n->m_infoset ->whichbranch ], nn);
179181 }
180182 }
181183 else {
182184 n->ptr = nullptr ;
183185 if (nn != nullptr ) {
184186 n->ptr = nn->m_parent ;
185187 }
186- n->whichbranch = n->children [1 ];
187- if (n->infoset ) {
188- n->infoset ->whichbranch = 0 ;
188+ n->whichbranch = n->m_children [1 ];
189+ if (n->m_infoset ) {
190+ n->m_infoset ->whichbranch = 0 ;
189191 }
190- MakeReducedStrats (n->children [1 ], n->children [1 ]);
192+ MakeReducedStrats (n->m_children [1 ], n->m_children [1 ]);
191193 }
192194 }
193195 else if (nn) {
@@ -217,7 +219,7 @@ void GamePlayerRep::MakeReducedStrats(GameTreeNodeRep *n, GameTreeNodeRep *nn)
217219 }
218220}
219221
220- GameInfoset GamePlayerRep::GetInfoset (int p_index) const { return m_infosets[p_index]; }
222+ GameInfoset GamePlayerRep::GetInfoset (int p_index) const { return m_infosets[p_index - 1 ]; }
221223
222224Array<GameInfoset> GamePlayerRep::GetInfosets () const
223225{
@@ -398,46 +400,31 @@ template <class T>
398400MixedStrategyProfile<T>::MixedStrategyProfile(const MixedBehaviorProfile<T> &p_profile)
399401 : m_rep(new TreeMixedStrategyProfileRep<T>(p_profile))
400402{
401- Game game = p_profile.GetGame ();
402- auto *efg = dynamic_cast <GameTreeRep *>(game.operator ->());
403- for (int pl = 1 ; pl <= m_rep->m_support .GetGame ()->NumPlayers (); pl++) {
404- GamePlayer player = m_rep->m_support .GetGame ()->GetPlayer (pl);
405- for (int st = 1 ; st <= player->NumStrategies (); st++) {
406- T prob = (T)1 ;
407-
408- for (int iset = 1 ; iset <= efg->GetPlayer (pl)->NumInfosets (); iset++) {
409- if (efg->m_players [pl]->m_strategies [st]->m_behav [iset] > 0 ) {
410- GameInfoset infoset = player->GetInfoset (iset);
411- prob *=
412- p_profile[infoset->GetAction (efg->m_players [pl]->m_strategies [st]->m_behav [iset])];
403+ auto *efg = dynamic_cast <GameTreeRep *>(p_profile.GetGame ().operator ->());
404+ for (const auto &player : efg->m_players ) {
405+ for (const auto &strategy : player->m_strategies ) {
406+ auto prob = static_cast <T>(1 );
407+ for (const auto &infoset : player->m_infosets ) {
408+ if (strategy->m_behav [infoset->GetNumber ()] > 0 ) {
409+ prob *= p_profile[infoset->GetAction (strategy->m_behav [infoset->GetNumber ()])];
413410 }
414411 }
415- (*this )[ m_rep-> m_support . GetGame ()-> GetPlayer (pl)-> GetStrategy (st) ] = prob;
412+ (*m_rep)[strategy ] = prob;
416413 }
417414 }
418415}
419416
420- template <class T >
421- MixedStrategyProfile<T>::MixedStrategyProfile(const MixedStrategyProfile<T> &p_profile)
422- : m_rep(p_profile.m_rep->Copy ())
423- {
424- InvalidateCache ();
425- }
426-
427417template <class T >
428418MixedStrategyProfile<T> &
429419MixedStrategyProfile<T>::operator =(const MixedStrategyProfile<T> &p_profile)
430420{
431421 if (this != &p_profile) {
432422 InvalidateCache ();
433- delete m_rep;
434- m_rep = p_profile.m_rep ->Copy ();
423+ m_rep.reset (p_profile.m_rep ->Copy ());
435424 }
436425 return *this ;
437426}
438427
439- template <class T > MixedStrategyProfile<T>::~MixedStrategyProfile () { delete m_rep; }
440-
441428// ========================================================================
442429// MixedStrategyProfile<T>: General data access
443430// ========================================================================
@@ -447,10 +434,8 @@ template <class T> Vector<T> MixedStrategyProfile<T>::operator[](const GamePlaye
447434 CheckVersion ();
448435 auto strategies = m_rep->m_support .GetStrategies (p_player);
449436 Vector<T> probs (strategies.size ());
450- int st = 1 ;
451- for (auto strategy : strategies) {
452- probs[st] = (*this )[strategy];
453- }
437+ std::transform (strategies.begin (), strategies.end (), probs.begin (),
438+ [this ](const GameStrategy &s) { return (*m_rep)[s]; });
454439 return probs;
455440}
456441
@@ -459,9 +444,10 @@ template <class T> MixedStrategyProfile<T> MixedStrategyProfile<T>::ToFullSuppor
459444 CheckVersion ();
460445 MixedStrategyProfile<T> full (m_rep->m_support .GetGame ()->NewMixedStrategyProfile (T (0 )));
461446
462- for (auto player : m_rep->m_support .GetGame ()->GetPlayers ()) {
463- for (auto strategy : player->GetStrategies ()) {
464- full[strategy] = (m_rep->m_support .Contains (strategy)) ? (*this )[strategy] : T (0 );
447+ for (const auto &player : m_rep->m_support .GetGame ()->GetPlayers ()) {
448+ for (const auto &strategy : player->GetStrategies ()) {
449+ full[strategy] =
450+ (m_rep->m_support .Contains (strategy)) ? (*m_rep)[strategy] : static_cast <T>(0 );
465451 }
466452 }
467453 return full;
@@ -470,17 +456,18 @@ template <class T> MixedStrategyProfile<T> MixedStrategyProfile<T>::ToFullSuppor
470456// ========================================================================
471457// MixedStrategyProfile<T>: Computation of interesting quantities
472458// ========================================================================
459+
473460template <class T > void MixedStrategyProfile<T>::ComputePayoffs() const
474461{
475462 if (!map_profile_payoffs.empty ()) {
476463 // caches (map_profile_payoffs and map_strategy_payoffs) are valid,
477464 // so don't compute anything, simply return
478465 return ;
479466 }
480- for (auto player : m_rep->m_support .GetPlayers ()) {
467+ for (const auto & player : m_rep->m_support .GetPlayers ()) {
481468 map_profile_payoffs[player] = GetPayoff (player);
482469 // values of the player's strategies
483- for (auto strategy : m_rep->m_support .GetStrategies (player)) {
470+ for (const auto & strategy : m_rep->m_support .GetStrategies (player)) {
484471 map_strategy_payoffs[player][strategy] = GetPayoff (strategy);
485472 }
486473 }
@@ -491,13 +478,10 @@ template <class T> T MixedStrategyProfile<T>::GetLiapValue() const
491478 CheckVersion ();
492479 ComputePayoffs ();
493480
494- T liapValue = T (0 );
495- for (auto player : m_rep-> m_support . GetPlayers () ) {
481+ auto liapValue = static_cast <T> (0 );
482+ for (auto [ player, payoff] : map_profile_payoffs ) {
496483 for (auto v : map_strategy_payoffs[player]) {
497- T regret = v.second - map_profile_payoffs[player];
498- if (regret > T (0 )) {
499- liapValue += regret * regret; // penalty if not best response
500- }
484+ liapValue += sqr (std::max (v.second - payoff, static_cast <T>(0 )));
501485 }
502486 }
503487 return liapValue;
0 commit comments