Hi. I am writing a program that takes 8 soccer teams and draws them randomly to play against each other. Every time the program runs, it selects the same team twice, or even more. I know what the problem is, and why that happens, but I do not know how I can fix it.
Is there any way I can fix that?
Thank you so much for any help!
cout << "\t\tWELCOME TO THE UEFA CHAMPIONS LEAGUE QUARTER FINALS DRAW " << endl;
cout << "\n\t\tTHE DRAW WILL INCLUDE THE FOLLOWING TEAMS: " << endl;
cout << "\n\t. REAL MADRID (ESP) ";
cout << "\n\t. BARCELONA (ESP) ";
cout << "\n\t. BAYERN MUNCHEN (GER) ";
cout << "\n\t. CHELSEA (ENG) ";
cout << "\n\t. PARIS SAINT GERMAIN (FRA) ";
cout << "\n\t. ARSENAL (ENG) ";
cout << "\n\t. DORTMUND (GER) ";
cout << "\n\t. JUVENTUS (ITA) ";
cout << "\n\t\tTHERE ARE NO RULES IN REGARDS TO WHICH TEAM CAN PLAY WHO. ANYONE CAN DRAW ANYONE! " << endl << endl;
cout << "\tTO START THE DRAW, PLEASE PRESS S AND ENTER! GOOD LUCK TO ALL TEAMS! ";
cin >> start;
if ((start == 's') || (start == 'S'))
{
draw();
}
else
{
cout << "\n\t\tINVALID ENTRY! THE PROGRAM WILL NOW CLOSE! OPEN AGAIN AND ONLY PRESS S TO START THE DRAW! " << endl;
Sleep(5000);
exit(0);
}
Create a parallel array ( ie the index number of teams array and the new one correspond to each other) that stores a 0 or 1 depending upon whether it has been already selected.
If the draw() selects a team already drawn discard that selection and get another one.
1. Store the teams in a standard library container that supports std::random_shuffle(), instead of a C-style array
2. std::random_shuffle() the container, select the team from the front or back of the container, as per container rules
3. pop_back() or pop_front as required
4. repeat
#include <iostream>
#include <string>
#include <ctime>
#include <random>
#include <algorithm>
#include <thread>
#include <chrono>
void draw( std::string teams[], std::size_t num_teams ) ;
int main()
{
std::cout << "Welcome to the UEFA Champions League quarter finals draw\n"
<< "\nThe draw will include the following teams:\n\n" ;
const std::size_t NTEAMS = 8 ;
std::string teams[NTEAMS] =
{
"Real Madrid (ESP)",
"Barcelona (ESP)",
"Bayern Munchen (GER)",
"Chelsea (ENG)",
"Paris Saint Germain (FRA)",
"Arsenal (ENG)",
"Dortmund (GER)",
"Juventus (ITA)"
};
// http://www.stroustrup.com/C++11FAQ.html#forfor( const std::string& team_name : teams ) std::cout << '\t' << team_name << '\n' ;
std::cout << "\nThere are no rules in regards to which team can play who.\n"
<< "Anyone can draw anyone!\n\n"
<< "To start the draw, please press s and enter!\n"
<< "Good luck to all teams!\n\n";
char start ;
std::cin >> start;
if ( (start == 's') || (start == 'S') ) draw( teams, NTEAMS ) ;
else
{
std::cout << "\nInvalid entry! the program will now close!\n"
<< "Open again and only press s to start the draw!\n" ;
}
}
void draw( std::string teams[], std::size_t num_teams )
{
// random number engine, seeded with the current time
// http://en.cppreference.com/w/cpp/numeric/random
std::mt19937 rng( std::time(nullptr) ) ;
// shuffle the teams in the array like we would shuffle a pack of cards
// http://en.cppreference.com/w/cpp/algorithm/random_shuffle
// note that std::random_shuffle is deprecated in C++14 and is removed in C++17
std::shuffle( teams, teams+num_teams, rng ) ; // use std::shuffle in new code
// print out the pairings
for( std::size_t i = 0 ; i < num_teams ; i += 2 )
{
// http://en.cppreference.com/w/cpp/thread/sleep_for
std::this_thread::sleep_for( std::chrono::seconds(1) ) ;
std::cout << "\n\t" << teams[i] << " vs. " << teams[i+1] << '\n' ;
}
// if the number of teams is odd, there would be one unpaired team
// (the function draw() is generic; we need not hard code for eight teams
if( num_teams%2 == 1 ) std::cout << "\n\t" << teams[num_teams-1] << " gets a bye\n" ;
}