From 35b2c15ca1c3c7ff0a5a931d9ccb57c820618d81 Mon Sep 17 00:00:00 2001 From: Theodore Turocy Date: Fri, 14 Apr 2023 21:25:52 +0100 Subject: [PATCH] Change parameter for chance probability setting from std::string to Number. --- src/games/file.cc | 2 +- src/games/game.h | 2 +- src/games/gametree.cc | 2 +- src/games/gametree.h | 2 +- src/gui/gamedoc.cc | 2 +- src/pygambit/lib/action.pxi | 12 +++--------- src/pygambit/lib/libgambit.pyx | 4 ++-- src/pygambit/tests/test_actions.py | 23 ++++++++++------------- 8 files changed, 20 insertions(+), 29 deletions(-) diff --git a/src/games/file.cc b/src/games/file.cc index a07e76024..6796d3b71 100644 --- a/src/games/file.cc +++ b/src/games/file.cc @@ -833,7 +833,7 @@ void ParseChanceNode(GameParserState &p_state, infoset->SetLabel(label); for (int act = 1; act <= actions.Length(); act++) { infoset->GetAction(act)->SetLabel(actions[act]); - infoset->SetActionProb(act, probs[act]); + infoset->SetActionProb(act, Number(probs[act])); } } else { diff --git a/src/games/game.h b/src/games/game.h index c9db18aaa..40fef39e2 100644 --- a/src/games/game.h +++ b/src/games/game.h @@ -309,7 +309,7 @@ class GameInfosetRep : public GameObject { virtual bool Precedes(GameNode) const = 0; - virtual void SetActionProb(int i, const std::string &p_value) = 0; + virtual void SetActionProb(int i, const Number &p_value) = 0; virtual double GetActionProb(int pl, double) const = 0; virtual Rational GetActionProb(int pl, const Rational &) const = 0; virtual std::string GetActionProb(int pl, const std::string &) const = 0; diff --git a/src/games/gametree.cc b/src/games/gametree.cc index 41d835065..1e700556a 100644 --- a/src/games/gametree.cc +++ b/src/games/gametree.cc @@ -169,7 +169,7 @@ void GameTreeInfosetRep::RemoveAction(int which) } } -void GameTreeInfosetRep::SetActionProb(int act, const std::string &p_value) +void GameTreeInfosetRep::SetActionProb(int act, const Number &p_value) { m_probs[act] = p_value; m_efg->ClearComputedValues(); diff --git a/src/games/gametree.h b/src/games/gametree.h index af0075396..c582b6213 100644 --- a/src/games/gametree.h +++ b/src/games/gametree.h @@ -114,7 +114,7 @@ class GameTreeInfosetRep : public GameInfosetRep { bool Precedes(GameNode) const override; - void SetActionProb(int i, const std::string &p_value) override; + void SetActionProb(int i, const Number &p_value) override; double GetActionProb(int pl, double) const override { return (double) m_probs[pl]; } Rational GetActionProb(int pl, const Rational &) const override diff --git a/src/gui/gamedoc.cc b/src/gui/gamedoc.cc index e4adf4d35..3fba2a0cf 100644 --- a/src/gui/gamedoc.cc +++ b/src/gui/gamedoc.cc @@ -687,7 +687,7 @@ void gbtGameDocument::DoSetActionProb(GameInfoset p_infoset, unsigned int p_action, const wxString &p_prob) { - p_infoset->SetActionProb(p_action, static_cast(p_prob.mb_str())); + p_infoset->SetActionProb(p_action, Number(p_prob.ToStdString())); UpdateViews(GBT_DOC_MODIFIED_PAYOFFS); } diff --git a/src/pygambit/lib/action.pxi b/src/pygambit/lib/action.pxi index 6be5229e4..28111add9 100644 --- a/src/pygambit/lib/action.pxi +++ b/src/pygambit/lib/action.pxi @@ -92,12 +92,6 @@ cdef class Action: return Rational(py_string.decode('ascii')) def __set__(self, value): - cdef string s - if isinstance(value, (int, decimal.Decimal, fractions.Fraction)): - v = str(value) - s = v.encode('ascii') - self.action.deref().GetInfoset().deref().SetActionProb( - self.action.deref().GetNumber(), s) - else: - raise TypeError("numeric argument required for action probability") - + self.action.deref().GetInfoset().deref().SetActionProb( + self.action.deref().GetNumber(), _to_number(value) + ) diff --git a/src/pygambit/lib/libgambit.pyx b/src/pygambit/lib/libgambit.pyx index 5eb1357d8..4d074c052 100644 --- a/src/pygambit/lib/libgambit.pyx +++ b/src/pygambit/lib/libgambit.pyx @@ -59,7 +59,7 @@ cdef extern from "core/number.h": c_Number(string) string as_string "operator const string &"() -cdef c_Number _to_number(value): +cdef c_Number _to_number(value) except *: """Convert a value into a game Number representation.""" if isinstance(value, (int, Decimal, Rational)): value = str(value) @@ -165,7 +165,7 @@ cdef extern from "games/game.h": c_GameAction InsertAction(c_GameAction) except +ValueError string GetActionProb(int, string) except +IndexError - void SetActionProb(int, string) except +IndexError + void SetActionProb(int, c_Number) except +IndexError int NumMembers() c_GameNode GetMember(int) except +IndexError diff --git a/src/pygambit/tests/test_actions.py b/src/pygambit/tests/test_actions.py index 200beaa41..80d12ba28 100644 --- a/src/pygambit/tests/test_actions.py +++ b/src/pygambit/tests/test_actions.py @@ -31,6 +31,9 @@ def test_action_probability(self): decimal.Decimal('0.500000') ) + self.extensive_game.root.infoset.actions[0].prob = 2.0 + assert(self.extensive_game.root.infoset.actions[0].prob == fractions.Fraction(2)) + self.extensive_game.root.infoset.actions[0].prob = ( decimal.Decimal('0.97300') ) @@ -50,22 +53,16 @@ def test_action_probability(self): self.extensive_game.root.infoset.actions[0].prob = 2 assert self.extensive_game.root.infoset.actions[0].prob == 2 + self.extensive_game.root.infoset.actions[0].prob = "1/7" + assert (self.extensive_game.root.infoset.actions[0].prob == fractions.Fraction('1/7')) + + self.extensive_game.root.infoset.actions[0].prob = "2.7" + assert (self.extensive_game.root.infoset.actions[0].prob == decimal.Decimal('2.7')) + self.assertRaises( - TypeError, setattr, self.extensive_game.root.infoset.actions[0], - "prob", 2.0 - ) - self.assertRaises( - TypeError, setattr, self.extensive_game.root.infoset.actions[0], + ValueError, setattr, self.extensive_game.root.infoset.actions[0], "prob", "test" ) - self.assertRaises( - TypeError, setattr, self.extensive_game.root.infoset.actions[0], - "prob", "1/7" - ) - self.assertRaises( - TypeError, setattr, self.extensive_game.root.infoset.actions[0], - "prob", "2.7" - ) def test_action_precedes(self): "Test to ensure precedes is working"