If your question is how to represent strengths based on rankings so that the probability that a player wins is based on his rank, you can represent strength as a range tuple (e.g. (3, 9)).
One rule to assign these ranges to players can be:
- sort players by rank
- create
p ranges from 0 to sum of all ranks (where p is the total number of players) so that ranges are created based on a player's rank number
- assign ranges to players in reverse order so that a player with a higher rank (lower rank number) gets a higher range tuple
Here's an implementation:
players = [['Tony', 3], ['Mike', 6], ['John', 9], ['Will', 7]]
players.sort(key=lambda x: x[1])
# create strength ranges
strengths = []
i = 0
for p in players:
strengths.append((i, i + p[1]))
i += p[1]
# assign strengths in reverse order
for p in players:
p.append(strengths.pop())
print(players)
# [['Tony', 3, (16, 25)], ['Mike', 6, (9, 16)], ['Will', 7, (3, 9)], ['John', 9, (0, 3)]]
Now suppose we play a random dice game with random.randint, we can see how these ranges determine winners:
import random
from collections import Counter
sum_ranks = sum(p[1] for p in players)
winners = []
for game in range(100):
dice_roll = random.randint(0, sum_ranks - 1)
winning_player = [p for p in players if dice_roll >= p[2][0] and dice_roll < p[2][1]][0]
winners.append(winning_player[0])
print(Counter(winners))
# Counter({'Tony': 39, 'Mike': 35, 'Will': 14, 'John': 12})
For several more experiments, we see the following results (the number in the counter object represents how many games that player won):
Counter({'Tony': 32, 'Mike': 29, 'Will': 27, 'John': 12})
Counter({'Tony': 33, 'Will': 29, 'Mike': 28, 'John': 10})
Counter({'Tony': 45, 'Mike': 28, 'Will': 16, 'John': 11})
Counter({'Tony': 34, 'Will': 28, 'Mike': 27, 'John': 11})
Counter({'Tony': 39, 'Mike': 35, 'Will': 20, 'John': 6})