src/subgame_utils.cpp
// Only write out strategy for nodes at or below below_action_sequence.
Only write out strategy for nodes at or below below_action_sequence.
Only write out strategy for nodes at or below below_action_sequence .
void WriteSubgame(Node *node, const string &action_sequence, const string &below_action_sequence,
		  int gbd, const CardAbstraction &base_card_abstraction,
		  const CardAbstraction &subgame_card_abstraction,
		  const BettingAbstraction &base_betting_abstraction,
		  const BettingAbstraction &subgame_betting_abstraction,
		  const CFRConfig &base_cfr_config, const CFRConfig &subgame_cfr_config,
		  ResolvingMethod method, const CFRValues *sumprobs, int root_bd_st, int root_bd,
		  int asym_p, int target_pa, int last_st) {
  if (node->Terminal()) return;
  int st = node->Street();
  if (st > last_st) {
    int ngbd_begin = BoardTree::SuccBoardBegin(last_st, gbd, st);
    int ngbd_end = BoardTree::SuccBoardEnd(last_st, gbd, st);
    for (int ngbd = ngbd_begin; ngbd < ngbd_end; ++ngbd) {
      WriteSubgame(node, action_sequence, below_action_sequence, ngbd, base_card_abstraction,
		   subgame_card_abstraction, base_betting_abstraction, subgame_betting_abstraction,
		   base_cfr_config, subgame_cfr_config, method, sumprobs, root_bd_st, root_bd,
		   asym_p, target_pa, st);
    }
    return;
  }
  int num_succs = node->NumSuccs();
  if (node->PlayerActing() == target_pa && num_succs > 1) {
    if (below_action_sequence.size() <= action_sequence.size() &&
	std::equal(below_action_sequence.begin(), below_action_sequence.end(),
		   action_sequence.begin())) {
      char dir[500], dir2[500], dir3[500], filename[500];
      sprintf(dir, "%s/%s.%u.%s.%u.%u.%u.%s.%s", Files::NewCFRBase(),
	      Game::GameName().c_str(), Game::NumPlayers(),
	      base_card_abstraction.CardAbstractionName().c_str(),
	      Game::NumRanks(), Game::NumSuits(), Game::MaxStreet(),
	      base_betting_abstraction.BettingAbstractionName().c_str(),
	      base_cfr_config.CFRConfigName().c_str());
      if (base_betting_abstraction.Asymmetric()) {
	sprintf(dir2, "%s.p%u/subgames.%s.%s.%s.%s.p%u.p%u", dir, asym_p,
		subgame_card_abstraction.CardAbstractionName().c_str(),
		subgame_betting_abstraction.BettingAbstractionName().c_str(),
		subgame_cfr_config.CFRConfigName().c_str(),
		ResolvingMethodName(method), asym_p, target_pa);
      } else {
	sprintf(dir2, "%s/subgames.%s.%s.%s.%s.p%u", dir, 
		subgame_card_abstraction.CardAbstractionName().c_str(),
		subgame_betting_abstraction.BettingAbstractionName().c_str(),
		subgame_cfr_config.CFRConfigName().c_str(),
		ResolvingMethodName(method), target_pa);
      }
      Mkdir(dir2);
      if (action_sequence == "") {
	fprintf(stderr, "Empty action sequence not allowed\n");
	exit(-1);
      }
      sprintf(dir3, "%s/%s", dir2, action_sequence.c_str());
      Mkdir(dir3);
      sprintf(filename, "%s/%u", dir3, gbd);
      Writer writer(filename);
      int num_hole_card_pairs = Game::NumHoleCardPairs(node->Street());
      int lbd = BoardTree::LocalIndex(root_bd_st, root_bd, st, gbd);
      sumprobs->WriteBoardValuesForNode(node, &writer, nullptr, lbd, num_hole_card_pairs);
    }
  }
  for (int s = 0; s < num_succs; ++s) {
    string action = node->ActionName(s);
    WriteSubgame(node->IthSucc(s), action_sequence + action,
		 below_action_sequence, gbd,
		 base_card_abstraction, subgame_card_abstraction,
		 base_betting_abstraction, subgame_betting_abstraction,
		 base_cfr_config, subgame_cfr_config, method, sumprobs,
		 root_bd_st, root_bd, asym_p, target_pa, st);
  }
}
void WriteSubgame ( Node * node , const string & action_sequence , const string & below_action_sequence , int gbd , const CardAbstraction & base_card_abstraction , const CardAbstraction & subgame_card_abstraction , const BettingAbstraction & base_betting_abstraction , const BettingAbstraction & subgame_betting_abstraction , const CFRConfig & base_cfr_config , const CFRConfig & subgame_cfr_config , ResolvingMethod method , const CFRValues * sumprobs , int root_bd_st , int root_bd , int asym_p , int target_pa , int last_st ) { if ( node -> Terminal ( ) ) return ; int st = node -> Street ( ) ; if ( st > last_st ) { int ngbd_begin = BoardTree :: SuccBoardBegin ( last_st , gbd , st ) ; int ngbd_end = BoardTree :: SuccBoardEnd ( last_st , gbd , st ) ; for ( int ngbd = ngbd_begin ; ngbd < ngbd_end ; ++ ngbd ) { WriteSubgame ( node , action_sequence , below_action_sequence , ngbd , base_card_abstraction , subgame_card_abstraction , base_betting_abstraction , subgame_betting_abstraction , base_cfr_config , subgame_cfr_config , method , sumprobs , root_bd_st , root_bd , asym_p , target_pa , st ) ; } return ; } int num_succs = node -> NumSuccs ( ) ; if ( node -> PlayerActing ( ) == target_pa && num_succs > 1 ) { if ( below_action_sequence . size ( ) <= action_sequence . size ( ) && std :: equal ( below_action_sequence . begin ( ) , below_action_sequence . end ( ) , action_sequence . begin ( ) ) ) { char dir [ 500 ] , dir2 [ 500 ] , dir3 [ 500 ] , filename [ 500 ] ; sprintf ( dir , " " , Files :: NewCFRBase ( ) , Game :: GameName ( ) . c_str ( ) , Game :: NumPlayers ( ) , base_card_abstraction . CardAbstractionName ( ) . c_str ( ) , Game :: NumRanks ( ) , Game :: NumSuits ( ) , Game :: MaxStreet ( ) , base_betting_abstraction . BettingAbstractionName ( ) . c_str ( ) , base_cfr_config . CFRConfigName ( ) . c_str ( ) ) ; if ( base_betting_abstraction . Asymmetric ( ) ) { sprintf ( dir2 , " " , dir , asym_p , subgame_card_abstraction . CardAbstractionName ( ) . c_str ( ) , subgame_betting_abstraction . BettingAbstractionName ( ) . c_str ( ) , subgame_cfr_config . CFRConfigName ( ) . c_str ( ) , ResolvingMethodName ( method ) , asym_p , target_pa ) ; } else { sprintf ( dir2 , " " , dir , subgame_card_abstraction . CardAbstractionName ( ) . c_str ( ) , subgame_betting_abstraction . BettingAbstractionName ( ) . c_str ( ) , subgame_cfr_config . CFRConfigName ( ) . c_str ( ) , ResolvingMethodName ( method ) , target_pa ) ; } Mkdir ( dir2 ) ; if ( action_sequence == " " ) { fprintf ( stderr , " \n " ) ; exit ( -1 ) ; } sprintf ( dir3 , " " , dir2 , action_sequence . c_str ( ) ) ; Mkdir ( dir3 ) ; sprintf ( filename , " " , dir3 , gbd ) ; Writer writer ( filename ) ; int num_hole_card_pairs = Game :: NumHoleCardPairs ( node -> Street ( ) ) ; int lbd = BoardTree :: LocalIndex ( root_bd_st , root_bd , st , gbd ) ; sumprobs -> WriteBoardValuesForNode ( node , & writer , nullptr , lbd , num_hole_card_pairs ) ; } } for ( int s = 0 ; s < num_succs ; ++ s ) { string action = node -> ActionName ( s ) ; WriteSubgame ( node -> IthSucc ( s ) , action_sequence + action , below_action_sequence , gbd , base_card_abstraction , subgame_card_abstraction , base_betting_abstraction , subgame_betting_abstraction , base_cfr_config , subgame_cfr_config , method , sumprobs , root_bd_st , root_bd , asym_p , target_pa , st ) ; } }
Only write out strategy for nodes at or below below_action_sequence.
Only write out strategy for nodes at or below below_action_sequence .
// If we resolve more than one street, things get a little tricky.  We are writing one // file per final-street board, but this sumprobs object will contain more than one // board's data.