@@ -49,7 +49,7 @@ class GameStrategyRep;
4949using GameStrategy = GameObjectPtr<GameStrategyRep>;
5050
5151class GamePlayerRep ;
52- using GamePlayer = GameObjectPtr <GamePlayerRep>;
52+ using GamePlayer = GameObjectSmartPtr <GamePlayerRep>;
5353
5454class GameNodeRep ;
5555using GameNode = GameObjectPtr<GameNodeRep>;
@@ -132,6 +132,81 @@ template <class P, class T> class ElementCollection {
132132 iterator cend () const { return {m_owner, m_container, (m_owner) ? m_container->size () : 0 }; }
133133};
134134
135+ template <class P , class T > class SmartElementCollection {
136+ P m_owner{nullptr };
137+ const std::vector<std::shared_ptr<T>> *m_container{nullptr };
138+
139+ public:
140+ class iterator {
141+ P m_owner{nullptr };
142+ const std::vector<std::shared_ptr<T>> *m_container{nullptr };
143+ size_t m_index{0 };
144+
145+ public:
146+ using iterator_category = std::bidirectional_iterator_tag;
147+ using difference_type = std::ptrdiff_t ;
148+ using value_type = GameObjectSmartPtr<T>;
149+ using pointer = value_type *;
150+ using reference = value_type &;
151+
152+ iterator () = default ;
153+ iterator (const P &p_owner, const std::vector<std::shared_ptr<T>> *p_container,
154+ size_t p_index = 0 )
155+ : m_owner(p_owner), m_container(p_container), m_index(p_index)
156+ {
157+ }
158+ iterator (const iterator &) = default ;
159+ ~iterator () = default ;
160+ iterator &operator =(const iterator &) = default ;
161+
162+ bool operator ==(const iterator &p_iter) const
163+ {
164+ return m_owner == p_iter.m_owner && m_container == p_iter.m_container &&
165+ m_index == p_iter.m_index ;
166+ }
167+ bool operator !=(const iterator &p_iter) const
168+ {
169+ return m_owner != p_iter.m_owner || m_container != p_iter.m_container ||
170+ m_index != p_iter.m_index ;
171+ }
172+
173+ iterator &operator ++()
174+ {
175+ m_index++;
176+ return *this ;
177+ }
178+ iterator &operator --()
179+ {
180+ m_index--;
181+ return *this ;
182+ }
183+ value_type operator *() const { return m_container->at (m_index); }
184+ };
185+
186+ SmartElementCollection () = default ;
187+ explicit SmartElementCollection (const P &p_owner,
188+ const std::vector<std::shared_ptr<T>> *p_container)
189+ : m_owner(p_owner), m_container(p_container)
190+ {
191+ }
192+ SmartElementCollection (const SmartElementCollection<P, T> &) = default ;
193+ ~SmartElementCollection () = default ;
194+ SmartElementCollection &operator =(const SmartElementCollection<P, T> &) = default ;
195+
196+ bool operator ==(const SmartElementCollection<P, T> &p_other) const
197+ {
198+ return m_owner == p_other.m_owner && m_container == p_other.m_container ;
199+ }
200+ size_t size () const { return m_container->size (); }
201+ GameObjectSmartPtr<T> front () const { return m_container->front (); }
202+ GameObjectSmartPtr<T> back () const { return m_container->back (); }
203+
204+ iterator begin () const { return {m_owner, m_container, 0 }; }
205+ iterator end () const { return {m_owner, m_container, (m_owner) ? m_container->size () : 0 }; }
206+ iterator cbegin () const { return {m_owner, m_container, 0 }; }
207+ iterator cend () const { return {m_owner, m_container, (m_owner) ? m_container->size () : 0 }; }
208+ };
209+
135210//
136211// Forward declarations of classes defined elsewhere.
137212//
@@ -369,7 +444,7 @@ class GameStrategyRep : public GameObject {
369444};
370445
371446// / A player in a game
372- class GamePlayerRep : public GameObject {
447+ class GamePlayerRep : public std ::enable_shared_from_this<GamePlayerRep> {
373448 friend class GameRep ;
374449 friend class GameExplicitRep ;
375450 friend class GameTreeRep ;
@@ -388,20 +463,24 @@ class GamePlayerRep : public GameObject {
388463 void MakeReducedStrats (class GameNodeRep *, class GameNodeRep *);
389464 // @}
390465
466+ bool m_valid{true };
391467 GameRep *m_game;
392468 int m_number;
393469 std::string m_label;
394470 std::vector<GameInfosetRep *> m_infosets;
395471 std::vector<GameStrategyRep *> m_strategies;
396472
397- GamePlayerRep (GameRep *p_game, int p_id) : m_game(p_game), m_number(p_id) {}
398- GamePlayerRep (GameRep *p_game, int p_id, int m_strats);
399- ~GamePlayerRep () override ;
400-
401473public:
402474 using Infosets = ElementCollection<GamePlayer, GameInfosetRep>;
403475 using Strategies = ElementCollection<GamePlayer, GameStrategyRep>;
404476
477+ GamePlayerRep (GameRep *p_game, int p_id) : m_game(p_game), m_number(p_id) {}
478+ GamePlayerRep (GameRep *p_game, int p_id, int m_strats);
479+ ~GamePlayerRep ();
480+
481+ bool IsValid () const { return m_valid; }
482+ void Invalidate () { m_valid = false ; }
483+
405484 int GetNumber () const { return m_number; }
406485 Game GetGame () const ;
407486
@@ -415,7 +494,10 @@ class GamePlayerRep : public GameObject {
415494 // / Returns the p_index'th information set
416495 GameInfoset GetInfoset (int p_index) const { return m_infosets.at (p_index - 1 ); }
417496 // / Returns the information sets for the player
418- Infosets GetInfosets () const { return Infosets (this , &m_infosets); }
497+ Infosets GetInfosets () const
498+ {
499+ return Infosets (std::const_pointer_cast<GamePlayerRep>(shared_from_this ()), &m_infosets);
500+ }
419501
420502 // / @name Strategies
421503 // @{
@@ -499,7 +581,7 @@ class GameRep : public std::enable_shared_from_this<GameRep> {
499581 template <class T > friend class TableMixedStrategyProfileRep ;
500582
501583protected:
502- std::vector<GamePlayerRep * > m_players;
584+ std::vector<std::shared_ptr< GamePlayerRep> > m_players;
503585 std::vector<GameOutcomeRep *> m_outcomes;
504586 std::string m_title, m_comment;
505587 unsigned int m_version{0 };
@@ -513,7 +595,7 @@ class GameRep : public std::enable_shared_from_this<GameRep> {
513595 // @}
514596
515597public:
516- using Players = ElementCollection <Game, GamePlayerRep>;
598+ using Players = SmartElementCollection <Game, GamePlayerRep>;
517599 using Outcomes = ElementCollection<Game, GameOutcomeRep>;
518600
519601 class Nodes {
@@ -728,17 +810,19 @@ class GameRep : public std::enable_shared_from_this<GameRep> {
728810 int NumStrategyContingencies () const
729811 {
730812 BuildComputedValues ();
731- return std::transform_reduce (m_players.begin (), m_players.end (), 0 , std::multiplies<>(),
732- [](const GamePlayerRep *p) { return p->m_strategies .size (); });
813+ return std::transform_reduce (
814+ m_players.begin (), m_players.end (), 0 , std::multiplies<>(),
815+ [](const std::shared_ptr<GamePlayerRep> &p) { return p->m_strategies .size (); });
733816 }
734817 // / Returns the total number of actions in the game
735818 virtual int BehavProfileLength () const = 0;
736819 // / Returns the total number of strategies in the game
737820 int MixedProfileLength () const
738821 {
739822 BuildComputedValues ();
740- return std::transform_reduce (m_players.begin (), m_players.end (), 0 , std::plus<>(),
741- [](const GamePlayerRep *p) { return p->m_strategies .size (); });
823+ return std::transform_reduce (
824+ m_players.begin (), m_players.end (), 0 , std::plus<>(),
825+ [](const std::shared_ptr<GamePlayerRep> &p) { return p->m_strategies .size (); });
742826 }
743827 // @}
744828
@@ -778,7 +862,7 @@ class GameRep : public std::enable_shared_from_this<GameRep> {
778862 // / Returns the number of players in the game
779863 size_t NumPlayers () const { return m_players.size (); }
780864 // / Returns the pl'th player in the game
781- GamePlayer GetPlayer (int pl) const { return m_players.at (pl - 1 ); }
865+ GamePlayer GetPlayer (int pl) const { return m_players.at (pl - 1 )-> shared_from_this () ; }
782866 // / Returns the set of players in the game
783867 Players GetPlayers () const
784868 {
@@ -847,7 +931,7 @@ inline Game GameOutcomeRep::GetGame() const { return m_game->shared_from_this();
847931template <class T > const T &GameOutcomeRep::GetPayoff (const GamePlayer &p_player) const
848932{
849933 try {
850- return static_cast <const T &>(m_payoffs.at (p_player));
934+ return static_cast <const T &>(m_payoffs.at (p_player. get () ));
851935 }
852936 catch (const std::out_of_range &) {
853937 throw MismatchException ();
@@ -857,7 +941,7 @@ template <class T> const T &GameOutcomeRep::GetPayoff(const GamePlayer &p_player
857941template <> inline const Number &GameOutcomeRep::GetPayoff (const GamePlayer &p_player) const
858942{
859943 try {
860- return m_payoffs.at (p_player);
944+ return m_payoffs.at (p_player. get () );
861945 }
862946 catch (const std::out_of_range &) {
863947 throw MismatchException ();
@@ -869,14 +953,14 @@ inline void GameOutcomeRep::SetPayoff(const GamePlayer &p_player, const Number &
869953 if (p_player->GetGame () != GetGame ()) {
870954 throw MismatchException ();
871955 }
872- m_payoffs[p_player] = p_value;
956+ m_payoffs[p_player. get () ] = p_value;
873957 m_game->IncrementVersion ();
874958}
875959
876- inline GamePlayer GameStrategyRep::GetPlayer () const { return m_player; }
960+ inline GamePlayer GameStrategyRep::GetPlayer () const { return m_player-> shared_from_this () ; }
877961
878962inline Game GameInfosetRep::GetGame () const { return m_game->shared_from_this (); }
879- inline GamePlayer GameInfosetRep::GetPlayer () const { return m_player; }
963+ inline GamePlayer GameInfosetRep::GetPlayer () const { return m_player-> shared_from_this () ; }
880964inline bool GameInfosetRep::IsChanceInfoset () const { return m_player->IsChance (); }
881965
882966inline Game GamePlayerRep::GetGame () const { return m_game->shared_from_this (); }
@@ -888,7 +972,7 @@ inline GameStrategy GamePlayerRep::GetStrategy(int st) const
888972inline GamePlayerRep::Strategies GamePlayerRep::GetStrategies () const
889973{
890974 m_game->BuildComputedValues ();
891- return Strategies (this , &m_strategies);
975+ return Strategies (std::const_pointer_cast<GamePlayerRep>( shared_from_this ()) , &m_strategies);
892976}
893977
894978inline Game GameNodeRep::GetGame () const { return m_game->shared_from_this (); }
0 commit comments