Ticket #2516: 2v2.diff

File 2v2.diff, 9.7 KB (added by Jia Henry, 9 years ago)

Hi again everyone. I've managed to find some more time to do some work on this patch. This the progress so far. IT doesn't work yet. When I test it , it gives me the following error (see comment below)

  • XpartaMuPP.py

     
    158158    return game
    159159 
    160160  def verifyGame(self, gamereport):
     161    print("VERIFYING")
    161162    """
    162163      Returns a boolean based on whether the game should be rated.
    163164      Here, we can specify the criteria for rated games.
    164165    """
     166    # First check how many people have won. Teams may be balanced but if everyone
     167    # allies in the game then don't rate it
    165168    winning_jids = list(dict.keys({jid: state for jid, state in
    166169                                  gamereport['playerStates'].items()
    167170                                  if state == 'won'}))
    168     # We only support 1v1s right now. TODO: Support team games.
    169171    if len(winning_jids) * 2 > len(dict.keys(gamereport['playerStates'])):
    170172      # More than half the people have won. This is not a balanced team game or duel.
     173      print(gamereport)
     174      print(winning_jids)
    171175      return False
    172     if len(dict.keys(gamereport['playerStates'])) != 2:
     176
     177    # Check that teams are balanced
     178    teams = list(dict.values(gamereport['teams']))
     179    teamSize = 1
     180    for i in range(1, len(dict.keys(gamereport['playerStates']))):
     181      if teams[0] == teams[i] and teams[i] != -1:
     182        teamSize += 1
     183    if teamSize * 2 != len(dict.keys(gamereport['playerStates'])) and len(dict.keys(gamereport['playerStates'])) != 2:
     184      print(teamSize)
     185      print(teams)
     186      print(gamereport)
    173187      return False
     188
    174189    return True
    175190
    176191  def rateGame(self, game):
     192    print("RATING")
    177193    """
    178       Takes a game with 2 players and alters their ratings
     194      Takes a balanced team game and alters their ratings
    179195      based on the result of the game.
    180196      Returns self.
    181197      Side effects:
    182198        Changes the game's players' ratings in the database.
    183199    """
    184     player1 = game.players[0]
    185     player2 = game.players[1]
    186200    # TODO: Support draws. Since it's impossible to draw in the game currently,
    187201    # the database model, and therefore this code, requires a winner.
    188202    # The Elo implementation does not, however.
    189     result = 1 if player1 == game.winner else -1
     203    winners = []
     204    losers = []
     205
     206    # First we set the teams to 1 & 2 if it's a 1 v 1.
     207    if len(game.players) == 2:
     208      game.player_info[0].teams = 1
     209      game.player_info[1].teams = 2
     210
     211    # Find the first winner in the game
     212    for i in range(len(game.players)):
     213      if game.players[i] == game.winner:
     214        winners.append(i)
     215        break
     216
     217    # The first loop finds 1 of the winners in a team game. The second loop
     218    # then find the other winners by looking for the player who is on the
     219    # same team as him. Anyone who is not on his/her team is then a loser
     220    for i in range(0, (len(game.players))):
     221      if i != winners[0]:
     222        if game.player_info[winners[0]].teams == game.player_info[i].teams:
     223          winners.append(i)
     224        else:
     225          losers.append(i)
     226
    190227    # Player's ratings are -1 unless they have played a rated game.
    191     if player1.rating == -1:
    192       player1.rating = leaderboard_default_rating
    193     if player2.rating == -1:
    194       player2.rating = leaderboard_default_rating
     228    for i in range(len(game.players)):
     229      if game.players[i].rating == -1:
     230        game.players[i].rating = leaderboard_default_rating
    195231
    196     rating_adjustment1 = int(get_rating_adjustment(player1.rating, player2.rating,
    197       len(player1.games), len(player2.games), result))
    198     rating_adjustment2 = int(get_rating_adjustment(player2.rating, player1.rating,
    199       len(player2.games), len(player1.games), result * -1))
    200     if result == 1:
    201       resultQualitative = "won"
    202     elif result == 0:
    203       resultQualitative = "drew"
    204     else:
    205       resultQualitative = "lost"
    206     name1 = '@'.join(player1.jid.split('@')[:-1])
    207     name2 = '@'.join(player2.jid.split('@')[:-1])
    208     self.lastRated = "A rated game has ended. %s %s against %s. Rating Adjustment: %s (%s -> %s) and %s (%s -> %s)."%(name1,
    209       resultQualitative, name2, name1, player1.rating, player1.rating + rating_adjustment1,
    210       name2, player2.rating, player2.rating + rating_adjustment2)
    211     player1.rating += rating_adjustment1
    212     player2.rating += rating_adjustment2
    213     if not player1.highest_rating:
    214       player1.highest_rating = -1
    215     if not player2.highest_rating:
    216       player2.highest_rating = -1
    217     if player1.rating > player1.highest_rating:
    218       player1.highest_rating = player1.rating
    219     if player2.rating > player2.highest_rating:
    220       player2.highest_rating = player2.rating
     232    winners_ratings_adjustments = []
     233    losers_ratings_adjustments = []
     234    winners_ratings = []
     235    losers_ratings = []
     236    winners_names = []
     237    losers_names = []
     238
     239    # Assemble an list of the players' previous ratings
     240    for i in range(len(winners)):
     241      winners_ratings.append(game.players[winners[i]].rating)
     242      losers_ratings.append(game.players[losers[i]].rating)
     243
     244    # Calculate ratings
     245    for i in range(len(winners)):
     246      winners_ratings_adjustments.append(int(get_rating_adjustment(winners_ratings[i], winners_ratings,
     247        losers_ratings, len(game.players[winners[i]].games), 1)))
     248      losers_ratings_adjustments.append(int(get_rating_adjustment(losers_ratings[i], losers_ratings,
     249        winners_ratings, len(game.players[losers[i]].games), -1)))
     250      # Get the names of each player
     251      winners_names.append( '@'.join(game.players[winners[i]].jid.split('@')[:-1]))
     252      losers_names.append('@'.join(game.players[losers[i]].jid.split('@')[:-1]))
     253
     254    # Generate the message for the ratings
     255    winnersNameStr = ""
     256    winnersRatingStr = ""
     257    losersNameStr = ""
     258    losersRatingStr = ""
     259    winnersNameStr = ", ".join(winners_names[:-1]) + (" and " if len(winners_names) != 1 else "") + winners_names[-1]
     260    ratingAdjustmentList = list(map(lambda name, rating, adjustment:"%s (%s -> %s)" %(name, rating, rating + adjustment), winners_names, winners_ratings, winners_ratings_adjustments))
     261    winnersRatingStr = ", ".join(ratingAdjustmentList[:-1]) + (" and " if len(ratingAdjustmentList) != 1 else "") + ratingAdjustmentList[-1]
     262    losersNameStr = ", ".join(losers_names[:-1]) + (" and " if len(losers_names) != 1 else "") + losers_names[-1]
     263    ratingAdjustmentList = list(map(lambda name, rating, adjustment:"%s (%s -> %s)" %(name, rating, rating + adjustment), losers_names, losers_ratings, losers_ratings_adjustments))
     264    losersRatingStr = ", ".join(ratingAdjustmentList[:-1]) + (" and " if len(ratingAdjustmentList) != 1 else "") + ratingAdjustmentList[-1]
     265    # Construct message
     266    self.lastRated = "A rated game has ended. " + winnersNameStr + " won against " + losersNameStr + ". Rating Adjustments: " + winnersRatingStr + " won aginst " + losersRatingStr + "."
     267
     268    # Change the ratings in the database
     269    for i in range(len(winners)):
     270      game.players[winners[i]].rating += winners_ratings_adjustments[i]
     271      game.players[losers[i]].rating += losers_ratings_adjustments[i]
    221272    db.commit()
    222273    return self
    223274
     
    317368    self.leaderboard = leaderboard
    318369    self.interimReportTracker = []
    319370    self.interimJIDTracker = []
     371    self.processedGameReport = {}
    320372
    321373  def addReport(self, JID, rawGameReport):
    322374    """
     
    354406        Python data structures leaving JIDs empty.
    355407      Returns a processed gameReport of type dict.
    356408    """
    357     processedGameReport = {}
     409
     410    inProcessGameReport = {}
     411    statToJID = {}
    358412    for key in rawGameReport:
    359413      if rawGameReport[key].find(",") == -1:
    360         processedGameReport[key] = rawGameReport[key]
     414        inProcessGameReport[key] = rawGameReport[key]
    361415      else:
    362416        split = rawGameReport[key].split(",")
    363417        # Remove the false split positive.
     
    364418        split.pop()
    365419        # We just delete gaia for now.
    366420        split.pop(0)
    367         statToJID = {}
    368421        for i, part in enumerate(split):
    369            statToJID[JIDs[i]] = part
    370         processedGameReport[key] = statToJID
    371     return processedGameReport
     422          statToJID[JIDs[i]] = part
     423        inProcessGameReport[key] = statToJID
     424    if self.processedGameReport == {}:
     425      self.processedGameReport = inProcessGameReport
    372426
     427    players = map(lambda jid: db.query(Player).filter_by(jid=jid).first(),
     428                  dict.keys(self.processedGameReport['playerStates']))
     429
     430    for player in players:
     431      if self.processedGameReport['playerStates'][player] == "active" and inProcessGameReport['playerStates'][player] != "active":
     432        for key in dict.keys(self.processedGameReport):
     433          self.processedGameReport[key][player] = inProcessGameReport[key][player]
     434    print(self.processedGameReport)
     435    return self.processedGameReport
     436
    373437  def checkFull(self):
    374438    """
    375439      Searches internal database to check if enough
     
    386450      for JID in self.interimJIDTracker[i]:
    387451        if JID != None:
    388452          numReports += 1
    389       if numReports == numPlayers:
    390         self.leaderboard.addAndRateGame(self.expandReport(self.interimReportTracker[i], self.interimJIDTracker[i]))
    391         del self.interimJIDTracker[i]
    392         del self.interimReportTracker[i]
    393         length -= 1
    394       else:
    395         i += 1
    396         self.leaderboard.lastRated = ""
     453      print(self.interimJIDTracker[i])
     454      print("numReports")
     455      print(numReports)
     456      #if numReports == numPlayers:
     457      self.leaderboard.addAndRateGame(self.expandReport(self.interimReportTracker[i], self.interimJIDTracker[i]))
     458      i += 1
     459      del self.interimJIDTracker[i]
     460      del self.interimReportTracker[i]
     461      length -= 1
     462      #else:
     463       #i += 1
     464       #self.leaderboard.lastRated = ""
     465    self.processedGameReport = {}
    397466
    398467  def getNumPlayers(self, rawGameReport):
    399468    """