Solved

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

Posted on 2004-09-01
271 Views
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
Question by:mSchmidt
• 15
• 15
• 9
• +2

LVL 45

Expert Comment

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

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

And sorry i also have to make sure that each team has equally many Home and Away games
0

LVL 5

Expert Comment

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

O nevermind, its not quite right I found out.

-Ram
0

LVL 3

Expert Comment

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

rsriprac earned 100 total points
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

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

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

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

//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

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

Opps, damn too many mistakes, yes its:

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

0

LVL 5

Expert Comment

I feel like i'm spamming up the place with my code. hehe.

-Ram
0

Author Comment

What if they are only going to play one round ?
0

Author Comment

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 ?
0

Author Comment

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

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

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

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

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

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

LVL 3

Expert Comment

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

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

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

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

drichards earned 400 total points
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

Forgot to ask, got a C++ compiler?
0

LVL 19

Expert Comment

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

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

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

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

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

>> 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

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

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

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

Author Comment

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

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

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

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

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

Author Comment

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

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

mSchmidt sorry to mess it up...

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

Featured Post

Suggested Solutions

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 â€¦