Fix ratings and print rating changes in the lobby.

Fix game listings.
Fix non-hosts unregistering games.
Patch by scythetwirler.

This was SVN commit r14228.
This commit is contained in:
leper
2013-11-25 02:55:47 +00:00
parent d6a9489ccb
commit c3ebb50711
3 changed files with 45 additions and 15 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ def get_rating_adjustment(rating, opponent_rating, games_played, opponent_games_
rating_k_factor = 0.75 * pow(elo_k_factor_constant_rating / min(elo_k_factor_constant_rating, (rating + opponent_rating) / 2), 0.5)
player_volatility = min(pow(1.1, games_played + 16), 25)
volatility = opponent_volatility_influence * player_volatility / rating_k_factor
difference = rating - opponent_rating
difference = opponent_rating - rating
if result == 1:
return round(max(0, (difference + result * elo_sure_win_difference) / volatility))
elif result == -1:
+1 -1
View File
@@ -57,7 +57,7 @@ You need to have python 3 installed
$ sudo apt-get install python3
You also need the SleekXmpp Python library
Go to to github and follow their instructions
Go to github and follow their instructions
https://github.com/fritzy/SleekXMPP
If you would like to run the leaderboard database,
+43 -13
View File
@@ -34,7 +34,7 @@ from config import default_rating, leaderboard_minimum_games, leaderboard_active
class LeaderboardList():
def __init__(self, room):
self.room = room
self.lastRated = ""
def getOrCreatePlayer(self, JID):
"""
Stores a player(JID) in the database if they don't yet exist.
@@ -122,13 +122,33 @@ class LeaderboardList():
# the database model, and therefore this code, requires a winner.
# The Elo implementation does not, however.
result = 1 if player1 == game.winner else -1
rating_adjustment = get_rating_adjustment(player1.rating, player2.rating,
rating_adjustment1 = get_rating_adjustment(player1.rating, player2.rating,
len(player1.games), len(player2.games), result)
player1.rating += rating_adjustment
player2.rating -= rating_adjustment
rating_adjustment2 = get_rating_adjustment(player2.rating, player1.rating,
len(player2.games), len(player1.games), result * -1)
if result == 1:
resultQualitative = "won"
elif result == 0:
resultQualitative = "drew"
else:
resultQualitative = "lost"
name1 = '@'.join(player1.jid.split('@')[:-1])
name2 = '@'.join(player2.jid.split('@')[:-1])
self.lastRated = "A rated game has ended. %s %s against %s. Rating Adjustment: %s (%s -> %s) and %s (%s -> %s)."%(name1,
resultQualitative, name2, name1, player1.rating, player1.rating + rating_adjustment1,
name2, player2.rating, player2.rating + rating_adjustment2)
player1.rating += rating_adjustment1
player2.rating += rating_adjustment2
db.commit()
return self
def getLastRatedMessage(self):
"""
Gets the string of the last rated game. Triggers an update
chat for the bot.
"""
return self.lastRated
def addAndRateGame(self, gamereport):
"""
Calls addGame and if the game has only two
@@ -138,6 +158,8 @@ class LeaderboardList():
game = self.addGame(gamereport)
if game and len(game.players) == 2:
self.rateGame(game)
else:
self.lastRated = ""
return game
def getBoard(self):
@@ -269,6 +291,7 @@ class ReportManager():
length -= 1
else:
i += 1
self.leaderboard.lastRated = ""
def getNumPlayers(self, rawGameReport):
"""
@@ -405,7 +428,10 @@ class XpartaMuPP(sleekxmpp.ClientXMPP):
# Send Gamelist to new player
self.sendGameList(presence['muc']['jid'])
# Store player JID mapped to their nick
self.nicks[str(presence['muc']['jid'])] = presence['muc']['nick']
if presence['muc']['nick'] not in self.nicks:
self.nicks[str(presence['muc']['jid'])] = presence['muc']['nick']
if presence['muc']['jid'] not in self.JIDs:
self.JIDs.append(presence['muc']['jid'])
logging.debug("Client '%s' connected with a nick of '%s'." %(presence['muc']['jid'], presence['muc']['nick']))
def muc_offline(self, presence):
@@ -415,11 +441,12 @@ class XpartaMuPP(sleekxmpp.ClientXMPP):
# Clean up after a player leaves
if presence['muc']['nick'] != self.nick:
for JID in self.gameList.getAllGames():
if self.gameList.getAllGames()[JID]['players'].split(',')[0] == presence['muc']['nick']:
if JID == str(presence['muc']['jid']):
self.gameList.removeGame(JID)
self.sendGameList()
break
self.lastLeft = str(presence['muc']['jid'])
self.JIDs.remove(presence['muc']['jid'])
del self.nicks[str(presence['muc']['jid'])]
def iqhandler(self, iq):
@@ -450,15 +477,15 @@ class XpartaMuPP(sleekxmpp.ClientXMPP):
"""
pass
elif iq['type'] == 'set':
if 'gamelist' in iq.values:
if 'gamelist|en' in iq.values:
"""
Register-update / unregister a game
"""
command = iq['gamelist']['command']
command = iq['gamelist|en']['command']
if command == 'register':
# Add game
try:
self.gameList.addGame(iq['from'], iq['gamelist']['game'])
self.gameList.addGame(iq['from'], iq['gamelist|en']['game'])
self.sendGameList()
except:
traceback.print_exc()
@@ -475,19 +502,22 @@ class XpartaMuPP(sleekxmpp.ClientXMPP):
elif command == 'changestate':
# Change game status (waiting/running)
try:
self.gameList.changeGameState(iq['from'], iq['gamelist']['game'])
self.gameList.changeGameState(iq['from'], iq['gamelist|en']['game'])
self.sendGameList()
except:
traceback.print_exc()
logging.error("Failed to process changestate data")
else:
logging.error("Failed to process command '%s' received from %s" % command, iq['from'].bare)
elif 'gamereport' in iq.values:
elif 'gamereport|en' in iq.values:
"""
Client is reporting end of game statistics
"""
try:
self.reportManager.addReport(iq['from'], iq['gamereport']['game'])
self.reportManager.addReport(iq['from'], iq['gamereport|en']['game'])
if self.leaderboard.getLastRatedMessage() != "":
self.send_message(mto=self.room, mbody=self.leaderboard.getLastRatedMessage(), mtype="groupchat",
mnick=self.nick)
self.sendBoardList()
except:
traceback.print_exc()