@@ -854,6 +854,7 @@ void GameTreeRep::ClearComputedValues() const
854854 }
855855 player->m_strategies .clear ();
856856 }
857+ const_cast <GameTreeRep *>(this )->m_nodePlays .clear ();
857858 m_computedValues = false ;
858859}
859860
@@ -869,6 +870,29 @@ void GameTreeRep::BuildComputedValues() const
869870 m_computedValues = true ;
870871}
871872
873+ void GameTreeRep::BuildConsistentPlays ()
874+ {
875+ m_nodePlays.clear ();
876+ BuildConsistentPlaysRecursiveImpl (m_root);
877+ }
878+
879+ std::vector<GameNodeRep *> GameTreeRep::BuildConsistentPlaysRecursiveImpl (GameNodeRep *node)
880+ {
881+ std::vector<GameNodeRep *> consistent_plays;
882+ if (node->IsTerminal ()) {
883+ consistent_plays = std::vector<GameNodeRep *>{node};
884+ }
885+ else {
886+ for (GameNodeRep *child : node->GetChildren ()) {
887+ auto child_consistent_plays = BuildConsistentPlaysRecursiveImpl (child);
888+ consistent_plays.insert (consistent_plays.end (), child_consistent_plays.begin (),
889+ child_consistent_plays.end ());
890+ }
891+ }
892+ m_nodePlays[node] = consistent_plays;
893+ return consistent_plays;
894+ }
895+
872896// ------------------------------------------------------------------------
873897// GameTreeRep: Writing data files
874898// ------------------------------------------------------------------------
@@ -997,6 +1021,43 @@ std::vector<GameInfoset> GameTreeRep::GetInfosets() const
9971021// GameTreeRep: Outcomes
9981022// ------------------------------------------------------------------------
9991023
1024+ std::vector<GameNode> GameTreeRep::GetPlays (GameNode node) const
1025+ {
1026+ const_cast <GameTreeRep *>(this )->BuildConsistentPlays ();
1027+
1028+ const std::vector<GameNodeRep *> &consistent_plays = m_nodePlays.at (node);
1029+ std::vector<GameNode> consistent_plays_copy;
1030+ consistent_plays_copy.reserve (consistent_plays.size ());
1031+
1032+ std::transform (consistent_plays.cbegin (), consistent_plays.cend (),
1033+ std::back_inserter (consistent_plays_copy),
1034+ [](GameNodeRep *rep_ptr) -> GameNode { return {rep_ptr}; });
1035+
1036+ return consistent_plays_copy;
1037+ }
1038+
1039+ std::vector<GameNode> GameTreeRep::GetPlays (GameInfoset infoset) const
1040+ {
1041+ std::vector<GameNode> plays;
1042+
1043+ for (const auto &node : infoset->GetMembers ()) {
1044+ std::vector<GameNode> member_plays = GetPlays (node);
1045+ plays.insert (plays.end (), member_plays.begin (), member_plays.end ());
1046+ }
1047+ return plays;
1048+ }
1049+
1050+ std::vector<GameNode> GameTreeRep::GetPlays (GameAction action) const
1051+ {
1052+ std::vector<GameNode> plays;
1053+
1054+ for (const auto &node : action->GetInfoset ()->GetMembers ()) {
1055+ std::vector<GameNode> child_plays = GetPlays (node->GetChild (action));
1056+ plays.insert (plays.end (), child_plays.begin (), child_plays.end ());
1057+ }
1058+ return plays;
1059+ }
1060+
10001061void GameTreeRep::DeleteOutcome (const GameOutcome &p_outcome)
10011062{
10021063 IncrementVersion ();
0 commit comments