Skip to content

Commit 53a366c

Browse files
Exposed sequence form to python
1 parent 3a2b32b commit 53a366c

File tree

4 files changed

+1446
-1
lines changed

4 files changed

+1446
-1
lines changed

src/games/gameseq.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ class MixedSequenceProfile {
101101
return probs[p_key];
102102
}
103103

104-
void GetMixedBehaviorProfile() const
104+
MixedBehaviorProfile<T> GetMixedBehaviorProfile() const
105105
{
106106
MixedBehaviorProfile<T> mbp(game);
107107
for (const auto& [seq, prob] : probs) {
@@ -333,6 +333,8 @@ class GameSequenceForm {
333333

334334
~GameSequenceForm() = default;
335335

336+
GameSequence GetCorrespondingSequence(GameAction action) { return m_correspondence[action]; }
337+
336338
const BehaviorSupportProfile &GetSupport() const { return m_support; }
337339

338340
Sequences GetSequences() const { return {this}; }

src/pygambit/gambit.pyx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,4 @@ include "stratmixed.pxi"
9999
include "behavmixed.pxi"
100100
include "game.pxi"
101101
include "nash.pxi"
102+
include "sequence_form.pxi"

src/pygambit/sequence_form.pxi

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
from libcpp.map cimport map as cpp_map
2+
from libcpp.memory cimport shared_ptr as cpp_shared_ptr
3+
from libcpp.vector cimport vector as cpp_vector
4+
5+
@cython.cfunc
6+
def rat_to_py_new(r: c_Rational):
7+
s = to_string(r).decode("ascii")
8+
if not s:
9+
return Rational(0)
10+
return Rational(s)
11+
12+
13+
cdef extern from "../games/behavspt.h" namespace "Gambit":
14+
cdef cppclass c_BehaviorSupportProfile "BehaviorSupportProfile":
15+
c_BehaviourSupportProfile(const c_Game&) except +
16+
17+
18+
cdef extern from "../games/gameseq.h" namespace "Gambit":
19+
cdef cppclass c_GameSequenceRep "GameSequenceRep":
20+
pass
21+
22+
23+
ctypedef cpp_shared_ptr[c_GameSequenceRep] c_GameSequence
24+
25+
26+
cdef extern from "../games/gameseq.h" namespace "Gambit":
27+
cdef cppclass c_PlayerSequences "GameSequenceForm::PlayerSequences":
28+
cpp_vector[c_GameSequence].const_iterator begin()
29+
30+
31+
cdef extern from "../games/gameseq.h" namespace "Gambit":
32+
cdef cppclass c_GameSequenceForm "GameSequenceForm":
33+
c_GameSequenceForm(const c_BehaviorSupportProfile&) except +
34+
c_Rational PayoffFromActions(cpp_map[c_GamePlayer, c_GameAction] action_profile, c_GamePlayer p_player)
35+
c_GameSequence GetCorrespondingSequence(c_GameAction action)
36+
c_PlayerSequences GetSequences(const c_GamePlayer &p_player) const
37+
const c_Rational &GetPayoff(const cpp_map[c_GamePlayer, c_GameSequence] &p_profile, const c_GamePlayer &p_player) const
38+
int GetConstraintEntry(const c_GameInfoset &p_infoset, const c_GameAction &p_action) const
39+
40+
41+
cdef class GameSequenceForm:
42+
cdef c_GameSequenceForm* seq_form
43+
cdef c_BehaviorSupportProfile* support
44+
45+
def __cinit__(self, py_game):
46+
cdef Game game = cython.cast(Game, py_game)
47+
cdef c_Game cpp_game = game.game
48+
self.support = new c_BehaviorSupportProfile(cpp_game)
49+
self.seq_form = new c_GameSequenceForm(deref(self.support))
50+
51+
def __dealloc__(self):
52+
del self.seq_form
53+
del self.support
54+
55+
def get_payoff(self, action_dict, py_player):
56+
cdef Player player = cython.cast(Player, py_player)
57+
cdef c_GamePlayer cpp_player = player.player
58+
cdef cpp_map[c_GamePlayer, c_GameSequence] profile
59+
cdef c_GamePlayer temp_player
60+
cdef c_GameAction temp_action
61+
cdef Player key
62+
cdef Action value
63+
for py_key, py_value in action_dict.items():
64+
key = cython.cast(Player, py_key)
65+
temp_player = key.player
66+
if py_value is None:
67+
profile[temp_player] = deref(self.seq_form.GetSequences(temp_player).begin())
68+
else:
69+
value = cython.cast(Action, py_value)
70+
temp_action = value.action
71+
profile[temp_player] = self.seq_form.GetCorrespondingSequence(temp_action)
72+
cdef c_Rational payoff = self.seq_form.GetPayoff(profile, cpp_player)
73+
return rat_to_py_new(payoff)
74+
75+
def get_constraint_entry(self, py_infoset, py_action):
76+
cdef Infoset infoset = cython.cast(Infoset, py_infoset)
77+
cdef c_GameInfoset cpp_infoset = infoset.infoset
78+
cdef Action action
79+
cdef c_GameAction cpp_action
80+
if py_action is None:
81+
cpp_action = <c_GameAction>0
82+
else:
83+
action = cython.cast(Action, py_action)
84+
cpp_action = action.action
85+
return self.seq_form.GetConstraintEntry(cpp_infoset, cpp_action)
86+
87+

0 commit comments

Comments
 (0)