Skip to content

Commit d5805cf

Browse files
committed
Try a more conservative implementation that simply wraps the public ranges for players and infosets.
1 parent d7856c2 commit d5805cf

3 files changed

Lines changed: 47 additions & 85 deletions

File tree

src/games/game.h

Lines changed: 46 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -999,114 +999,81 @@ inline void GameInfosetRep::DebugSanityCheck() const
999999
}
10001000

10011001
class GameRep::Infosets {
1002+
Players m_players;
1003+
10021004
public:
1005+
explicit Infosets(const Players &outer) : m_players(outer) {}
1006+
10031007
class iterator {
1008+
using OuterIter = Players::iterator;
1009+
using InnerIter = GamePlayerRep::Infosets::iterator;
1010+
1011+
OuterIter m_playerIterator, m_playerEnd;
1012+
InnerIter m_infosetIterator, m_infosetEnd;
1013+
1014+
void next()
1015+
{
1016+
while (m_playerIterator != m_playerEnd && m_infosetIterator == m_infosetEnd) {
1017+
++m_playerIterator;
1018+
if (m_playerIterator != m_playerEnd) {
1019+
auto infosets = (*m_playerIterator)->GetInfosets();
1020+
m_infosetIterator = infosets.begin();
1021+
m_infosetEnd = infosets.end();
1022+
}
1023+
}
1024+
}
1025+
10041026
public:
10051027
using iterator_category = std::forward_iterator_tag;
10061028
using value_type = GameInfoset;
1029+
using reference = GameInfoset;
1030+
using pointer = GameInfoset;
10071031
using difference_type = std::ptrdiff_t;
1008-
using pointer = value_type;
1009-
using reference = value_type;
1010-
1011-
using outer_iter = std::vector<std::shared_ptr<GamePlayerRep>>::const_iterator;
1012-
using inner_iter = std::vector<std::shared_ptr<GameInfosetRep>>::const_iterator;
10131032

10141033
iterator() = default;
10151034

1016-
iterator(std::shared_ptr<GameRep> game, outer_iter outer, outer_iter outer_end)
1017-
: game_(std::move(game)), outer_(outer), outer_end_(outer_end)
1035+
iterator(const OuterIter &p_playerIterator, const OuterIter &p_playerEnd)
1036+
: m_playerIterator(p_playerIterator), m_playerEnd(p_playerEnd)
10181037
{
1019-
if (outer_ != outer_end_) {
1020-
init_inner();
1021-
satisfy_invariant();
1038+
if (m_playerIterator != m_playerEnd) {
1039+
const auto infosets = (*m_playerIterator)->GetInfosets();
1040+
m_infosetIterator = infosets.begin();
1041+
m_infosetEnd = infosets.end();
10221042
}
1043+
next();
10231044
}
10241045

1025-
value_type operator*() const
1026-
{
1027-
(*inner_)->DebugSanityCheck();
1028-
(*inner_)->GetPlayer()->DebugSanityCheck();
1029-
auto g = (*inner_)->GetGame();
1030-
assert(g); // i.e. g != nullptr
1031-
return GameInfoset(*inner_); // GameObjectPtr constructor
1032-
}
1033-
1034-
value_type operator->() const
1035-
{
1036-
(*inner_)->DebugSanityCheck();
1037-
(*inner_)->GetPlayer()->DebugSanityCheck();
1038-
auto g = (*inner_)->GetGame();
1039-
assert(g); // i.e. g != nullptrreturn
1040-
return GameInfoset(*inner_);
1041-
}
1046+
reference operator*() const { return *m_infosetIterator; }
1047+
pointer operator->() const { return *m_infosetIterator; }
10421048

10431049
iterator &operator++()
10441050
{
1045-
++inner_;
1046-
satisfy_invariant();
1051+
++m_infosetIterator;
1052+
next();
10471053
return *this;
10481054
}
10491055

1050-
bool operator==(const iterator &other) const
1051-
{
1052-
// Compare end iterators correctly
1053-
if (outer_ == outer_end_ && other.outer_ == other.outer_end_) {
1054-
return true;
1055-
}
1056-
1057-
return outer_ == other.outer_ && inner_ == other.inner_;
1058-
}
1059-
1060-
bool operator!=(const iterator &other) const { return !(*this == other); }
1061-
1062-
private:
1063-
bool is_end() const { return outer_ == outer_end_; }
1064-
1065-
void init_inner()
1056+
iterator operator++(int)
10661057
{
1067-
const auto &player = *outer_;
1068-
inner_ = player->m_infosets.begin();
1069-
inner_end_ = player->m_infosets.end();
1058+
iterator tmp = *this;
1059+
++(*this);
1060+
return tmp;
10701061
}
10711062

1072-
void satisfy_invariant()
1063+
friend bool operator==(const iterator &a, const iterator &b)
10731064
{
1074-
while (!is_end() && inner_ == inner_end_) {
1075-
++outer_;
1076-
if (!is_end()) {
1077-
init_inner();
1078-
}
1079-
}
1065+
return a.m_playerIterator == b.m_playerIterator &&
1066+
(a.m_playerIterator == a.m_playerEnd || a.m_infosetIterator == b.m_infosetIterator);
10801067
}
10811068

1082-
// HOLD GAME ALIVE
1083-
std::shared_ptr<GameRep> game_;
1084-
1085-
outer_iter outer_{};
1086-
outer_iter outer_end_{};
1087-
inner_iter inner_{};
1088-
inner_iter inner_end_{};
1069+
friend bool operator!=(const iterator &a, const iterator &b) { return !(a == b); }
10891070
};
10901071

1091-
// Construct a view storing a strong reference to the GameRep
1092-
explicit Infosets(std::shared_ptr<GameRep> game)
1093-
: game_(std::move(game)), players_(&game_->m_players)
1094-
{
1095-
}
1096-
1097-
iterator begin() const { return iterator(game_, players_->begin(), players_->end()); }
1098-
1099-
iterator end() const { return iterator(game_, players_->end(), players_->end()); }
1100-
1101-
private:
1102-
std::shared_ptr<GameRep> game_;
1103-
const std::vector<std::shared_ptr<GamePlayerRep>> *players_;
1072+
iterator begin() const { return {m_players.begin(), m_players.end()}; }
1073+
iterator end() const { return {m_players.end(), m_players.end()}; }
11041074
};
11051075

1106-
inline GameRep::Infosets GameRep::GetInfosets() const
1107-
{
1108-
return Infosets(std::const_pointer_cast<GameRep>(this->shared_from_this()));
1109-
}
1076+
inline GameRep::Infosets GameRep::GetInfosets() const { return Infosets(GetPlayers()); }
11101077

11111078
//=======================================================================
11121079
// Inline members of game representation classes

src/games/gameobject.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ template <class T> class GameObjectPtr {
135135
bool operator<(const GameObjectPtr<T> &r) const { return (m_rep < r.m_rep); }
136136

137137
operator bool() const noexcept { return m_rep != nullptr; }
138-
operator std::shared_ptr<T>() const { return m_rep; }
138+
operator std::shared_ptr<T>() const { return get_shared(); }
139139
};
140140

141141
template <class P, class T> class ElementCollection {

src/games/gametree.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,6 @@ class GameTreeRep : public GameExplicitRep {
130130
//@{
131131
/// Returns the iset'th information set in the game (numbered globally)
132132
GameInfoset GetInfoset(int iset) const override;
133-
/// Returns the set of information sets in the game
134-
Infosets GetInfosets() const override
135-
{
136-
return Infosets(std::const_pointer_cast<GameRep>(this->shared_from_this()));
137-
}
138133
/// Sort the information sets for each player in a canonical order
139134
void SortInfosets() override;
140135
/// Returns the set of actions taken by the infoset's owner before reaching this infoset

0 commit comments

Comments
 (0)