Exemplo n.º 1
0
// works only for k > 1
UINT32 next_k_permutation(UINT32 *ar, UINT32 n, UINT32 k) {
    UINT32 result = next_permutation(ar, k);
    if (result == 0) {
        result = next_combination(ar, n, k);
    }
    return result;
}
Exemplo n.º 2
0
int main(){
    int round = 15;
    GeneralInteger gden(1);
    GeneralInteger gnum(0);
    for(int i= 0; i< round; ++i){
        gden = gden.multiply(i+2);
    }
    gden.print();
    printf("\n");
    for(int i = (round/2)+1; i<=round; ++i){
        vector<int> combi;
        vector<int> flag;
        combi.resize(i);
        for(unsigned int j = 0; j < combi.size(); ++j)
            combi[j]= j;
        do{
            flag.clear();
            flag.resize(round, 0);
            for(unsigned int j = 0; j < combi.size(); ++j)
                flag[combi[j]] = 1;
            GeneralInteger gtp(1);
            for(unsigned int j = 0; j < flag.size(); ++j){
                if(flag[j] == 0)
                    gtp = gtp.multiply(j+1);
            }
            gnum += gtp;
        }while(next_combination(combi, round, i));
    }
    gnum.print(1);
    GeneralInteger gr(1);
    gden.print();
    //gr= gden.divide();
    printf("\n");
}
Exemplo n.º 3
0
int compare(int size, vector<int> top, vector<int> bottom){
    int sum = 0;
    unsigned int vsize = top.size();
    assert(top.size() == bottom.size());
    vector<int> realbottom;
    realbottom.resize(vsize, 0);
    do{
        //find the real combination
        for(unsigned int i = 0; i < vsize; ++i){
            realbottom[vsize-1-i] = size - 1 - bottom[i];
        }
        do{
            vector<int> sunion;
            set_union(top.begin(), top.end(), 
                    realbottom.begin(), realbottom.end(),
                    back_inserter(sunion));
            if(sunion.size()!= 2*vsize)
                continue;
            bool alwaysequal = true;
            bool initialized = false;
            bool greater = true;
            bool needCompare = false; 
            for(unsigned int i = 0; i<vsize; ++i){
                if(top[i]== realbottom[i]) 
                    continue;
                alwaysequal = false;
                if(!initialized){
                    greater = top[i] > realbottom[i];
                    initialized = true;
                    continue;
                }
                if((top[i] > realbottom[i]) != greater){
                    needCompare = true;
                    break;
                }
            }
            if(alwaysequal)
                continue;
            if(needCompare)
                ++sum;
            
        }while(next_combination(top, size, vsize));
    }while(next_combination(bottom, size, vsize));
    return sum;
}
Exemplo n.º 4
0
int main(){
    int count = 0, ac=0;
    vector<int> veca, vecb;
    veca.resize(6);
    vecb.resize(6);
    for(unsigned int i = 0; i< 6; ++i){
        veca[i] = i;
        vecb[i] = i;
    }

    do{
        do{ 
            ++ac;
            if(checkSquare(veca, vecb))
                ++count; // all test passed
        }while(next_combination(vecb, 10, 6));   //for b
    }while(next_combination(veca, 10, 6));       //for a
    printf("%d %d\n", count, ac);
}
Exemplo n.º 5
0
int main(int argc, char *argv[]) {

	char tab [10] = {'A', 'B', 'C', 'E', 'G', 'I', 'M', 'O', 'P', 'Y'};
	std::vector<char> vi(tab, tab+10);
	std::vector<char> vc(tab, tab+4);

	do
	{
		show_collection(vc);
	} 
	while(next_combination(vi.begin(), vi.end(), vc.begin(), vc.end()));

	return 0; //Huge success!
}
Exemplo n.º 6
0
Matrix<int> getCombinationMatrix(unsigned int n, unsigned int k){
    std::vector<int> ints;
    for (unsigned int i = 1; i <= n; ints.push_back(i++));
    unsigned long chooseCount = choose(n,k);

    Matrix<int> combinations(chooseCount, k);

    int counter = 0;
    do{
       for (unsigned int i = 0; i < k; ++i)
            combinations(counter,i) = ints[i];
       counter++;
    }while(next_combination(ints.begin(),ints.begin() + k,ints.end()));
    return combinations;
}
Exemplo n.º 7
0
  bool replaceWithWildCard(std::vector<std::vector<std::string>::iterator>& cont,
			   std::vector<std::string>& sequence, std::vector<std::string>& result, const std::string& wildCard) {
    if (cont.size() > sequence.size()) {
      std::cerr << "the size of iterator container is greater than the size of sequence";
    }

    bool hasMoreCombination = next_combination(cont, sequence.begin(), sequence.end());
    if (hasMoreCombination) {
      result.clear();
      result.insert(result.begin(), sequence.size(), wildCard);
      std::vector<std::vector<std::string>::iterator>::iterator i;
      for ( i = cont.begin(); i != cont.end(); ++i){
	result[*i - sequence.begin()] = **i;
      }
    }

    return hasMoreCombination;
    
  }//end replaceWildCard
Exemplo n.º 8
0
void a(){
    std::vector< char > a;
    std::vector< char > result;

    result.push_back('A');
    result.push_back('B');
    result.push_back('C');

    a.push_back('A');
    a.push_back('B');
    a.push_back('C');
    a.push_back('D');
    a.push_back('E');
    
    int cnt = 0;
    do{
        std::cout<<"oto "<<++cnt<<" kombinacja: "<<std::endl;
        print_obj(result.begin(), result.end());
    } while( next_combination(a.begin(), a.end(), result.begin(), result.end()) );
}
Exemplo n.º 9
0
int main(){
    a();
    return 0;
    std::vector<int> a;
    std::vector<int> result;

    result.push_back(0);
    result.push_back(1);
    result.push_back(2);

    for(int i=0;i<N;i++)
        a.push_back(i);   
    
    int cnt = 0;
    do{
        std::cout<<"oto "<<++cnt<<" kombinacja: "<<std::endl;
        print_obj(result.begin(), result.end());
    } while( next_combination(a.begin(), a.end(), result.begin(), result.end()) );
    return 0;
}
Exemplo n.º 10
0
bool is_correct_sequence(Sequence &sequence) {
    if(sequence.size() < 3) return false;

    uint32_t mask = (1 << sequence.size()) - 1;
    uint32_t combination = 0b111;

    Sequence c(3);

    while(next_combination(combination,mask)) {
        auto i = c.begin();
        uint32_t x = combination;
        while(uint32_t k = __builtin_ffs(x)) {
            *i++ = sequence[k-1];
             x &= ~(1 << (k-1));
        }

        if(c[1]-c[0] == c[2]-c[1]) {
            sequence = c;
            return true;
        }
    }

    return false;
}
Exemplo n.º 11
0
/*It solves the problem. If we are deleteting duplicates, it checks that the
 solution is valid.*/
int solve(Satellite *sats, int *combination, int *solution) {
  int i, j, k;
  long long int combs;
  int n;
  int valid;
  float r, num;

  combs = number_of_combinations(sats);
  //  printf("Combinations: %ld\n", combs);
  get_golden_index_max(sats);
  for (k = 0; k < nsats; k++) {
    combination[k] = 0; // We start from the combination 1 1 .. 1
    for (j = 0; j < sats[k].golden_index - 1; j++) {
      // delete_duplicates(sats, j, k);
    }
  }
  // print_F_matrix(sats);
  for (i = 1; i < combs; i++) {
    printf("%d ", i);
    next_combination(sats, combination);
    valid = check_solution(sats, combination);
    if (!valid)
      continue;
    //  print_array("comb", combination, nsats);
    n = total_occurrences(sats, combination);
    //  printf("tic: %.2f\n", tic);
    r = total_reward(sats, combination);
    num = r / n;
    printf("%.2f\n", num);
    if (num > max) {
      max = num;
      copy_solution(combination, solution);
    }
  }
  return 0;
}
Exemplo n.º 12
0
 bool next_combination(const it__ itb, it__ itk, const it__ ite)
 {
   return next_combination(itb, itk, ite, std::less<typename it__::value_type>());
 }
Exemplo n.º 13
0
	bool TrickHelper::IterFlush::nextCombine( int m , int n )
	{
		return next_combination( combine , combine + n , combine + m );
	}
Exemplo n.º 14
0
Arquivo: main.cpp Projeto: kotake/R
int main(){

	int sheet_num = 0;
	vector<int> order;
	int level;
	double SD_max[K], SD_min[K];
	ofstream sokanf;//sokan出力用
	ofstream sdf;//k-meansのクラスタごとの標準偏差の出力用

	const string fn = "iris.csv";
	//vector<vector<double> > m_csv_data;
	//vector<string> m_rabel;
	//vector<double> csv;

	CSVData mycsv;
	
	mycsv = CSVData::load_from(fn);

	//Bigdata myBd;
	//csvはvector<double>?CSVDataのオブジェクト?
	//vector<doubleならCSVDataのオブジェクトっていつ作るの?
	//CSVDataのオブジェクトなら静的メンバ関数にする意味は何?>

	//mycsv.load_from(fn);
	//Bigdata mybd(mycsv);
	
	//cout << myBd.col_num() << endl;


	//csv_data = new double[myBd.col_num()*myBd.row_num()];
	cout << "new size:"<< mycsv.col_num * mycsv.row_num << endl;

	/*if(myBd.read(csv_data))//fn->csv_data
		cout<< "csv読み込み完了"<< endl;



	//ベクター型のcsvというコンテナに入力データcsv_data[]を入れる
	if(myBd.tovec(csv_data, csv)){
		cout << "vector変換完了"<<endl;
	}

	cout <<" csv:"<< csv[0] << endl;
*/

	//配列を何個用意しますか?xC2個
	//xC2個のVectorに突っ込んでいく
	int result_num;
	int r = 2;
	result_num = conb(mycsv.col_num, r);

	vector<P> data;
	//int m_row_num =	mycsv.row_num;
	//int m_col_num = mycsv.col_num;
	data.reserve(mycsv.row_num);

	cout << "conb:" << result_num << endl;

	//comb

	for(int i=0;i< mycsv.col_num;i++){
		order.push_back(i);
	}

	//sokan用ファイルポインタ
	stringstream output_name;
	if(mkdir("all",777)==0){
		cout << "フォルダallを作成しました"<<endl;
		mkdir("all/correlation",777)==0;
		cout << "フォルダall/correlationを作成しました"<<endl;
		mkdir("all/k-means",777)==0;
		cout << "フォルダall/k-meansを作成しました"<<endl;
		mkdir("all/k-means/output",777)==0;
		cout << "フォルダall/k-means/outputを作成しました"<<endl;
		mkdir("all/k-means/graph",777)==0;
		cout << "フォルダall/k-means/graphを作成しました"<<endl;
		mkdir("all/association",777)==0;
		cout << "フォルダall/associationを作成しました"<<endl;
	};

	output_name<< "all/correlation/output.txt";
	sokanf.open(output_name.str());
	sdf.open("all/k-means/standard_deviation.txt");

	//max,min
	for(int i = 0; i < K; i++){
		SD_max[i] = 0;
		SD_min[i] = INT_MAX;
	}

	Bigdata myBd;

	//csv.reserve(mycsv.index);

	cout <<"do"<<endl;

	do{
		sokanf << "[ "<<order[0] << "列目と"<<order[1]<< "列目 ]" <<endl;
		sdf << "[ "<<order[0] << "列目と"<<order[1]<< "列目 ]" <<endl;


		//data[行数]に全組み合わせで値入れる
		for(int j = 0 ; j < mycsv.row_num ; j++){
			data[j].x = mycsv.csv_data[j * mycsv.col_num + order[0]];
			data[j].y = mycsv.csv_data[j * mycsv.col_num + order[1]];
		}

		//ここからdata[]に対して3つの統計処理を行う
		//kmeans関数内でgnuplotまでやってる
		//gnuplotで使うrabelの添え字
		myBd.sokan(mycsv, data, sokanf);
		
		myBd.kmeans(mycsv, data, sheet_num, order[0], order[1], SD_max, SD_min, sdf);

		sheet_num++;
	}while(next_combination(order.begin(),order.begin()+r, order.end()));//csv[]の中の順番が変わる

	cout <<"-----------------------------------------"<<endl;
	cout << "相関とk-means終了"<<endl<<endl;

	myBd.aso(mycsv);

	sokanf.close();
	sdf.close();

	//全部計算終わってからじゃないとフィルタリングはできない
	for(int i=0;i<result_num;i++){
		for(int j=0;j<K;j++){
			//filter(level, SD[i][j],i);
		}
	}

	cout << "Complete!!!" <<endl;

	return 0;
}
Exemplo n.º 15
0
Arquivo: main.cpp Projeto: kotake/R
int main(){

	//int sheet_num = 0;
	vector<int> order;
	int level;
	double SD_max[K], SD_min[K];
	ofstream sokanf;//sokan出力用
	ofstream sdf;//k-meansのクラスタごとの標準偏差の出力用

	const string fn = "iris.csv";
	//const string fn = "maeda_input.txt";

	CSVData mycsv;
	mycsv = CSVData::load_from(fn);

	cout << "new size:"<< mycsv.get_col() * mycsv.get_row() << endl;

	//配列を何個用意しますか?xC2個
	//xC2個のVectorに突っ込んでいく
	int result_num;
	int r = 2;
	result_num =conb(mycsv.get_col(), r);

	vector<P> data;
	data.reserve(mycsv.get_row());

	cout << "conb:" << result_num << endl;

	//comb

	for(int i=0;i< mycsv.get_col();i++){
		order.push_back(i);
	}

	//sokan用ファイルポインタ
	stringstream output_name;

	if(mkdir("all",777)==0){
		cout << "フォルダallを作成しました"<<endl;
		mkdir("all/correlation",777)==0;
		cout << "フォルダall/correlationを作成しました"<<endl;
		mkdir("all/k-means",777)==0;
		cout << "フォルダall/k-meansを作成しました"<<endl;
		mkdir("all/k-means/output",777)==0;
		cout << "フォルダall/k-means/outputを作成しました"<<endl;
		mkdir("all/k-means/graph",777)==0;
		cout << "フォルダall/k-means/graphを作成しました"<<endl;
		mkdir("all/association",777)==0;
		cout << "フォルダall/associationを作成しました"<<endl;
	};

	output_name<< "all/correlation/output.txt";
	sokanf.open(output_name.str());
	sdf.open("all/k-means/standard_deviation.txt");

	//max,min
	for(int i = 0; i < K; i++){
		SD_max[i] = 0;
		SD_min[i] = INT_MAX;
	}

	Result sokan, kmeans, aso;

	/////////////////////////////////////////
	int order_array[result_num][2];
	for(int i=0;i<result_num;i++){
		order_array[i][0] = order[0];
		order_array[i][1] = order[1];
		next_combination(order.begin(), order.begin()+r, order.end());
	}
	///////////////////////////////////////

#pragma omp parallel for
	//nC2回繰り返される
	for(int i=0;i<result_num;i++){//csv[]の中の順番が変わる
		Bigdata myBd;
		sokanf << "[ "<<order[0] << "列目と"<<order[1]<< "列目 ]" <<endl;
		sdf << "[ "<<order[0] << "列目と"<<order[1]<< "列目 ]" <<endl;

		//data[行数]に全組み合わせで値入れる
		for(int j = 0 ; j < mycsv.row_num ; j++){
			data[j].x = mycsv.csv_data[j * mycsv.get_col() + order[0]];
			data[j].y = mycsv.csv_data[j * mycsv.get_col() + order[1]];
		}

		//ここからdata[]に対して3つの統計処理を行う
		//kmeans関数内でgnuplotまでやってる
		//gnuplotで使うrabelの添え字

		sokan = myBd.sokan(mycsv, data, sokanf);

		kmeans = myBd.kmeans(mycsv, data, i, order[0], order[1], SD_max, SD_min, sdf);

		//orderには01,02,03と組み合わせの数が入ってる。また順番が変わる
		next_combination(order.begin(),order.begin()+r, order.end());
		//sheet_num++;
	}

	cout <<"-----------------------------------------"<<endl;
	cout << "相関とk-means終了"<<endl<<endl;

	Bigdata myBd;
	myBd.aso(mycsv);

	sokanf.close();
	sdf.close();

	//フィルタ
	cout <<"-----------------------------------------"<<endl;
	//filter();

	cout << "Complete!!!" <<endl;

	return 0;
}
Exemplo n.º 16
0
void Node::doYourThing()
{
	if (isBuy)
	{
		// Discard hand after buy
		for (int cardIndex = 0; cardIndex < 6; cardIndex++)
		{
			state.discard[cardIndex] += state.hand[cardIndex];
			state.hand[cardIndex] = 0;
		}

		State copyState = state;

		// Check for shuffle
		int cardCounter = 0;
		for (int cardIndex = 0; cardIndex < 6; cardIndex++)
		{
			cardCounter += copyState.deck[cardIndex];
		}
		std::array<int, 6> guaranteedCards = { 0, 0, 0, 0, 0, 0 };
		if (cardCounter < 5)
		{
			for (int cardIndex = 0; cardIndex < 6; cardIndex++)
			{
				guaranteedCards[cardIndex] = copyState.deck[cardIndex];
				copyState.deck[cardIndex] = copyState.discard[cardIndex];
				copyState.discard[cardIndex] = 0;
			}
		}

		// Append each card in deck to string
		std::string s = "";
		for (int cardIndex = 0; cardIndex < 6; cardIndex++)
		{
			for (int j = 0; j < copyState.deck[cardIndex]; j++)
			{
				s.append(std::to_string(static_cast<long long>(cardIndex)));
			}
		}

		// If <= than 5 in cardCounter, then draw fewer cards.
		std::size_t k = 5;
		if (cardCounter < 5)
			k = 5 - cardCounter;
	
		// While there are still new combinations of chars in string, create a new draw.
		std::vector<std::array<int, 6>> draws;
		do
		{
			std::array<int, 6> draw = { 0, 0, 0, 0, 0, 0 };
			// First, add the guaranteedCards
			for (int cardIndex = 0; cardIndex < 6; cardIndex++)
			{
				draw[cardIndex] += guaranteedCards[cardIndex];
			}

			// This is the combinationString, containing a combination of cards.
			std::string combinationString = std::string(s.begin(), s.begin() + k); 

			// For each letter in the combinationString
			for (int stringIndex = 0; stringIndex < k; stringIndex++)
			{
				// Convert letter to int, and add to draw
				int cardNumber = atoi(std::string(combinationString.begin() + stringIndex, combinationString.begin() + stringIndex + 1).c_str());
				draw[cardNumber]++;
			}
			
			// Finally, add draw to collecction of draws
			draws.push_back(draw);
		} while (next_combination(s.begin(), s.begin() + k, s.end()));

		// For each draw, create child node
		for (std::vector<std::array<int, 6>>::iterator iterator = draws.begin(); iterator != draws.end(); ++iterator)
		{
			Node* newNodePtr = bfPtr->requestNewNodePtr();
			newNodePtr->isBuy = false;

			for (int cardIndex = 0; cardIndex < 6; cardIndex++)
			{
				newNodePtr->state.hand[cardIndex] = (*iterator)[cardIndex];
				newNodePtr->state.deck[cardIndex] = copyState.deck[cardIndex] - (*iterator)[cardIndex] + guaranteedCards[cardIndex];
				newNodePtr->state.discard[cardIndex] = copyState.discard[cardIndex];
				newNodePtr->state.supplyPiles[cardIndex] = copyState.supplyPiles[cardIndex];
			}
			children.push_back(newNodePtr);
		}
	}
	else
	{
		// Find money available
		int money = 0;
		money += state.hand[0]*1;
		money += state.hand[1]*2;
		money += state.hand[2]*3;

		// Find available choices
		bool choices[] = {false,false,false,false,false,false,false};	// If a choice is false, then it is not an option.
		choices[0] = true;							// Can always choose to not buy
		choices[6] = true;							// Can always buy copper
		if (money >= 2)
			choices[3] = true;
		if (money >= 3)
			choices[1] = true;
		if (money >= 5)
			choices[4] = true;
		if (money >= 6)
			choices[2] = true;
		if (money >= 8)
			choices[5] = true;

		// Create a child node for each choice
		for (int choiceIndex = 0; choiceIndex < 7; choiceIndex ++)
		{
			if (choices[choiceIndex] == false)
				continue;

			Node* newNodePtr = bfPtr->requestNewNodePtr();
			newNodePtr->isBuy = true;
			for (int cardIndex = 0; cardIndex < 6; cardIndex++)
			{
				newNodePtr->state.deck[cardIndex] = state.deck[cardIndex];
				newNodePtr->state.hand[cardIndex] = state.hand[cardIndex];
				newNodePtr->state.discard[cardIndex] = state.discard[cardIndex];
				newNodePtr->state.supplyPiles[cardIndex] = state.supplyPiles[cardIndex];
			}

			newNodePtr->boughtCard = choiceIndex;
			if (newNodePtr->boughtCard != 6)										// If a card was bought, then put one in discard, and remove one from supply
			{
				newNodePtr->state.discard[newNodePtr->boughtCard] ++;
				newNodePtr->state.supplyPiles[newNodePtr->boughtCard] --;
			}
			
			children.push_back(newNodePtr);
		}
	}
}
Exemplo n.º 17
0
void FlatUCBMod::createDrawNodes(Node* parentNode, GameState& currentState, int currentlyPlaying, int numberOfCards, bool createThiefDraws)
{
	// Create as many draw nodes as there are combinations of cards, based on numberOfCards to draw, and the current deck.
	// If there are cards on top, then draw as many of these needed first, before moving on to draw from deck.
	// If deck does not have enough cards, then first draw the ones in draw, then shuffle and draw the rest.

	GameState copyState = currentState;

	std::array<int, INSUPPLY> guaranteedCards;
	for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++) // Initialize guaranteedCards array to zeroes.
		guaranteedCards[cardIndex] = 0;

	// If there are any cards on top, put them in guaranteed cards, and decrement numberOfCards.
	// If numberOfCards reaches zero, then no more cards should be drawn.
	while (numberOfCards > 0 && copyState.playerStates[currentlyPlaying].topOfDeckAsIndex.size() > 0)
	{
		numberOfCards--; // Decrement number of cards for each draw, based on the number of guaranteed cards.
		guaranteedCards[copyState.playerStates[currentlyPlaying].topOfDeckAsIndex.top()]++;
		copyState.playerStates[currentlyPlaying].deck[copyState.playerStates[currentlyPlaying].topOfDeckAsIndex.top()]--;
		copyState.playerStates[currentlyPlaying].topOfDeckAsIndex.pop();
	}


	// Check for shuffle
	int cardCounter = 0;
	for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++)
	{
		cardCounter += copyState.playerStates[currentlyPlaying].deck[cardIndex];
	}
	// "Shuffle" after making current cards guaranteedcards.
	if (cardCounter < numberOfCards)
	{
		// Put the remaining cards in deck over in guaranteedCards, put discard in deck and set discard to zero.
		for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++)
		{
			guaranteedCards[cardIndex] += copyState.playerStates[currentlyPlaying].deck[cardIndex];
			copyState.playerStates[currentlyPlaying].deck[cardIndex] = copyState.playerStates[currentlyPlaying].discard[cardIndex];
			copyState.playerStates[currentlyPlaying].discard[cardIndex] = 0;
		}
	}

	std::vector<std::array<int, INSUPPLY>> draws;
	std::vector<double> probabilities;

	// Create one draw if there are enough known cards to draw.
	if (numberOfCards == 0)
	{
		std::array<int, INSUPPLY> draw;
		for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++)
			draw[cardIndex] = guaranteedCards[cardIndex]; // The draw is equal to each card in guaranteedCards
		draws.push_back(draw);
		probabilities.push_back(1.0);
	}
	else
	{
		// Finding n and k for draw probability
		int n = 0; // Total cards - those in guaranteedCards and discard. Possible cards to draw.
		std::size_t k = numberOfCards;
		// If less than numberOfCards in cardCounter, then draw fewer cards.
		if (cardCounter < numberOfCards)
			k = numberOfCards - cardCounter;

		// Append each card in deck to string
		std::string s = "";
		for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++)
		{
			for (int j = 0; j < copyState.playerStates[currentlyPlaying].deck[cardIndex]; j++)
			{
				s.append(CardManager::cardLookupByIndex[cardIndex].charId);
				n++;
			}
		}

		do // While there are still new combinations of chars in string, create a new draw.
		{
			double probability = 0, nkInCardComboPossibilities = 1, nkPossibilities = 1;

			std::array<int, INSUPPLY> draw;
			for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++) // Dynamic initialization
				draw[cardIndex] = 0;

			// This is the combinationString, containing a combination of cards.
			std::string combinationString = std::string(s.begin(), s.begin() + k);

			// For each letter in the combinationString
			for (int stringIndex = 0; stringIndex < k; stringIndex++)
			{
				// Convert letter to int, and add to draw
				std::string cardCharId = std::string(combinationString.begin() + stringIndex, combinationString.begin() + stringIndex + 1);
				draw[CardManager::cardLookupCharToIndex[cardCharId]]++;
			}

			// Find possible ways to draw the draw
			for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++)
			{
				int nInCardCombo = copyState.playerStates[currentlyPlaying].deck[cardIndex];
				int kInCardCombo = draw[cardIndex];
				nkInCardComboPossibilities *= choose(nInCardCombo, kInCardCombo);
			}

			// Add the guaranteedCards
			for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++)
			{
				draw[cardIndex] += guaranteedCards[cardIndex];
			}

			// Find the total possible outcomes
			nkPossibilities = choose(n, k);

			// Calculate probability
			probability = nkInCardComboPossibilities / nkPossibilities;

			// Finally, add draw to collection of draws, and probability to collection of probabilities (associate a probability with each draw)
			draws.push_back(draw);
			probabilities.push_back(probability);
		} while (next_combination(s.begin(), s.begin() + k, s.end()));
	}


	if (createThiefDraws)
	{
		// For each draw, create child node
		for (int drawCounter = 0; drawCounter < draws.size(); drawCounter++)
		{
			Node* newNodePtr = requestNewNode();
			newNodePtr->currentState = currentState;
			newNodePtr->opt.absoluteCardId = 0;
			newNodePtr->opt.absoluteExtraCardId = 0;
			for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++)
			{
				if (newNodePtr->opt.absoluteCardId == 0 && draws[drawCounter][cardIndex] > 0)
					newNodePtr->opt.absoluteCardId = CardManager::cardLookupByIndex[cardIndex].id;
				else if (draws[drawCounter][cardIndex] > 0)
					newNodePtr->opt.absoluteExtraCardId = CardManager::cardLookupByIndex[cardIndex].id;

				newNodePtr->currentState.playerStates[currentlyPlaying].deck[cardIndex] = copyState.playerStates[currentlyPlaying].deck[cardIndex] + guaranteedCards[cardIndex];
				newNodePtr->currentState.playerStates[currentlyPlaying].discard[cardIndex] = copyState.playerStates[currentlyPlaying].discard[cardIndex];
				newNodePtr->currentState.supplyPiles[cardIndex] = copyState.supplyPiles[cardIndex];
			}
			newNodePtr->currentState.playerStates[currentlyPlaying].topOfDeckAsIndex = copyState.playerStates[currentlyPlaying].topOfDeckAsIndex;
			parentNode->childrenPtrs.push_back(newNodePtr);
			newNodePtr->parentPtr = parentNode;
			newNodePtr->playerPlaying = currentlyPlaying;
			newNodePtr->opt.type = THIEFFLIP;
			newNodePtr->flags = THIEFDRAW;
			newNodePtr->probability = probabilities[drawCounter];
		}
	}
	else
	{
		// For each draw, create child node
		for (int drawCounter = 0; drawCounter < draws.size(); drawCounter++)
		{
			Node* newNodePtr = requestNewNode();
			newNodePtr->currentState = currentState;

			for (int cardIndex = 0; cardIndex < INSUPPLY; cardIndex++)
			{
				newNodePtr->currentState.playerStates[currentlyPlaying].hand[cardIndex] += draws[drawCounter][cardIndex];
				newNodePtr->currentState.playerStates[currentlyPlaying].deck[cardIndex] = copyState.playerStates[currentlyPlaying].deck[cardIndex] + guaranteedCards[cardIndex] - draws[drawCounter][cardIndex];
				newNodePtr->currentState.playerStates[currentlyPlaying].discard[cardIndex] = copyState.playerStates[currentlyPlaying].discard[cardIndex];
				newNodePtr->currentState.supplyPiles[cardIndex] = copyState.supplyPiles[cardIndex];
			}
			newNodePtr->currentState.playerStates[currentlyPlaying].topOfDeckAsIndex = copyState.playerStates[currentlyPlaying].topOfDeckAsIndex;
			parentNode->childrenPtrs.push_back(newNodePtr);
			newNodePtr->parentPtr = parentNode;
			newNodePtr->playerPlaying = currentlyPlaying;
			newNodePtr->opt.absoluteCardId = -2;
			newNodePtr->opt.type = DRAW;
			newNodePtr->visited = 1;
			newNodePtr->value = -1;
			newNodePtr->probability = probabilities[drawCounter];
		}
	}
}