Solved

Advanced all versus all, match assignment algorithme, creating matching so all teams always can play

Posted on 2004-09-01
45
271 Views
Last Modified: 2010-04-17
I have when you think of it  a very simple algorithme ( thanks to str_ek on an earlier EE post ) creating the matchplan, whom to play against whom and whether they are on home court or not... ( i can have either 4, 6, 8 or 10 teams )


    1   2   3   4   5   6
1  -    h   a   h   a   h
2  a   -    h   a   h   a
3  h   a   -    h   a   h
4  a   h   a   -    h   a
5  h   a   h   a   -   h
6  a   h   a   h   a   -

For example from this chart you can read that Team 1's matches will be the following :
1 vs 2
3 vs 1
1 vs 4
5 vs 1
1 vs 6

Okay but the thing is that all teams has to play every time and at the same time, this means that i need is to calculate which 3 matches that can be played in all of the 5 rounds.
Example round
1 vs 2
3 vs 4
5 vs 6

the second round could for example not be
1 vs 4
2 vs 3
because this combination would mean that 5 vs 6 should play again.
I hope iam explaining it well

Okay so what i need is some algorithme which can calculate which matches for each round (5 rounds in the example of 6 teams) should be playd so that each team can play every round without ever meeting the same opponent

0
Comment
Question by:mSchmidt
  • 15
  • 15
  • 9
  • +2
45 Comments
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
Hi mSchmidt,

Divide your teams into two groups ... given 2n teams, your have 2 groups of n teams each
label the teams A1-An and B1-Bn

First let us get intergroup matches out of the way

First
Ai plays with Bi, for all 1<=i<=n
next, Ai plays with B (i+1)%n ... and so until all n opponents in the other group are exhausted ... this is just circular ordering

 Go recursive and divide groups A and B into sub groups again

I think this should be easy to implement and should work. Oly special case will be when n is odd, in that case divide into two unequal groups and increment in those groups according to their capacity or schedule the match between left outs in group A and B

Sunnycoder
0
 

Author Comment

by:mSchmidt
Comment Utility
I do not believe iam not following you could you create some pseudo code, and again i do only have 4, 6, 8 or 10 teams and in 1 round they are only supposed to play against each other once...
0
 

Author Comment

by:mSchmidt
Comment Utility
And sorry i also have to make sure that each team has equally many Home and Away games
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
Refer back to my rotating-wheels I talked about at:

http://www.experts-exchange.com/Programming/Q_21114785.html#11951196

It will solve the problem.

-Ram
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
O nevermind, its not quite right I found out.

-Ram
0
 
LVL 3

Expert Comment

by:str_ek
Comment Utility
you  need just to trace the diagonals :) it's realy simple again...

in
    1   2   3   4   5   6
1  -    h   a   h   a   h
2  a   -    h   a   h   a
3  h   a   -    h   a   h
4  a   h   a   -    h   a
5  h   a   h   a   -   h
6  a   h   a   h   a   -

it's enought to "execute" one of "triangles" (cos the other one is just a reverse transcript :))

so, to be shore not to chose a blocking series you have to make teams unique... in diagonal (any) they are unique...
the only problem is for diagonals shorter than series...

   1   2   3   4   5   6
1  -    1   2   4   5  5
2  a   -    1   3   4  5
3  h   a   -    1   3  4
4  a   h   a   -    2  3
5  h   a   h   a   -   2
6  a   h   a   h   a   -

now 5 is the "blocking" series... all you need to do is switch it with team uniq elements from non-blocking series....
like (for 3 in series - only one swap)

  1   2   3   4   5   6
1  -    1   2   4   1  5
2  a   -    5   3   4  2
3  h   a   -    1   3  4
4  a   h   a   -    5  3
5  h   a   h   a   -   2
6  a   h   a   h   a   -

that's the general idea :)

for as little as 4 teams there will be more blocking series, than nonblocking series, what leads to conclusion,that it's not possible to be played in 3 match series...
0
 
LVL 5

Assisted Solution

by:rsriprac
rsriprac earned 100 total points
Comment Utility
This will mix it up a bit, but it should work.  This time it is like a rubber band with all the teams inscribed on it.  When you pinch the ends of the band and the teams will align up.  This will define who plays who.  As you rotate the band, this will define a new round set. try sudo code:  (also note that if you have a large count of rounds, the matches WILL have to repeat.  And I believe that the max rounds before repeat is n/2)


team = {"T1", "T2", ... , "Tn"};  //n team, where n is even
FOR( round =0, round < roundmax, round ++)
{
    steam = RSPLIT(team);
    teamA = steam[0];
    teamB = steam[1];
   
    FOR(i = 0, i < (COUNT(team)/2) )
    {
        PRINT(teamA[i] & " vs. " & teamB[i]);
    }

    team = ROTATE(team);
}

Some function definition

ROTATE( array)
//return a single array
//It basically moves the teams by one and place the last in array to the first element
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then ROTATE(foo) = {"T4", "T1", "T2", "T3"}

REVERSE(array)
//return a single array
//It basically flips the array
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then REVERSE(foo) = {"T1", "T2", "T3", "T4"}

RSPLIT(array)
//returns two arrays
//i.e. say  foo = {"T1", "T2", "T3", "T4, "T5", "T6"}
//      then SPLIT(foo) = {{"T1", "T2", "T3"}, REVERSE({"T4, "T5", "T6"})} = {{"T1", "T2", "T3"},{"T4", "T5", "T6"}}



0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
sorry, the line in RSPLIT:

//      then SPLIT(foo) = {{"T1", "T2", "T3"}, REVERSE({"T4, "T5", "T6"})} = {{"T1", "T2", "T3"},{"T4", "T5", "T6"}}

should be:

//      then SPLIT(foo) = {{"T1", "T2", "T3"}, REVERSE({"T4, "T5", "T6"})} = {{"T1", "T2", "T3"},{"T6", "T5", "T4"}}
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
O and the output of the sudocode should be the matches.  I left out some details, but this is essentially the same but with more print statements::

team = {"T1", "T2", ... , "Tn"};  //n team, where n is even
FOR( round =0, round < roundmax, round ++)
{
    PRINT("Round: " & (round +1) );
    PRINT("------------------" );

    steam = RSPLIT(team);
    teamA = steam[0];
    teamB = steam[1];
   
    FOR(i = 0, i < (COUNT(team)/2) )
    {
        PRINT(teamA[i] & " vs. " & teamB[i]);
    }

    team = ROTATE(team);
}

Some function definition

ROTATE( array)
//return a single array
//It basically moves the teams by one and place the last in array to the first element
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then ROTATE(foo) = {"T4", "T1", "T2", "T3"}

REVERSE(array)
//return a single array
//It basically flips the array
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then REVERSE(foo) = {"T1", "T2", "T3", "T4"}

RSPLIT(array)
//returns two arrays
//i.e. say  foo = {"T1", "T2", "T3", "T4, "T5", "T6"}
//      then SPLIT(foo) = {{"T1", "T2", "T3"}, REVERSE({"T4, "T5", "T6"})} = {{"T1", "T2", "T3"},{"T6", "T5", "T4"}}
0
 
LVL 3

Expert Comment

by:str_ek
Comment Utility
bwha^_^ well for 4 teams teher is one blocking and one non-blocking, but the blocked is in double block, so 3 series are to be played.. (oh what a mess i make)
0
 

Author Comment

by:mSchmidt
Comment Utility
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then REVERSE(foo) = {"T1", "T2", "T3", "T4"}

Seriously ? or do you mean

//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then REVERSE(foo) = {"T4","T3","T2","T1"}

?


for as little as 4 teams there will be more blocking series, than nonblocking series, what leads to conclusion,that it's not possible to be played in 3 match series...
thats not true i can do that one in my head
Round 1
  T1 vs T2
  T3 vs T4
Round 2
  T1 vs T3
  T2 vs T4
Round 3
  T4 vs T1
  T3 vs T2

right ? :))
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
I for got that you have a constrant that it has to have 50/50 away and home games.  This could be done by flipping the rubber band every round.  so this is the new code with the flip motion:

team = {"T1", "T2", ... , "Tn"};  //n team, where n is even
FOR( round =0, round < roundmax, round ++)
{
    PRINT("Round: " & (round +1) );
    PRINT("------------------" );

    steam = RSPLIT(team);
    teamA = steam[0];
    teamB = steam[1];
   
    FOR(i = 0, i < (COUNT(team)/2) )
    {
        //Flip the home and away every round to even out the Away and home games
        IF(EVEN(round))
        {
            PRINT(teamA[i] & " vs. " & teamB[i]);
        }ELSE
        {
            PRINT(teamB[i] & " vs. " & teamA[i]);
        }
    }

    team = ROTATE(team);
}

Some function definition

EVEN(int)
//returns boolean value

ROTATE( array)
//returns a single array
//It basically moves the teams by one and place the last in array to the first element
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then ROTATE(foo) = {"T4", "T1", "T2", "T3"}

REVERSE(array)
//returns a single array
//It basically flips the array
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then REVERSE(foo) = {"T1", "T2", "T3", "T4"}

RSPLIT(array)
//returns two arrays
//i.e. say  foo = {"T1", "T2", "T3", "T4, "T5", "T6"}
//      then SPLIT(foo) = {{"T1", "T2", "T3"}, REVERSE({"T4, "T5", "T6"})} = {{"T1", "T2", "T3"},{"T6", "T5", "T4"}}
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
Opps, damn too many mistakes, yes its:

//      then REVERSE(foo) = {"T4","T3","T2","T1"}

0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
I feel like i'm spamming up the place with my code. hehe.

-Ram
0
 

Author Comment

by:mSchmidt
Comment Utility
What if they are only going to play one round ?
0
 

Author Comment

by:mSchmidt
Comment Utility
Sorry str_ek i do not understand

   1   2   3   4   5   6
1  -    1   2   4   5  5
2  a   -    1   3   4  5
3  h   a   -    1   3  4
4  a   h   a   -    2  3
5  h   a   h   a   -   2
6  a   h   a   h   a   -

First of all... how do you get those numbers ?
and how would you extract matches from this ?
please explain
0
 

Author Comment

by:mSchmidt
Comment Utility
Ram, another thing in your pseudo code, when will the teams in for example TeamA play against each other... teams in TeamA will get only to play against those in TeamB they will never meet the teams within TeamA
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
O ****, yea huh?  I'm lacking sleep, I'm off by a loop, this should better simulate a rotating rubber-band model.

team = {"T1", "T2", ... , "Tn"};  //n team, where n is even
FOR( round =0, round < roundmax, round ++)
{
    PRINT("Round: " & (round +1) );
    PRINT("------------------" );

   
    FOR(j = 0, j < (COUNT(team)/2) , i++)
    {
        steam = RSPLIT(team);
        teamA = steam[0];
        teamB = steam[1];

        FOR(i = 0, i < (COUNT(team)/2) , i++)
        {
            //Flip the home and away every round to even out the Away and home games
            IF(EVEN(round))
            {
                PRINT(teamA[i] & " vs. " & teamB[i]);
            }ELSE
            {
            PRINT(teamB[i] & " vs. " & teamA[i]);
            }
        }

        team = ROTATE(team);

    }
}

Some function definition

EVEN(int)
//returns boolean value

ROTATE( array)
//returns a single array
//It basically moves the teams by one and place the last in array to the first element
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then ROTATE(foo) = {"T4", "T1", "T2", "T3"}

REVERSE(array)
//returns a single array
//It basically flips the array
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then REVERSE(foo) = {"T4", "T3", "T2", "T1"}

RSPLIT(array)
//returns two arrays
//i.e. say  foo = {"T1", "T2", "T3", "T4, "T5", "T6"}
//      then SPLIT(foo) = {{"T1", "T2", "T3"}, REVERSE({"T4, "T5", "T6"})} = {{"T1", "T2", "T3"},{"T6", "T5", "T4"}}
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
Correction line:

FOR(j = 0, j < (COUNT(team)/2) , i++)

is support to be:

FOR(j = 0, j < (COUNT(team)/2) , j++)
0
 

Author Comment

by:mSchmidt
Comment Utility
I still see one problem, iam sorry =)

You are which team will be on home court only in the next round but if i have only ONE round, i still need them to play equally many Home and away ( propably of by one in some situation but each team should as much as possible play equally many home and away games)
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
O sure, just change the line:

IF(EVEN(round))

to:

// Will flip the team to the oppsite side each match and make sure we dont flip the top or botto since they are auto-flipped when they are rotated to the oppsite side in the previous or next match (depend if they are on the bottom or top of the band).



team = {"T1", "T2", ... , "Tn"};  //n team, where n is even
FOR( round =0, round < roundmax, round ++)
{
    PRINT("Round: " & (round +1) );
    PRINT("------------------" );

   
    FOR(j = 0, j < (COUNT(team)/2) , j++)
    {
        steam = RSPLIT(team);
        teamA = steam[0];
        teamB = steam[1];

        FOR(i = 0, i < (COUNT(team)/2) , i++)
        {
            //Flip the home and away every match to even out the Away and home games
            IF(EVEN(j))
            {
                PRINT(teamA[i] & " vs. " & teamB[i]);
            }ELSE
            {
                PRINT(teamB[i] & " vs. " & teamA[i]);
            }
        }

        team = ROTATE(team);

    }
}

Some function definition

EVEN(int)
//returns boolean value

ROTATE( array)
//returns a single array
//It basically moves the teams by one and place the last in array to the first element
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then ROTATE(foo) = {"T4", "T1", "T2", "T3"}

REVERSE(array)
//returns a single array
//It basically flips the array
//i.e. say  foo = {"T1", "T2", "T3", "T4"}
//      then REVERSE(foo) = {"T4", "T3", "T2", "T1"}

RSPLIT(array)
//returns two arrays
//i.e. say  foo = {"T1", "T2", "T3", "T4, "T5", "T6"}
//      then SPLIT(foo) = {{"T1", "T2", "T3"}, REVERSE({"T4, "T5", "T6"})} = {{"T1", "T2", "T3"},{"T6", "T5", "T4"}}
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
I think its getter closer with every revision, lol.  I think I'm still missing the code to the flip prevention when it on top or bottom of the band.  There should be an inset in it to check

 IF(j != 0 || j != COUNT(team)/2 -1 )

Something like:

            //Flip the home and away every match to even out the Away and home games
            IF(EVEN(j) || (j == 0 || j == COUNT(team)/2 -1 ) )
            {
                PRINT(teamA[i] & " vs. " & teamB[i]);
            }ELSE
            {
                PRINT(teamB[i] & " vs. " & teamA[i]);
            }


-Ram
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 3

Expert Comment

by:str_ek
Comment Utility
hi again...
1 is for 1. "seson"
2 for "second"

diagonals just  let you couple them in eazy way :) it's the visual representation of linear independence
0
 
LVL 3

Expert Comment

by:str_ek
Comment Utility
you said you'd like a 3 mach packs playable "at once"

the pattern to pack it is like on
      1   2   3   4   5   6

1     -    1   2   4   5  5
2     a   -    1   3   4  5
3     h   a   -    1   3  4
4     a   h   a   -    2  3
5     h   a   h   a   -   2
6     a   h   a   h   a   -

ones are for 1. pack twos for 2. etc..

blocked packs elimination is explained in my previous posts
0
 

Author Comment

by:mSchmidt
Comment Utility
Str_ek but you cant play all the 1's in one round, the same teams popup and they cant play two games at once
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
I hope my rubber band analogy could be visualized, cause it'll help understand the base idea, and all it is then just a matter of tweeks.  The rubber band will prevent any multi-math per team per round problems.  You just need to tweek it with twists to achive other constraints.

-Ram
0
 
LVL 19

Accepted Solution

by:
drichards earned 400 total points
Comment Utility
Here's a solution that seems to generate the rubber band effect using a matrix.  I'm going to code up the rubber band algorithm to see how they compare.  Each row of the printout is a round.  This algorithm handles odd numbers of teams/players as well as evens (odds are actually easier).  Most of the code is setting up the data structure (you can do it without the data structure, but it's more code) and printing the result.

void ScheduleMatches(const int NPLAYERS)
{
    // This logic assumes a layout of N rounds of play with M matches
    // in each round and P total players.  There is a "top-half" logic
    // which looks like this:
    //
    //   Match#  Rounds->  1     2      3      4      5      6    7 ....
    //     V
    //     1              P,1  P-1,1  P-2,1  P-3,1  P-4,1  P-5,1  ...
    //     2             P-1,2 P-2,2  P-3,2  P-4,2  P-5,2  ...
    //     3             P-2,3 P-3,3  P-4,3  P-5,3  ...
    //    ...
    // And a "bottom-half" logic which looks lke this:
    //
    //   Match#  Rounds-> ...  N-5   N-4   N-3  N-2  N-1  N
    //     V
    //    ...
    //    M-2                            ...    5,P-2  4,P-2
    //    M-1                     ...    5,P-1  4,P-1  3,P-1
    //    M                    ...   5,P  4,P    3,P    2,P
    //
    // The only catch is the row of last matches for each round.  In
    // the case of even number of players, there is a lost degree of
    // freedom without the extra player.  Thus, the "bottom-half" is
    // calculated by using P against the only player left in the round
    // who is not yet scheduled.  This means the last row (M) above
    // is not that nicely ordered in the even-player scenario.  The
    // matches are the same, but ordered differently.
    //

    std::vector<std::vector<Matchup> > matches;

    // Total games for all teams to play each other once
    const int numGames = NPLAYERS*NPLAYERS/2 - NPLAYERS/2;
    // Total games per round
    const int gpr = NPLAYERS/2;
    // Number of rounds
    const int nRounds = numGames/gpr;
    // If odd number of players, we've got an odd man out each round
    int oddPlayer = nRounds - NPLAYERS + 1;

    // Allocate data structure
    std::vector<Matchup> v;
    v.reserve(gpr);
    for ( int ii = 0; ii < nRounds; ii++ )
    {
        matches.push_back(v);
        for ( int jj = 0; jj < gpr; jj++ ) matches[ii].push_back(Matchup(0,0));
    }

    // Actual logic begins here...
    for ( int ii = 0; ii < gpr; ii++ )
    {
        int t1 = ii+1;
        int t2 = NPLAYERS-ii;
        for ( int jj = 0; jj < nRounds; jj++ )
        {
            // For all rows except last row "bottom-half" of even player case...
            if ( ii+1 < gpr || oddPlayer != 0 || jj < 1 )
            {
                // If t2 == t1, switch to "bottom-half" logic
                if ( t2 == t1 ) { t2 = gpr+ii+oddPlayer; t1 = t2+1; }
                matches[jj][ii].SetMatchup(t2,t1);
            }
            else
            {
                // This is the "bottom-half" logic for the last row of the even player case.
                // Final match is just the last team (# NPLAYERS) and the other unscheduled team this round.
                bool playerActive[64] = { 64*false };
                for ( int kk = 0; kk < gpr-1; kk++ )
                {
                    playerActive[matches[jj][kk].m_team1-1] = true;
                    playerActive[matches[jj][kk].m_team2-1] = true;
                }
                for ( int kk = 0; kk < NPLAYERS; kk++ ) if ( !playerActive[kk] ) { t1 = kk+1; break; }
                matches[jj][ii].SetMatchup(t1, NPLAYERS);
            }
            --t2;
        }
    }

    // Print out results, 1 round per row. Each round alternate first/second team as home.
    bool reverse = false;
    for ( int ii = 0; ii < nRounds; ii++ )
    {
        for ( int jj = 0; jj < gpr; jj++ )
        {
            if ( reverse )  std::cout << "  (" << matches[ii][jj].m_team2 << " vs. " << matches[ii][jj].m_team1 << ")";
            else std::cout << "  (" << matches[ii][jj].m_team1 << " vs. " << matches[ii][jj].m_team2 << ")";
        }
        std::cout << std::endl;
        reverse = !reverse;
    }
}
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
Forgot to ask, got a C++ compiler?
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
rsriprac ,

What is your definition of a round?  I coded up your algorithm, and each round has every team playing three times for a 6-team pool.  I would assume that a round would be each team playing once (except with an odd number of teams where there is an odd-man out) and that at the conclusion of all rounds, each team has played every other team exactly once.

You are also generating only three out of a 5 possible ways to pair 6 teams (it requires 5 rounds of three games for all teams to play each other once).  Each of your rounds as you define them has the same 9 matchups.  It seems that by rotating the whole array of teams, you miss games.  Because you fold the rotated array, the teams slide 2 slots each time - one top shift and one bottom shift.  Since there are an even number of teams, you end up back where you started after three rotations and you have missed some matchups.

Am I missing something here?
0
 

Author Comment

by:mSchmidt
Comment Utility
Well first of all iam using Visual Basic, not THAT big a deal because i can simply translate it,

BUT one round is 5 matches for each team (in a 6 team pool) meaning that what i need calculated is 15 matches which can be put in to three rounds, which all can be playd at the same time meaning one round cannot have one team twice. Yet another thing is that each team needs to play equally many home and away games ( as far as this is possible may differ one game) This also has to be true when only 1 round is played, meaning each team only plays versus the other teams ones.

Here is an example not taking in to count the amount of home and away games

 round 1      round 2      round 3      round 4          round 5
T1 vs T2     T1 vs T5    T1 vs T6      T1 vs T4       T1 vs T3
T3 vs T4     T2 vs T3    T2 vs T4      T2 vs T5       T2 vs T6
T5 vs T6     T4 vs T6    T3 vs T5      T3 vs T6       T4 vs T5

That might have been a good solution if not T1 had playd 5 Home matches and T6 5 away matches.... meaning this solution does not work !
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
I think  you left out "j" for loop is missing the j++ rather then i++, cause it should do more loops then 3 per round. The j loop should do 3 and the inner should do another 3, so it should be ~ 9 matches per round.  

-Ram
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
What you said  - "15 matches which can be put in to three rounds" -  and what you drew - "5 rounds of three matches" - are not consistent.  What you drew is what my program will calculate, with correct pairings such that no teams play each other twice in the 15 matches.  It will print out the rounds in rowa rather than columns, however.  Home and away games are also taken into account.  If you need a VB version to try, I will unfortunately be on vacation for the next few days.

Here's the output for 6 teams.  Each row corresponds to a round in your picture above.  Each team plays every other team once and is home for 2 or 3 of the 5 games.  With an odd number of teams each is home team exactly half the time.
--------------------------------------------------------------
D:\DevProjects\CPPConsole\Debug>cppconsole 6
  (6 vs. 1)  (5 vs. 2)  (4 vs. 3)
  (1 vs. 5)  (2 vs. 4)  (6 vs. 3)
  (4 vs. 1)  (3 vs. 2)  (5 vs. 6)
  (1 vs. 3)  (5 vs. 4)  (6 vs. 2)
  (2 vs. 1)  (3 vs. 5)  (4 vs. 6)

D:\DevProjects\CPPConsole\Debug>
0
 
LVL 5

Expert Comment

by:rsriprac
Comment Utility
I just noice that there are a few more issues.  Nevermind,  I'll actually try the code before revision. heh. sorry bout that.

-Ram
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
>> The j loop should do 3 and the inner should do another 3, so it should be ~ 9 matches per round.  

No, for 6 teams there should be 3 matches per "mini" round (each team plays once) and 15 games per "big" round (each team has played every other team once).
0
 

Author Comment

by:mSchmidt
Comment Utility
So drichards your code will work and take away and home teams into account ?
and work with both 4 6 8 and 10 teams... right ?

Then i will just translate it my self
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
Yes, works with all number of teams up to 64 (limit of the hardcoded array in there), including odd number of teams.  I tested 1 to 12 teams and assume it works from there.
0
 

Author Comment

by:mSchmidt
Comment Utility
The setMatchup and push_back methods what do those do...
I need to translate it :) ...
0
 

Author Comment

by:mSchmidt
Comment Utility
Oki well push_back is simply adding an element at the end

but the setMatchup.. you created some class which you havent pasted here ?
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
Sorry about that.  Just a simple struct with a setter method.

struct Matchup
{
    Matchup() : m_team1(0), m_team2(0) {}
    Matchup(int t1, int t2) : m_team1(t1), m_team2(t2) {}
    void SetMatchup(int t1, int t2) { m_team1 = t1; m_team2 = t2; }

    int m_team1;
    int m_team2;
};
0
 

Author Comment

by:mSchmidt
Comment Utility
can i create anything like that structure in VB ???

i was thinking of using collection instead of the array...
and as i see it your "matches"... is a double vector ? one vector with a vector of matches within it.. right  ?
havent programmed C++ that much :)
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
I'm not a VB person at all, but this code seems to work.  You just have to get it printed to the screen somehow.  I turned the array of structs into an array or arrays of arrays.  Ouch.  There's probably a slick way to do it, but like I said, I am not a VB guy.

Private Sub Command1_Click()
    Dim NPLAYERS As Integer
    NPLAYERS = CInt(Text1.Text)
   
    ' Total games for all teams to play each other once
    Dim numGames As Integer
    numGames = NPLAYERS * NPLAYERS / 2 - NPLAYERS / 2
    ' Total games per round
    Dim gpr As Integer
    gpr = NPLAYERS / 2
    ' Number of rounds
    Dim nRounds As Integer
    nRounds = numGames / gpr
    ' If odd number of players, we've got an odd man out each round
    Dim oddPlayer As Integer
    oddPlayer = nRounds - NPLAYERS + 1

    ' Allocate data structure
    Dim matches(12) As Variant
    Dim round(6) As Variant
    For ii = 0 To nRounds
        matches(ii) = round
    Next

    For ii = 0 To gpr - 1
        Dim t1 As Integer
        t1 = ii + 1
        Dim t2 As Integer
        t2 = NPLAYERS - ii
        For jj = 0 To nRounds - 1
            ' For all rows in odd player scenarios and all but
            ' last game of rounds 2 -> n of even player scenarios...
            If (ii + 1 < gpr Or Not oddPlayer = 0 Or jj < 1) Then
                ' If t2 == t1, switch to "bottom-half" logic
                If (t2 = t1) Then
                    t2 = gpr + ii + oddPlayer
                    t1 = t2 + 1
                End If
                matches(jj)(ii) = Array(t2, t1)
            Else
                Dim playerActive(64) As Boolean
                For kk = 0 To NPLAYERS - 1
                    playerActive(kk) = False
                Next
                For kk = 0 To gpr - 1
                    If Not IsEmpty(matches(jj)(kk)) Then
                        playerActive(matches(jj)(kk)(0) - 1) = True
                        playerActive(matches(jj)(kk)(1) - 1) = True
                    End If
                Next
                For kk = 0 To NPLAYERS - 1
                    If (Not playerActive(kk)) Then
                        t1 = kk + 1
                        Exit For
                    End If
                Next
                       
                matches(jj)(ii) = Array(t1, NPLAYERS)
            End If
            t2 = t2 - 1
        Next
    Next

    ' Print out results, 1 round per row...
    Dim reverse As Boolean
    reverse = False
    For ii = 0 To nRounds - 1
        For jj = 0 To gpr - 1
            If (reverse) Then
                Print "  (" & matches(ii)(jj)(1) & " vs. " & matches(ii)(jj)(0) & ")"
            Else
                Print "  (" & matches(ii)(jj)(0) & " vs. " & matches(ii)(jj)(1) & ")"
            End If
        Next
        Print vbCrLf
        reverse = Not reverse
    Next
End Sub
0
 
LVL 19

Expert Comment

by:drichards
Comment Utility
FYI, that routine reads the number of teams fro a TextBox input in case it isn't clear.
0
 

Author Comment

by:mSchmidt
Comment Utility
Great !!! i believe this one is very close, but damn something is wrong... (btw thanks for the rough translation helped me alot)

This is a running VB.NET code the thing is it results in
  (2 vs. 1)  (3 vs. 4)
  (1 vs. 2)  (4 vs. 3)
  (2 vs. 1)  (3 vs. 4)
which is not true... can you see whats wrong ?

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim NPLAYERS As Integer
        NPLAYERS = CInt(Text1.Text)
        Dim jj As Integer
        Dim kk As Integer
        Dim ii As Integer

        ' Total games for all teams to play each other once
        Dim numGames As Integer
        numGames = NPLAYERS * NPLAYERS / 2 - NPLAYERS / 2
        ' Total games per round
        Dim gpr As Integer
        gpr = NPLAYERS / 2
        ' Number of rounds
        Dim nRounds As Integer
        nRounds = numGames / gpr
        ' If odd number of players, we've got an odd man out each round
        Dim oddPlayer As Integer
        oddPlayer = nRounds - NPLAYERS + 1

        ' Allocate data structure
        Dim matches(12) As Object
        Dim round(6) As Object
        For ii = 0 To nRounds
            matches(ii) = round
        Next

        For ii = 0 To gpr - 1
            Dim t1 As Integer
            t1 = ii + 1
            Dim t2 As Integer
            t2 = NPLAYERS - ii
            For jj = 0 To nRounds - 1
                ' For all rows in odd player scenarios and all but
                ' last game of rounds 2 -> n of even player scenarios...
                If (ii + 1 < gpr Or Not oddPlayer = 0 Or jj < 1) Then
                    ' If t2 == t1, switch to "bottom-half" logic
                    If (t2 = t1) Then
                        t2 = gpr + ii + oddPlayer
                        t1 = t2 + 1
                    End If
                    matches(jj)(ii) = New Integer(1) {t2, t1}
                Else
                    Dim playerActive(64) As Boolean
                    For kk = 0 To NPLAYERS - 1
                        playerActive(kk) = False
                    Next
                    For kk = 0 To gpr - 1
                        Console.WriteLine(matches(jj)(kk))
                        If Not (matches(jj)(kk)) Is Nothing Then
                            playerActive(matches(jj)(kk)(0) - 1) = True
                            playerActive(matches(jj)(kk)(1) - 1) = True
                        End If
                    Next
                    For kk = 0 To NPLAYERS - 1
                        If (Not playerActive(kk)) Then
                            t1 = kk + 1
                            Exit For
                        End If
                    Next

                    matches(jj)(ii) = New Integer(1) {t1, NPLAYERS}
                End If
                t2 = t2 - 1
            Next
        Next

        ' Print out results, 1 round per row...
        Dim reverse As Boolean
        reverse = False
        For ii = 0 To nRounds - 1
            For jj = 0 To gpr - 1
                If (reverse) Then
                    Console.Write("  (" & matches(ii)(jj)(1) & " vs. " & matches(ii)(jj)(0) & ")")
                Else
                    Console.Write("  (" & matches(ii)(jj)(0) & " vs. " & matches(ii)(jj)(1) & ")")
                End If
            Next
            Console.Write(vbCrLf)
            reverse = Not reverse
        Next
    End Sub
0
 

Author Comment

by:mSchmidt
Comment Utility
I figured it out it was simply because each matches()() would point to the same round object this is the final code

I want to thanks everyone who helped me out on this one, never would have made it without you guys... thanks alot, and drichards have a nice vacation...

Posting the final VB code as resource... thanks

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim NPLAYERS As Integer
        NPLAYERS = CInt(Text1.Text)
        Dim jj As Integer
        Dim kk As Integer
        Dim ii As Integer

        ' Total games for all teams to play each other once
        Dim numGames As Integer
        numGames = NPLAYERS * NPLAYERS / 2 - NPLAYERS / 2
        ' Total games per round
        Dim gpr As Integer
        gpr = NPLAYERS / 2
        ' Number of rounds
        Dim nRounds As Integer
        nRounds = numGames / gpr
        ' If odd number of players, we've got an odd man out each round
        Dim oddPlayer As Integer
        oddPlayer = nRounds - NPLAYERS + 1

        ' Allocate data structure
        Dim matches(12) As Object
        Dim round(6) As Object
        For ii = 0 To nRounds
            matches(ii) = New Object() {Nothing, Nothing, Nothing, Nothing, Nothing, Nothing}
        Next

        For ii = 0 To gpr - 1
            Dim t1 As Integer
            t1 = ii + 1
            Dim t2 As Integer
            t2 = NPLAYERS - ii
            Console.WriteLine("NExt")
            For jj = 0 To nRounds - 1
                ' For all rows in odd player scenarios and all but
                ' last game of rounds 2 -> n of even player scenarios...
                If (ii + 1 < gpr Or Not oddPlayer = 0 Or jj < 1) Then
                    ' If t2 == t1, switch to "bottom-half" logic
                    If (t2 = t1) Then
                        t2 = gpr + ii + oddPlayer
                        t1 = t2 + 1
                    End If
                    matches(jj)(ii) = New Integer() {t2, t1}
                Else
                    Dim playerActive(64) As Boolean
                    For kk = 0 To gpr - 1
                        If Not (matches(jj)(kk) Is Nothing) Then
                            playerActive(matches(jj)(kk)(0) - 1) = True
                            playerActive(matches(jj)(kk)(1) - 1) = True
                        End If
                    Next
                    For kk = 0 To NPLAYERS - 1
                        If (Not playerActive(kk)) Then
                            t1 = kk + 1
                            Exit For
                        End If
                    Next
                    matches(jj)(ii) = New Integer() {t1, NPLAYERS}
                End If
                t2 = t2 - 1
            Next
        Next

        ' Print out results, 1 round per row...
        Dim reverse As Boolean
        For ii = 0 To nRounds - 1
            For jj = 0 To gpr - 1
                If (reverse) Then
                    Console.Write("  (" & matches(ii)(jj)(1) & " vs. " & matches(ii)(jj)(0) & ")")
                Else
                    Console.Write("  (" & matches(ii)(jj)(0) & " vs. " & matches(ii)(jj)(1) & ")")
                End If
            Next
            Console.Write(vbCrLf)
            reverse = Not reverse
        Next
    End Sub
0
 
LVL 3

Expert Comment

by:str_ek
Comment Utility
mSchmidt sorry to mess it up...

just listen to drichards ... he's tha man
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
scoresIncreasing challenge 10 57
countAbc challenge 9 49
word0 challenge 3 55
delphi parse string to params 3 79
Here we come across an interesting topic of coding guidelines while designing automation test scripts. The scope of this article will not be limited to QTP but to an overall extent of using VB Scripting for automation projects. Introduction Now…
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now