Random teams that don't repeat

closed account (oEwqX9L8)
I'm writing a little program for a C++ class to practice using vectors. The program takes in restaurants and than puts them into a bracket style tournament. The only Standard Library function I am allowed to use is the rand() number generator.

The problem I am having is preventing the restaurants from repeating in a single round (i.e. the random number generator can create the same random number). My attempted solution to this was to create a temporary vector to hold the winners and then delete the winner and the loser from the original vector but using the vector[random_number] and vector.push_back() screws up the order.

Here is the function I'm using so far.

string generate_tournament (vector<string> test, int number_rounds){
string winner = "";
vector<string> round_winners;
for (int i = 0; i < number_rounds; i++){
for (int j = 0; j < (test.size()/2); j++){
int first_rand = rand() % (test.size() -1);
int second_rand = rand()% (test.size() -1);
string first_rest = test[first_rand];
string seco_rest = test[second_rand];
cout << "Choose between these two restaurants by entering 1 or 2.\n";
cout << "1 - " << first_rest << endl << "2 - " << seco_rest << endl;
int choice;
cin >> choice;
while (choice !=1 && choice !=2){
cout << "Please only enter either 1 or 2.\n";
cin >> choice;
}
if (choice == 1){
round_winners.push_back(first_rest);

}
else if (choice == 2){
round_winners.push_back(seco_rest);

}
}
}
return winner;
}


Can anyone give me some direction for where to go to prevent a restaurant from appearing more than once in a round?

Thanks for any tips!
> Can anyone give me some direction for where to go to prevent a restaurant from appearing more than once in a round?

Create a randomly shuffled sequence of the teams and then pair them in order (0,1), (2,3), (4,5) ...

Something along these lines, perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>

void do_swap( std::string& a, std::string& b ) // can't use std::swap
{
     std::string temp = a ; // static_cast<std::string&&>(a) ; // can't use std::move
     a = b ; // static_cast<std::string&&>(b) ;
     b = temp ; // static_cast<std::string&&>(temp) ;
}

// the "inside out" variant of the fisher–yates shuffle (can't use std::shuffle)
// https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle#The_.22inside-out.22_algorithm
std::vector<std::string> make_shuffled_copy( const std::vector<std::string>& srce )
{
    std::vector<std::string> cpy ;

    for( std::string str : srce ) // for each string in srce http://www.stroustrup.com/C++11FAQ.html#for
    {
        cpy.push_back(str) ; // add it to the back of cpy

        int rand_pos = std::rand() % cpy.size() ; // choose a random position
        do_swap( cpy[rand_pos], cpy.back() ) ; // and swap
    }

    return cpy ;
}

void print_bracket( const std::vector<std::string>& teams )
{
    std::vector<std::string> shuffled_copy = make_shuffled_copy(teams) ;

    // two at a time, till zero or one are left (0,1), (2,3), (4,5) ...
    for( std::size_t i = 0 ; i < shuffled_copy.size()/2 ; ++i )
        std::cout << i+1 << ". " << shuffled_copy[i*2] << " vs. " << shuffled_copy[i*2+1] << '\n' ;

    if( teams.size() % 2 == 1 ) std::cout << '\n' << shuffled_copy.back() << " gets a bye to the next round\n" ;
}

http://coliru.stacked-crooked.com/a/7035a838422dd79e
Topic archived. No new replies allowed.