src/tcfr.cpp
// Returns a pointer to the allocation buffer after this node and all of its
// descendants.
// Note: we could use num-succs to encode terminal/nonterminal
// Terminal
//   Byte 0:      1
// Nonterminal
//   Byte 0:      0
//   Byte 1:      Street
//   Byte 2:      Num succs
//   Byte 3:      Fold succ index
//   Byte 4:      Call succ index
//   Byte 5:      Player acting
//   Bytes 6-7:   Last-bet-to
//   Byte 8:      Beginning of succ ptrs
// The next num-succs * 8 bytes are for the succ ptrs
// For each bucket
//   num-succs * sizeof(T_REGRET) for the regrets
//   If saving sumprobs:
//     num-succs * sizeof(T_SUM_PROB) for the sum-probs
// If boosting: num_succs * sizeof(T_SUM_PROB) for the action-sum-probs
Returns a pointer to the allocation buffer after this node and all of its
descendants.
Returns a pointer to the allocation buffer after this node and all of its descendants .
unsigned char *TCFR::Prepare(unsigned char *ptr, Node *node, unsigned short last_bet_to,
			     unsigned long long int ***offsets) {
  if (node->Terminal()) {
    ptr[0] = 1;
    return ptr + 4;
  }
  int st = node->Street();
  int pa = node->PlayerActing();
  ptr[0] = 0;
  ptr[1] = st;
  int num_succs = node->NumSuccs();
  ptr[2] = num_succs;
  int fsi = 255;
  if (node->HasFoldSucc()) fsi = node->FoldSuccIndex();
  ptr[3] = fsi;
  int csi = 255;
  if (node->HasCallSucc()) csi = node->CallSuccIndex();
  ptr[4] = csi;
  ptr[5] = pa;
  *(unsigned short *)(ptr + 6) = last_bet_to;
  unsigned char *succ_ptr = ptr + 8;
  unsigned char *ptr1 = succ_ptr + num_succs * 8;
  if (num_succs > 1) {
    int num_buckets = buckets_.NumBuckets(st);
    for (int b = 0; b < num_buckets; ++b) {
      if (char_quantized_streets_[st]) {
	for (int s = 0; s < num_succs; ++s) {
	  *ptr1 = 0;
	  ++ptr1;
	}
      } else if (short_quantized_streets_[st]) {
	for (int s = 0; s < num_succs; ++s) {
	  *(unsigned short *)ptr1 = 0;
	  ptr1 += 2;
	}
      } else {
	for (int s = 0; s < num_succs; ++s) {
	  *((T_REGRET *)ptr1) = 0;
	  ptr1 += sizeof(T_REGRET);
	}
      }
      if (sumprob_streets_[pa][st] && (! asymmetric_ || target_player_ == pa)) {
	for (int s = 0; s < num_succs; ++s) {
	  *((T_SUM_PROB *)ptr1) = 0;
	  ptr1 += sizeof(T_SUM_PROB);
	}
      }
    }
    if (boost_thresholds_[st] > 0 && sumprob_streets_[pa][st] &&
	(! asymmetric_ || target_player_ == pa)) {
      for (int s = 0; s < num_succs; ++s) {
	*((T_SUM_PROB *)ptr1) = 0;
	ptr1 += sizeof(T_SUM_PROB);
      }
    }
  }
  for (int s = 0; s < num_succs; ++s) {
    unsigned long long int ull_offset = ptr1 - data_;
    Node *succ = node->IthSucc(s);
    if (! succ->Terminal()) {
      int succ_st = succ->Street();
      int succ_pa = succ->PlayerActing();
      int succ_nt = succ->NonterminalID();
      unsigned long long int succ_offset = offsets[succ_st][succ_pa][succ_nt];
      if (succ_offset != 999999999999) {
	unsigned short new_bet_to;
	if (s == fsi || s == csi) {
	  new_bet_to = last_bet_to;
	} else {
	  new_bet_to = succ->LastBetTo();
	}
	unsigned short old_bet_to =
	  *(unsigned short *)(data_ + succ_offset + 6);
	if (old_bet_to != new_bet_to) {
	  fprintf(stderr, "bet_to mismatch: %i %i\n", (int)old_bet_to,
		  (int)new_bet_to);
	  exit(-1);
	}
	*((unsigned long long int *)(succ_ptr + s * 8)) = succ_offset;
	continue;
      } else {
	offsets[succ_st][succ_pa][succ_nt] = ull_offset;
      }
    }
    *((unsigned long long int *)(succ_ptr + s * 8)) = ull_offset;
    if (s == fsi || s == csi) {
      ptr1 = Prepare(ptr1, succ, last_bet_to, offsets);
    } else {
      unsigned short new_bet_to = succ->LastBetTo();
      ptr1 = Prepare(ptr1, succ, new_bet_to, offsets);
    }
  }
  return ptr1;
}
unsigned char * TCFR :: Prepare ( unsigned char * ptr , Node * node , unsigned short last_bet_to , unsigned long long int * * * offsets ) { if ( node -> Terminal ( ) ) { ptr [ 0 ] = 1 ; return ptr + 4 ; } int st = node -> Street ( ) ; int pa = node -> PlayerActing ( ) ; ptr [ 0 ] = 0 ; ptr [ 1 ] = st ; int num_succs = node -> NumSuccs ( ) ; ptr [ 2 ] = num_succs ; int fsi = 255 ; if ( node -> HasFoldSucc ( ) ) fsi = node -> FoldSuccIndex ( ) ; ptr [ 3 ] = fsi ; int csi = 255 ; if ( node -> HasCallSucc ( ) ) csi = node -> CallSuccIndex ( ) ; ptr [ 4 ] = csi ; ptr [ 5 ] = pa ; * ( unsigned short * ) ( ptr + 6 ) = last_bet_to ; unsigned char * succ_ptr = ptr + 8 ; unsigned char * ptr1 = succ_ptr + num_succs * 8 ; if ( num_succs > 1 ) { int num_buckets = buckets_ . NumBuckets ( st ) ; for ( int b = 0 ; b < num_buckets ; ++ b ) { if ( char_quantized_streets_ [ st ] ) { for ( int s = 0 ; s < num_succs ; ++ s ) { * ptr1 = 0 ; ++ ptr1 ; } } else if ( short_quantized_streets_ [ st ] ) { for ( int s = 0 ; s < num_succs ; ++ s ) { * ( unsigned short * ) ptr1 = 0 ; ptr1 += 2 ; } } else { for ( int s = 0 ; s < num_succs ; ++ s ) { * ( ( T_REGRET * ) ptr1 ) = 0 ; ptr1 += sizeof ( T_REGRET ) ; } } if ( sumprob_streets_ [ pa ] [ st ] && ( ! asymmetric_ || target_player_ == pa ) ) { for ( int s = 0 ; s < num_succs ; ++ s ) { * ( ( T_SUM_PROB * ) ptr1 ) = 0 ; ptr1 += sizeof ( T_SUM_PROB ) ; } } } if ( boost_thresholds_ [ st ] > 0 && sumprob_streets_ [ pa ] [ st ] && ( ! asymmetric_ || target_player_ == pa ) ) { for ( int s = 0 ; s < num_succs ; ++ s ) { * ( ( T_SUM_PROB * ) ptr1 ) = 0 ; ptr1 += sizeof ( T_SUM_PROB ) ; } } } for ( int s = 0 ; s < num_succs ; ++ s ) { unsigned long long int ull_offset = ptr1 - data_ ; Node * succ = node -> IthSucc ( s ) ; if ( ! succ -> Terminal ( ) ) { int succ_st = succ -> Street ( ) ; int succ_pa = succ -> PlayerActing ( ) ; int succ_nt = succ -> NonterminalID ( ) ; unsigned long long int succ_offset = offsets [ succ_st ] [ succ_pa ] [ succ_nt ] ; if ( succ_offset != 999999999999 ) { unsigned short new_bet_to ; if ( s == fsi || s == csi ) { new_bet_to = last_bet_to ; } else { new_bet_to = succ -> LastBetTo ( ) ; } unsigned short old_bet_to = * ( unsigned short * ) ( data_ + succ_offset + 6 ) ; if ( old_bet_to != new_bet_to ) { fprintf ( stderr , " \n " , ( int ) old_bet_to , ( int ) new_bet_to ) ; exit ( -1 ) ; } * ( ( unsigned long long int * ) ( succ_ptr + s * 8 ) ) = succ_offset ; continue ; } else { offsets [ succ_st ] [ succ_pa ] [ succ_nt ] = ull_offset ; } } * ( ( unsigned long long int * ) ( succ_ptr + s * 8 ) ) = ull_offset ; if ( s == fsi || s == csi ) { ptr1 = Prepare ( ptr1 , succ , last_bet_to , offsets ) ; } else { unsigned short new_bet_to = succ -> LastBetTo ( ) ; ptr1 = Prepare ( ptr1 , succ , new_bet_to , offsets ) ; } } return ptr1 ; }
Returns a pointer to the allocation buffer after this node and all of its
descendants.
Returns a pointer to the allocation buffer after this node and all of its descendants .
// Regrets // Sumprobs // Action sumprobs // Temporary // Check last-bet-to's match