Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Elo for ping pong
ELO_DEFAULT = 1500
ELO_K_FACTOR = 16
def expected(Ra, Rb):
# https://en.wikipedia.org/wiki/Elo_rating_system
Ea = (1.0 / (1.0 + pow(10.0, (Rb-Ra)/400.0)))
return Ea, 1-Ea
@bot.add_command('!challenge')
@gen.coroutine
def challenge(message):
"""Creates an interactive prompt, and keeps track of scores.
This function uses the Elo method of keeping track of ranks.
Every participant starts with 1500 and the "k" factor of 16"""
Ua = bot._get_user(message.user)
ratings = yield bot.memory.get('pong-elo-ratings', {})
Ra = ratings.get(Ua.id)
if Ra is None:
Ra = yield bot.memory.get('%s-rating' % Ua.id, ELO_DEFAULT)
action = yield message.button_prompt(
'Who <!here> would like to challenge {}? Rating: {}'.format(Ua.first_name, int(Ra)),
['Take on the challenge']
)
event = action._meta['event']
accepting_user_id = event.get('user', {}).get('id')
Ub = bot._get_user(accepting_user_id)
Rb = ratings.get(Ub.id)
if Rb is None:
Rb = yield bot.memory.get('%s-rating' % Ub.id, ELO_DEFAULT)
yield message.reply('{} ({}) takes on the challenge!'.format(Ub.first_name, int(Rb)))
yield message.reply('{} vs. {}'.format(Ua.first_name, Ub.first_name))
winner = yield message.button_prompt(
'Who won?', [
'{}'.format(Ua.first_name),
'{}'.format(Ub.first_name),
'Draw',
'Cancel']
)
if winner == 'Cancel':
yield message.reply('Too bad ... :(')
raise gen.Return()
if winner == 'Draw':
Sa, Sb = 0.5, 0.5
elif winner == Ua.first_name:
Sa, Sb = 1, 0
elif winner == Ub.first_name:
Sa, Sb = 0, 1
else:
yield message.reply(('Got some strange button value "{}"...'
'ignoring this game').format(winner))
raise gen.Return()
Ea, Eb = expected(Ra, Rb)
Ra = Ra + ELO_K_FACTOR * (Sa - Ea)
Rb = Rb + ELO_K_FACTOR * (Sb - Eb)
ratings[Ua.id] = Ra
ratings[Ub.id] = Rb
yield bot.memory.save('pong-elo-ratings', ratings)
yield message.reply('New Ratings:')
yield message.reply('{}: {}'.format(Ua.first_name, int(Ra)))
yield message.reply('{}: {}'.format(Ub.first_name, int(Rb)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment