• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Round-Robin Tournament - Pairs Generator

  • Like
Reactions: Jaccouille
A round-robin tournament is a non-eliminating tournament where each player plays each player exactly once and the winner is the one with most... wins. The number of rounds is always (number of playing players - 1). The pairs must be generated before the game starts because they remain fixed throughout the tournament. This function will take into consideration only the currently playing players, not all players.
So for 12 playing players you get 66 unique pairs in 11 rounds and for 24 playing players you get 276 unique pairs in 23 rounds.
If the number of players is odd, there will be added one player 0 - dummy. If a player is paired with a dummy he gets a free win.
You can select if computer players will be included in the pairing process. And bunch of other settings.
It is based on the Circle method where for each cycle the elements in the array are shifted clockwise or counter-clockwise and one element always remains fixed in place.
274121-d48f7ff53d9d94b57f5372216ba325d9.gif


This is useful for arena/tournament maps with FFA



The pairs are stored in hashtable and you retrieve a pair from it with:
  • Set RRG_CurrentRound = 1
  • Set RRG_Player1 = 1
  • Set RRG_Player2 = (Load RRG_Player1 of RRG_CurrentRound from RRG_Tournament)
This gets the opponent of player 1 in round 1
TargetPlayer + CurrentRound = TargetPlayer's opponent in that round

When retrieving the opponent of a players don't forget to check if he has left the game or his index is 0. 0 means that there is no player and it's a free win. If you try to retrieve Player(0) with a trigger it will crash the map.

How to test/debug?

- in the folder "example" you will find the same trigger for generating pairs but with debug messages. Go to the trigger RRG call, disable calling the non-debug trigger for pairing and enable the one with debug messages.

How to install?
- Enable in the editor's preferences "Automatically create unknown variables whil pasting trigger data"
- copy-paste the folder "Round robin" in your map
- Change the way you call the pairing of the players however it suits your map

Triggers and code:

  • RRG Initialize
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set RRG_Tournament = (Last created hashtable)


  • RRG Call
    • Events
      • Player - Player 1 (Red) skips a cinematic sequence
    • Conditions
    • Actions
      • -------- ---------------------------- --------
      • -------- You can change those parameters to randomize the pairs as much as possible --------
      • -------- ---------------------------- --------
      • Set RRG_IncludeComputers = True
      • -------- ---------------------------- --------
      • Set RRG_Clockwise = True
      • -------- ---------------------------- --------
      • Set RRG_InitialShift_Times = 0
      • Set RRG_InitialShift_Clockwise = False
      • -------- ---------------------------- --------
      • Trigger - Run RRG Generate Pairs <gen> (ignoring conditions)

You can delete that "skips a cinematic sequence" and call the pairing however you like.
What is initialshift? It is if and how much the players are rotated before you start pairing them. This gives a sense of randomization.

  • RRG Collect players
    • Events
    • Conditions
    • Actions
      • Player Group - Remove all players from RRG_PlayingPlayers
      • Set RRG_EndIndex = 0
      • -------- collect players in the array --------
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RRG_IncludeComputers Equal to True
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • And - All (Conditions) are true
                    • Conditions
                      • Or - Any (Conditions) are true
                        • Conditions
                          • ((Picked player) controller) Equal to User
                          • ((Picked player) controller) Equal to Computer
                      • ((Picked player) controller) Not equal to None
                      • ((Picked player) slot status) Equal to Is playing
                • Then - Actions
                  • Player Group - Add (Picked player) to RRG_PlayingPlayers
                  • Set RRG_EndIndex = (RRG_EndIndex + 1)
                  • Set RRG_PlayersArray[RRG_EndIndex] = (Player number of (Picked player))
                • Else - Actions
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked player) controller) Equal to User
                  • ((Picked player) controller) Not equal to Computer
                  • ((Picked player) controller) Not equal to None
                  • ((Picked player) slot status) Equal to Is playing
                • Then - Actions
                  • Player Group - Add (Picked player) to RRG_PlayingPlayers
                  • Set RRG_EndIndex = (RRG_EndIndex + 1)
                  • Set RRG_PlayersArray[RRG_EndIndex] = (Player number of (Picked player))
                • Else - Actions


  • RRG Generate Pairs
    • Events
    • Conditions
    • Actions
      • Trigger - Run RRG Collect players <gen> (ignoring conditions)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Real((Number of players in RRG_PlayingPlayers))) mod 2.00) Equal to 0.00
        • Then - Actions
          • Set RRG_StartIndex = 1
          • Set RRG_Difference = 0
        • Else - Actions
          • Set RRG_StartIndex = 0
          • Set RRG_Difference = 1
          • Player Group - Add Neutral Passive to RRG_PlayingPlayers
      • Set RRG_PairsPer_Round = ((Number of players in RRG_PlayingPlayers) / 2)
      • Set RRG_MaxRounds = ((Number of players in RRG_PlayingPlayers) - 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • RRG_InitialShift_Times Greater than 0
        • Then - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RRG_InitialShift_Clockwise Equal to True
            • Then - Actions
              • For each (Integer A) from 1 to RRG_InitialShift_Times, do (Actions)
                • Loop - Actions
                  • Trigger - Run RRG Shift Right Except First <gen> (checking conditions)
            • Else - Actions
              • For each (Integer A) from 1 to RRG_InitialShift_Times, do (Actions)
                • Loop - Actions
                  • Trigger - Run RRG Shift Left Except First <gen> (checking conditions)
        • Else - Actions
      • -------- ---------------------------- --------
      • Trigger - Run RRG Reverse Second Half <gen> (checking conditions)
      • For each (Integer A) from 1 to RRG_MaxRounds, do (Actions)
        • Loop - Actions
          • For each (Integer B) from RRG_StartIndex to (RRG_PairsPer_Round - RRG_Difference), do (Actions)
            • Loop - Actions
              • Set RRG_Player1 = (Integer B)
              • Set RRG_Player2 = (RRG_Player1 + RRG_PairsPer_Round)
              • Hashtable - Save RRG_PlayersArray[RRG_Player2] as RRG_PlayersArray[RRG_Player1] of (Integer A) in RRG_Tournament
              • Hashtable - Save RRG_PlayersArray[RRG_Player1] as RRG_PlayersArray[RRG_Player2] of (Integer A) in RRG_Tournament
          • Trigger - Run RRG Reverse Second Half <gen> (checking conditions)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • RRG_Clockwise Equal to True
            • Then - Actions
              • Trigger - Run RRG Shift Right Except First <gen> (checking conditions)
            • Else - Actions
              • Trigger - Run RRG Shift Left Except First <gen> (checking conditions)
          • Trigger - Run RRG Reverse Second Half <gen> (checking conditions)
          • -------- ---------------------------- --------
          • -------- ---------------------------- --------


  • RRG Shift Right Except First
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of players in RRG_PlayingPlayers) Less than 3
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • Set RRG_StartShiftIndex = (RRG_StartIndex + 1)
      • Set LastElement = RRG_PlayersArray[RRG_EndIndex]
      • Set i = RRG_EndIndex
      • Custom script: loop
      • Set RRG_PlayersArray[i] = RRG_PlayersArray[(i - 1)]
      • Set i = (i - 1)
      • Custom script: exitwhen udg_i == udg_RRG_StartShiftIndex
      • Custom script: endloop
      • Set RRG_PlayersArray[RRG_StartShiftIndex] = LastElement


  • RRG Shift Left Except First
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of players in RRG_PlayingPlayers) Less than 3
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • Set RRG_StartShiftIndex = (RRG_StartIndex + 1)
      • Set RRG_FirstElement = RRG_PlayersArray[RRG_StartShiftIndex]
      • Set i = RRG_StartShiftIndex
      • Custom script: loop
      • Set RRG_PlayersArray[i] = RRG_PlayersArray[(i + 1)]
      • Set i = (i + 1)
      • Custom script: exitwhen udg_i == udg_RRG_EndIndex
      • Custom script: endloop
      • Set RRG_PlayersArray[RRG_EndIndex] = RRG_FirstElement


  • RRG Reverse Second Half
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of players in RRG_PlayingPlayers) Less than 2
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • Set RRG_Left = ((Number of players in RRG_PlayingPlayers) / 2)
      • Set RRG_Left = (RRG_Left + 1)
      • Set RRG_Right = (Number of players in RRG_PlayingPlayers)
      • Custom script: loop
      • Set RRG_TempValue = RRG_PlayersArray[RRG_Left]
      • Set RRG_PlayersArray[RRG_Left] = RRG_PlayersArray[RRG_Right]
      • Set RRG_PlayersArray[RRG_Right] = RRG_TempValue
      • Set RRG_Left = (RRG_Left + 1)
      • Set RRG_Right = (RRG_Right - 1)
      • Custom script: exitwhen udg_RRG_Left >= udg_RRG_Right
      • Custom script: endloop


update 07/0124:
- reset also EndIndex in collect players


Give credits if used in your map
Previews
Contents

Round Robin Generator by stan0033 (Map)

Reviews
Wrda
Collect Players And - All (Conditions) are true Conditions Or - Any (Conditions) are true Conditions ((Picked player) controller) Equal to User ((Picked player) controller) Equal to Computer...

Wrda

Spell Reviewer
Level 26
Joined
Nov 18, 2012
Messages
1,888
Collect Players
  • And - All (Conditions) are true
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • ((Picked player) controller) Equal to User
          • ((Picked player) controller) Equal to Computer
      • ((Picked player) controller) Not equal to None
      • ((Picked player) slot status) Equal to Is playing
Controller equal to none is redundant since you're already checking if it's user or computer.

  • If - Conditions
    • ((Picked player) controller) Equal to User
    • ((Picked player) controller) Not equal to Computer
    • ((Picked player) controller) Not equal to None
    • ((Picked player) slot status) Equal to Is playing
Checking if it is a user already eliminates the other controllers.
You should use your own integer loop variables instead of Integer A and B, it's less susceptible to unexpected bugs.

Useful for tournament and minigame type of maps.

Approved
 
Top