Search code examples
pythonpython-3.xfunctionwhile-looptournament

tournament winner python while loop


I made a function 'Match' which takes two country and return a winner according to my algorithm.
EX)

def Match(England, Brazil) ----> England, 
def Match(Mexico, France) ---> France  

I need to write function Winner which takes list of 2^n nations and run a tournament and find a winner.
EX)

def Winner([England, Brazil, Mexico, France]) ---> France 

England---Brazil,        Mexico---France  (Semifinal)

England---France (final)

France (winner) Return value

The length of nation list differs and I cannot make a winner choosing algorithm. The match-up is It would be great if the code uses while loop rather than for loop ^^.


Solution

  • Your tournament method should make matches between consecutive pairs of players, for ["a", "b", "c", "d", "e", "f", "g", "h"] it should be a/b, c/d, e/f and g/h

    You can achieve these with slicing and zip

    • countries[::2] takes 1 on 2 so ["a", "c", "e", "g"]

    • countries[1::2] same but starting at 1 so ["b", "d", "f", "h"]

    • zip pairs these 2 lists to create pairs of opponents

    Keep the winner of each match, and call tournament recursivly with the next round of players which contains half of players

    # FOR DEMO PURPOSER
    def match(country_a, country_b):
        return random.choice([country_a, country_b])
    
    def tournament(countries):
        n = len(countries)
        if not ((n & (n - 1) == 0) and n != 0):
            raise Exception("Size isn't power of 2")
    
        if n == 2:
            return match(*countries)
    
        next_round = []
        for player1, player2 in zip(countries[::2], countries[1::2]):
            winner = match(player1, player2)
            next_round.append(winner)
    
        return tournament(next_round)
    

    Using list-comprehension the for-loop and return can be replaced with

    return tournament([match(p1, p2) for p1, p2 in zip(countries[::2], countries[1::2])])
    

    Improvement full code

    After some time and discussion with the OP here's a major improvement of the full code with the major rules :

    • don't call the exact same method in a loop, do it outside
    • don't call a method again and again if it does the same, store the data somewhere