Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9324864
Added GetFullSupport() to Game
StephenPasteris Nov 18, 2025
24261f5
Moved Sequences into Gambit namespace
StephenPasteris Nov 19, 2025
36f4040
Added sequence form functionality to Game
StephenPasteris Nov 19, 2025
b252b87
Made get_sequence_form_payoff function on pygambit game
StephenPasteris Nov 19, 2025
41e7e43
Made a Sequence class in cython
StephenPasteris Nov 20, 2025
8a570b5
Moved PlayerSequences into Gambit namespace and added GetSequences(pl…
StephenPasteris Nov 21, 2025
1ce3457
Exposed PlayerSequences
StephenPasteris Nov 22, 2025
de490db
Added MixedSequenceProfile to game.h
StephenPasteris Nov 24, 2025
ca7cadf
Added MixedSequenceProfile to game.h
StephenPasteris Nov 24, 2025
e3cbb9d
Added failing LCP code
StephenPasteris Nov 24, 2025
936385c
Added failing LP code
StephenPasteris Nov 24, 2025
e224052
Fixed LP and LCP
StephenPasteris Nov 28, 2025
5fa380b
Cleaned up LP
StephenPasteris Nov 28, 2025
fbc88cc
Cleaned up LCP
StephenPasteris Nov 28, 2025
408ac5d
Removed GetConstraintEntry from BSP (now just GetSequenceConstraintEn…
StephenPasteris Nov 28, 2025
811c882
Changed uint8_t to int
StephenPasteris Nov 28, 2025
54bfe42
Used member initialiser to fix clang-tidy error
StephenPasteris Nov 28, 2025
0205b5c
Changed int to const int for clang-tidy
StephenPasteris Nov 28, 2025
2d88e5f
Added terminal prob code
StephenPasteris Dec 10, 2025
7537624
resolved conflict in gametree.h
StephenPasteris Dec 10, 2025
36ccf6a
pushed payoffs to terminal nodes in sequence form object
StephenPasteris Dec 11, 2025
b728f3a
updated nonterm_outcomes kuhn poker test so that it xpasses
StephenPasteris Dec 12, 2025
ead0c23
set m_fullSupport to null when game changes
StephenPasteris Dec 12, 2025
9204b87
removed commented out code from gameseq.cc
StephenPasteris Dec 12, 2025
710ff33
added perfect info game with chance to tests
StephenPasteris Dec 13, 2025
1c0f0e7
added one card poker with lacking outcome to tests
StephenPasteris Dec 13, 2025
7d04c18
added one card poker with lacking outcome to tests
StephenPasteris Dec 13, 2025
4ffc68e
added one perfect info game with internal outcomes to tests
StephenPasteris Dec 13, 2025
571c94e
added game testing multiple things to tests
StephenPasteris Dec 13, 2025
5b98213
added large payoff game to tests
StephenPasteris Dec 13, 2025
917630b
added chance in middle game
StephenPasteris Dec 14, 2025
9f0fe58
added chance in middle game
StephenPasteris Dec 14, 2025
3a8c741
added entry-accomodation game to tests
StephenPasteris Dec 15, 2025
98ac78c
added non-zero sum game lacking outcome to tests
StephenPasteris Dec 15, 2025
308ce80
added 3 player game with internal outcomes to tests
StephenPasteris Dec 15, 2025
ed9554c
Added tests to enumpoly
StephenPasteris Dec 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 16 additions & 80 deletions src/games/behavspt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,20 +174,30 @@ std::shared_ptr<GameSequenceForm> BehaviorSupportProfile::GetSequenceForm() cons
return m_sequenceForm;
}

BehaviorSupportProfile::Sequences BehaviorSupportProfile::GetSequences() const { return {this}; }
Sequences BehaviorSupportProfile::GetSequences() const { return {this}; }

BehaviorSupportProfile::PlayerSequences
BehaviorSupportProfile::GetSequences(GamePlayer &p_player) const
GameSequence BehaviorSupportProfile::GetCorrespondingSequence(const GameAction &p_action) const
{
return {this, p_player};
return GetSequenceForm()->m_correspondence.at(p_action);
}

int BehaviorSupportProfile::GetConstraintEntry(const GameInfoset &p_infoset,
const GameAction &p_action) const
int BehaviorSupportProfile::GetSequenceConstraintEntry(const GameInfoset &p_infoset,
const GameAction &p_action) const
{
return GetSequenceForm()->GetConstraintEntry(p_infoset, p_action);
}

PlayerSequences BehaviorSupportProfile::GetSequences(const GamePlayer &p_player) const
{
return {this, p_player};
}

const Rational &
BehaviorSupportProfile::GetTerminalProb(const std::map<GamePlayer, GameSequence> &p_profile) const
{
return GetSequenceForm()->GetTerminalProb(p_profile);
}

const Rational &
BehaviorSupportProfile::GetPayoff(const std::map<GamePlayer, GameSequence> &p_profile,
const GamePlayer &p_player) const
Expand Down Expand Up @@ -220,80 +230,6 @@ BehaviorSupportProfile::ToMixedBehaviorProfile(const std::map<GameSequence, doub
return b;
}

size_t BehaviorSupportProfile::Sequences::size() const
{
return std::accumulate(m_support->GetSequenceForm()->m_sequences.cbegin(),
m_support->GetSequenceForm()->m_sequences.cend(), 0,
[](int acc, const std::pair<GamePlayer, std::vector<GameSequence>> &seq) {
return acc + seq.second.size();
});
}

BehaviorSupportProfile::Sequences::iterator BehaviorSupportProfile::Sequences::begin() const
{
return {m_support->GetSequenceForm(), false};
}
BehaviorSupportProfile::Sequences::iterator BehaviorSupportProfile::Sequences::end() const
{
return {m_support->GetSequenceForm(), true};
}

BehaviorSupportProfile::Sequences::iterator::iterator(
const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end)
: m_sfg(p_sfg)
{
if (p_end) {
m_currentPlayer = m_sfg->m_sequences.cend();
}
else {
m_currentPlayer = m_sfg->m_sequences.cbegin();
m_currentSequence = m_currentPlayer->second.cbegin();
}
}

BehaviorSupportProfile::Sequences::iterator &
BehaviorSupportProfile::Sequences::iterator::operator++()
{
if (m_currentPlayer == m_sfg->m_sequences.cend()) {
return *this;
}
m_currentSequence++;
if (m_currentSequence != m_currentPlayer->second.cend()) {
return *this;
}
m_currentPlayer++;
if (m_currentPlayer != m_sfg->m_sequences.cend()) {
m_currentSequence = m_currentPlayer->second.cbegin();
}
return *this;
}

bool BehaviorSupportProfile::Sequences::iterator::operator==(const iterator &it) const
{
if (m_sfg != it.m_sfg || m_currentPlayer != it.m_currentPlayer) {
return false;
}
if (m_currentPlayer == m_sfg->m_sequences.end()) {
return true;
}
return (m_currentSequence == it.m_currentSequence);
}

std::vector<GameSequence>::const_iterator BehaviorSupportProfile::PlayerSequences::begin() const
{
return m_support->GetSequenceForm()->m_sequences.at(m_player).begin();
}

std::vector<GameSequence>::const_iterator BehaviorSupportProfile::PlayerSequences::end() const
{
return m_support->GetSequenceForm()->m_sequences.at(m_player).end();
}

size_t BehaviorSupportProfile::PlayerSequences::size() const
{
return m_support->GetSequenceForm()->m_sequences.at(m_player).size();
}

BehaviorSupportProfile::SequenceContingencies::iterator::iterator(
const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end)
: m_sfg(p_sfg), m_end(p_end)
Expand Down
54 changes: 4 additions & 50 deletions src/games/behavspt.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@
namespace Gambit {

class GameSequenceForm;
class SequencesWrapper;
class PlayerSequencesWrapper;
class InfosetsWrapper;
class ContingenciesWrapper;

/// This class represents a subset of the actions in an extensive game.
/// It is enforced that each player has at least one action at each
Expand Down Expand Up @@ -165,50 +161,6 @@ class BehaviorSupportProfile {
}
};

class Sequences {
const BehaviorSupportProfile *m_support;

public:
class iterator {
const std::shared_ptr<GameSequenceForm> m_sfg;
std::map<GamePlayer, std::vector<GameSequence>>::const_iterator m_currentPlayer;
std::vector<GameSequence>::const_iterator m_currentSequence;

public:
iterator(const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end);

GameSequence operator*() const { return *m_currentSequence; }
GameSequence operator->() const { return *m_currentSequence; }

iterator &operator++();

bool operator==(const iterator &it) const;
bool operator!=(const iterator &it) const { return !(*this == it); }
};

Sequences(const BehaviorSupportProfile *p_support) : m_support(p_support) {}

size_t size() const;

iterator begin() const;
iterator end() const;
};

class PlayerSequences {
const BehaviorSupportProfile *m_support;
GamePlayer m_player;

public:
PlayerSequences(const BehaviorSupportProfile *p_support, const GamePlayer &p_player)
: m_support(p_support), m_player(p_player)
{
}

size_t size() const;
std::vector<GameSequence>::const_iterator begin() const;
std::vector<GameSequence>::const_iterator end() const;
};

class SequenceContingencies {
const BehaviorSupportProfile *m_support;

Expand Down Expand Up @@ -245,15 +197,17 @@ class BehaviorSupportProfile {

std::shared_ptr<GameSequenceForm> GetSequenceForm() const;
Sequences GetSequences() const;
PlayerSequences GetSequences(GamePlayer &p_player) const;
int GetConstraintEntry(const GameInfoset &p_infoset, const GameAction &p_action) const;
PlayerSequences GetSequences(const GamePlayer &p_player) const;
const Rational &GetPayoff(const std::map<GamePlayer, GameSequence> &p_profile,
const GamePlayer &p_player) const;
const Rational &GetTerminalProb(const std::map<GamePlayer, GameSequence> &p_profile) const;
GameRep::Players GetPlayers() const { return GetGame()->GetPlayers(); }
MixedBehaviorProfile<double>
ToMixedBehaviorProfile(const std::map<GameSequence, double> &) const;
Infosets GetInfosets() const { return {this}; };
SequenceContingencies GetSequenceContingencies() const;
GameSequence GetCorrespondingSequence(const GameAction &p_action) const;
int GetSequenceConstraintEntry(const GameInfoset &p_infoset, const GameAction &p_action) const;

void FindReachableInfosets(GameNode p_node) const;
std::shared_ptr<std::map<GameInfoset, bool>> GetReachableInfosets() const;
Expand Down
71 changes: 71 additions & 0 deletions src/games/game.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
// editing operations into the game itself instead of in the member-object
// classes.
#include "gametree.h"
#include "gameseq.h"

namespace Gambit {

Expand Down Expand Up @@ -409,4 +410,74 @@ template class MixedStrategyProfileRep<Rational>;
template class MixedStrategyProfile<double>;
template class MixedStrategyProfile<Rational>;

//========================================================================
// Sequences
//========================================================================

size_t Sequences::size() const
{
return std::accumulate(m_support->GetSequenceForm()->m_sequences.cbegin(),
m_support->GetSequenceForm()->m_sequences.cend(), 0,
[](int acc, const std::pair<GamePlayer, std::vector<GameSequence>> &seq) {
return acc + seq.second.size();
});
}

Sequences::iterator Sequences::begin() const { return {m_support->GetSequenceForm(), false}; }
Sequences::iterator Sequences::end() const { return {m_support->GetSequenceForm(), true}; }

Sequences::iterator::iterator(const std::shared_ptr<GameSequenceForm> p_sfg, bool p_end)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a NestedElementCollection which implements exactly this generically - see how Infosets and Strategies are implemented.

: m_sfg(p_sfg)
{
if (p_end) {
m_currentPlayer = m_sfg->m_sequences.cend();
}
else {
m_currentPlayer = m_sfg->m_sequences.cbegin();
m_currentSequence = m_currentPlayer->second.cbegin();
}
}

Sequences::iterator &Sequences::iterator::operator++()
{
if (m_currentPlayer == m_sfg->m_sequences.cend()) {
return *this;
}
m_currentSequence++;
if (m_currentSequence != m_currentPlayer->second.cend()) {
return *this;
}
m_currentPlayer++;
if (m_currentPlayer != m_sfg->m_sequences.cend()) {
m_currentSequence = m_currentPlayer->second.cbegin();
}
return *this;
}

bool Sequences::iterator::operator==(const iterator &it) const
{
if (m_sfg != it.m_sfg || m_currentPlayer != it.m_currentPlayer) {
return false;
}
if (m_currentPlayer == m_sfg->m_sequences.end()) {
return true;
}
return (m_currentSequence == it.m_currentSequence);
}

std::vector<GameSequence>::const_iterator PlayerSequences::begin() const
{
return m_support->GetSequenceForm()->m_sequences.at(m_player).begin();
}

std::vector<GameSequence>::const_iterator PlayerSequences::end() const
{
return m_support->GetSequenceForm()->m_sequences.at(m_player).end();
}

size_t PlayerSequences::size() const
{
return m_support->GetSequenceForm()->m_sequences.at(m_player).size();
}

} // end namespace Gambit
Loading