Skip to content
1 change: 1 addition & 0 deletions src/core/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ template <class T> class Array {
void erase(iterator pos) { m_data.erase(pos); }
void push_back(const T &value) { m_data.push_back(value); }
void pop_back() { m_data.pop_back(); }
void reserve(size_t len) { m_data.reserve(len); }
};

/// Convenience function to erase the element at `p_index`
Expand Down
2 changes: 1 addition & 1 deletion src/core/function.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ using namespace Gambit;
// vector perpendicular to the plane, then subtracting to compute the
// component parallel to the plane.)
//
void FunctionOnSimplices::Project(Vector<double> &x, const Array<int> &lengths) const
void FunctionOnSimplices::Project(Vector<double> &x, const Array<size_t> &lengths) const
{
int index = 1;
for (size_t part = 1; part <= lengths.size(); part++) {
Expand Down
2 changes: 1 addition & 1 deletion src/core/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class FunctionOnSimplices : public Function {

protected:
// Project the gradient 'x' onto the plane of the product of simplices.
void Project(Vector<double> &x, const Array<int> &lengths) const;
void Project(Vector<double> &x, const Array<size_t> &lengths) const;
};

class FunctionMinimizerError : public std::runtime_error {
Expand Down
148 changes: 36 additions & 112 deletions src/games/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -818,39 +818,6 @@ class GameRep : public std::enable_shared_from_this<GameRep> {
throw UndefinedException();
}

/// @name Dimensions of the game
//@{
/// The number of strategies for each player
virtual Array<int> NumStrategies() const = 0;
/// Gets the i'th strategy in the game, numbered globally
virtual GameStrategy GetStrategy(int p_index) const = 0;
/// Creates a new strategy for the player
virtual GameStrategy NewStrategy(const GamePlayer &p_player, const std::string &p_label)
{
throw UndefinedException();
}
/// Remove the strategy from the game
virtual void DeleteStrategy(const GameStrategy &p_strategy) { throw UndefinedException(); }
/// Returns the number of strategy contingencies in the game
int NumStrategyContingencies() const
{
BuildComputedValues();
return std::transform_reduce(
m_players.begin(), m_players.end(), 0, std::multiplies<>(),
[](const std::shared_ptr<GamePlayerRep> &p) { return p->m_strategies.size(); });
}
/// Returns the total number of actions in the game
virtual int BehavProfileLength() const = 0;
/// Returns the total number of strategies in the game
int MixedProfileLength() const
{
BuildComputedValues();
return std::transform_reduce(
m_players.begin(), m_players.end(), 0, std::plus<>(),
[](const std::shared_ptr<GamePlayerRep> &p) { return p->m_strategies.size(); });
}
//@}

virtual PureStrategyProfile NewPureStrategyProfile() const = 0;
virtual MixedStrategyProfile<double> NewMixedStrategyProfile(double) const = 0;
virtual MixedStrategyProfile<Rational> NewMixedStrategyProfile(const Rational &) const = 0;
Expand Down Expand Up @@ -899,14 +866,48 @@ class GameRep : public std::enable_shared_from_this<GameRep> {
virtual GamePlayer NewPlayer() = 0;
//@}

/// @name Dimensions of the game
//@{
using Strategies =
NestedElementCollection<Game, &GameRep::GetPlayers, &GamePlayerRep::GetStrategies>;
/// Returns the set of strategies in the game
Strategies GetStrategies() const
{
BuildComputedValues();
return Strategies(std::const_pointer_cast<GameRep>(this->shared_from_this()));
}
/// Gets the i'th strategy in the game, numbered globally starting from 1
GameStrategy GetStrategy(const std::size_t p_index) const
{
const auto strategies = GetStrategies();
if (p_index < 1 || p_index > strategies.size()) {
throw std::out_of_range("Strategy index out of range");
}
return *std::next(strategies.begin(), p_index - 1);
}
/// Creates a new strategy for the player
virtual GameStrategy NewStrategy(const GamePlayer &p_player, const std::string &p_label)
{
throw UndefinedException();
}
/// Remove the strategy from the game
virtual void DeleteStrategy(const GameStrategy &p_strategy) { throw UndefinedException(); }
/// Returns the total number of actions in the game
virtual int BehavProfileLength() const = 0;
//@}

/// @name Information sets
//@{
class Infosets;
using Infosets =
NestedElementCollection<Game, &GameRep::GetPlayers, &GamePlayerRep::GetInfosets>;

/// Returns the iset'th information set in the game (numbered globally)
virtual GameInfoset GetInfoset(int iset) const { throw UndefinedException(); }
/// Returns the set of information sets in the game
virtual Infosets GetInfosets() const;
virtual Infosets GetInfosets() const
{
return Infosets(std::const_pointer_cast<GameRep>(this->shared_from_this()));
}
/// Sort the information sets for each player in a canonical order
virtual void SortInfosets() {}
/// Returns the set of actions taken by the infoset's owner before reaching this infoset
Expand Down Expand Up @@ -958,83 +959,6 @@ class GameRep : public std::enable_shared_from_this<GameRep> {
virtual void BuildComputedValues() const {}
};

class GameRep::Infosets {
Players m_players;

public:
explicit Infosets(const Players &outer) : m_players(outer) {}

class iterator {
using OuterIter = Players::iterator;
using InnerIter = GamePlayerRep::Infosets::iterator;

OuterIter m_playerIterator, m_playerEnd;
InnerIter m_infosetIterator, m_infosetEnd;

void next()
{
while (m_playerIterator != m_playerEnd && m_infosetIterator == m_infosetEnd) {
++m_playerIterator;
if (m_playerIterator != m_playerEnd) {
auto infosets = (*m_playerIterator)->GetInfosets();
m_infosetIterator = infosets.begin();
m_infosetEnd = infosets.end();
}
}
}

public:
using iterator_category = std::forward_iterator_tag;
using value_type = GameInfoset;
using reference = GameInfoset;
using pointer = GameInfoset;
using difference_type = std::ptrdiff_t;

iterator() = default;

iterator(const OuterIter &p_playerIterator, const OuterIter &p_playerEnd)
: m_playerIterator(p_playerIterator), m_playerEnd(p_playerEnd)
{
if (m_playerIterator != m_playerEnd) {
const auto infosets = (*m_playerIterator)->GetInfosets();
m_infosetIterator = infosets.begin();
m_infosetEnd = infosets.end();
}
next();
}

reference operator*() const { return *m_infosetIterator; }
pointer operator->() const { return *m_infosetIterator; }

iterator &operator++()
{
++m_infosetIterator;
next();
return *this;
}

iterator operator++(int)
{
iterator tmp = *this;
++(*this);
return tmp;
}

friend bool operator==(const iterator &a, const iterator &b)
{
return a.m_playerIterator == b.m_playerIterator &&
(a.m_playerIterator == a.m_playerEnd || a.m_infosetIterator == b.m_infosetIterator);
}

friend bool operator!=(const iterator &a, const iterator &b) { return !(a == b); }
};

iterator begin() const { return {m_players.begin(), m_players.end()}; }
iterator end() const { return {m_players.end(), m_players.end()}; }
};

inline GameRep::Infosets GameRep::GetInfosets() const { return Infosets(GetPlayers()); }

//=======================================================================
// Inline members of game representation classes
//=======================================================================
Expand Down
26 changes: 0 additions & 26 deletions src/games/gameagg.cc
Original file line number Diff line number Diff line change
Expand Up @@ -196,32 +196,6 @@ Game GameAGGRep::Copy() const
return ReadAggFile(is);
}

//------------------------------------------------------------------------
// GameAGGRep: Dimensions of the game
//------------------------------------------------------------------------

Array<int> GameAGGRep::NumStrategies() const
{
Array<int> ns;
for (const auto &player : m_players) {
ns.push_back(player->GetStrategies().size());
}
return ns;
}

GameStrategy GameAGGRep::GetStrategy(int p_index) const
{
for (const auto &player : m_players) {
if (static_cast<int>(player->GetStrategies().size()) >= p_index) {
return player->GetStrategy(p_index);
}
else {
p_index -= player->GetStrategies().size();
}
}
throw std::out_of_range("Strategy index out of range");
}

//------------------------------------------------------------------------
// GameAGGRep: Factory functions
//------------------------------------------------------------------------
Expand Down
4 changes: 0 additions & 4 deletions src/games/gameagg.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,6 @@ class GameAGGRep : public GameRep {
std::shared_ptr<agg::AGG> GetUnderlyingAGG() const { return aggPtr; }
/// @name Dimensions of the game
//@{
/// The number of strategies for each player
Array<int> NumStrategies() const override;
/// Gets the i'th strategy in the game, numbered globally
GameStrategy GetStrategy(int p_index) const override;
/// Returns the total number of actions in the game
int BehavProfileLength() const override { throw UndefinedException(); }
//@}
Expand Down
19 changes: 5 additions & 14 deletions src/games/gamebagg.cc
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,16 @@ template <class T> class BAGGMixedStrategyProfileRep : public MixedStrategyProfi
template <class T> T BAGGMixedStrategyProfileRep<T>::GetPayoff(int pl) const
{
auto &g = dynamic_cast<GameBAGGRep &>(*(this->m_support.GetGame()));
std::vector<double> s(g.MixedProfileLength());
Array<int> ns = g.NumStrategies();
std::vector<double> s(g.GetStrategies().size());
const auto ns = g.GetStrategies().shape();
int bplayer = -1, btype = -1;
for (int i = 0, offs = 0; i < g.baggPtr->getNumPlayers(); ++i) {
for (int tp = 0; tp < g.baggPtr->getNumTypes(i); ++tp) {
if (pl == g.baggPtr->typeOffset[i] + tp + 1) {
bplayer = i;
btype = tp;
}
for (int j = 0; j < ns[g.baggPtr->typeOffset[i] + tp + 1]; ++j, ++offs) {
for (int j = 0; j < ns[g.baggPtr->typeOffset[i] + tp]; ++j, ++offs) {
const GameStrategy strategy = this->m_support.GetGame()
->GetPlayer(g.baggPtr->typeOffset[i] + tp + 1)
->GetStrategy(j + 1);
Expand All @@ -124,7 +124,7 @@ template <class T>
T BAGGMixedStrategyProfileRep<T>::GetPayoffDeriv(int pl, const GameStrategy &ps) const
{
auto &g = dynamic_cast<GameBAGGRep &>(*(this->m_support.GetGame()));
std::vector<double> s(g.MixedProfileLength());
std::vector<double> s(g.GetStrategies().size());
int bplayer = -1, btype = -1;
for (int i = 0; i < g.baggPtr->getNumPlayers(); ++i) {
for (int tp = 0; tp < g.baggPtr->getNumTypes(i); ++tp) {
Expand Down Expand Up @@ -163,7 +163,7 @@ T BAGGMixedStrategyProfileRep<T>::GetPayoffDeriv(int pl, const GameStrategy &ps1
}

auto &g = dynamic_cast<GameBAGGRep &>(*(this->m_support.GetGame()));
std::vector<double> s(g.MixedProfileLength());
std::vector<double> s(g.GetStrategies().size());
int bplayer = -1, btype = -1;
for (int i = 0; i < g.baggPtr->getNumPlayers(); ++i) {
for (int tp = 0; tp < g.baggPtr->getNumTypes(i); ++tp) {
Expand Down Expand Up @@ -236,15 +236,6 @@ Game GameBAGGRep::Copy() const
// GameBAGGRep: Dimensions of the game
//------------------------------------------------------------------------

Array<int> GameBAGGRep::NumStrategies() const
{
Array<int> ns;
for (const auto &player : m_players) {
ns.push_back(player->m_strategies.size());
}
return ns;
}

PureStrategyProfile GameBAGGRep::NewPureStrategyProfile() const
{
return PureStrategyProfile(std::make_shared<BAGGPureStrategyProfileRep>(
Expand Down
4 changes: 0 additions & 4 deletions src/games/gamebagg.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ class GameBAGGRep : public GameRep {

/// @name Dimensions of the game
//@{
/// The number of strategies for each player
Array<int> NumStrategies() const override;
/// Gets the i'th strategy in the game, numbered globally
GameStrategy GetStrategy(int p_index) const override { throw UndefinedException(); }
/// Returns the total number of actions in the game
int BehavProfileLength() const override { throw UndefinedException(); }
//@}
Expand Down
28 changes: 0 additions & 28 deletions src/games/gameexpl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,6 @@ Rational GameExplicitRep::GetMaxPayoff() const
});
}

//------------------------------------------------------------------------
// GameExplicitRep: Dimensions of the game
//------------------------------------------------------------------------

Array<int> GameExplicitRep::NumStrategies() const
{
BuildComputedValues();
Array<int> dim;
for (const auto &player : m_players) {
dim.push_back(player->m_strategies.size());
}
return dim;
}

GameStrategy GameExplicitRep::GetStrategy(int p_index) const
{
BuildComputedValues();
int i = 1;
for (const auto &player : m_players) {
for (const auto &strategy : player->m_strategies) {
if (p_index == i++) {
return strategy;
}
}
}
throw std::out_of_range("Strategy index out of range");
}

//------------------------------------------------------------------------
// GameExplicitRep: Outcomes
//------------------------------------------------------------------------
Expand Down
8 changes: 0 additions & 8 deletions src/games/gameexpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,6 @@ class GameExplicitRep : public GameRep {
Rational GetMaxPayoff() const override;
//@}

/// @name Dimensions of the game
//@{
/// The number of strategies for each player
Array<int> NumStrategies() const override;
/// Gets the i'th strategy in the game, numbered globally
GameStrategy GetStrategy(int p_index) const override;
//@}

/// @name Outcomes
//@{
/// Creates a new outcome in the game
Expand Down
Loading
Loading