Opened 10 years ago
Last modified 6 years ago
#2516 new enhancement
Expand Rating System
Reported by: | Josh | Owned by: | |
---|---|---|---|
Priority: | Nice to Have | Milestone: | Backlog |
Component: | Multiplayer lobby | Keywords: | |
Cc: | Patch: |
Description (last modified by )
Currently only 1 vs. 1 games started through the multiplayer lobby are rated. This should at be expanded to support any grouping where the number of opponents are equal (eg. 2v2v2, 4v4, 1v1v1v1).
It would also be nice if the enable rating checkbox on the gamesetup page enabled/disabled itself based on a game's ratability.
Attachments (2)
Change History (39)
comment:1 by , 10 years ago
Owner: | changed from | to
---|
comment:2 by , 10 years ago
Any player count without fixed teams should also be seen as a 1v1v1v..., as you can keep playing until there's only one winner.
comment:3 by , 10 years ago
I don't think we should rate games with more than two teams; there's too much randomness going on (who attacks who, who is closest to attack, so the team caught in the middle may have an inherent disadvantage) that doesn't really correlate to the skill of the players (which is what the rating should measure).
comment:4 by , 10 years ago
I agree with scythetwirler. Furthermore, teams with more than 2 players often result in the 2 players in the team that are on the edge of the map doing all the work and the player in the middle doing nothing. This is especially noticeable on the oasis maps where the 2nd player on the team is sandwiched between the first and 3rd player on the team and is unable to attack or expand due to being blocked by the oasis at the centre of the map and blocked by the 2 other players on his/her team
comment:5 by , 10 years ago
Keywords: | patch review added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
Summary: | Expand Rating System → [PATCH] Expand Rating System |
comment:6 by , 10 years ago
Component: | Core engine → Multiplayer lobby |
---|
comment:7 by , 10 years ago
I have attached a patch which I have made which should enable 2v2
However, it is untested, so someone will have to test it first.
comment:8 by , 10 years ago
Keywords: | review removed |
---|
A couple comments:
- Most of the function should be rewritten to handle arrays so we can avoid hard-coding so much.
- The code is rather hard to follow for a somewhat simple concept; cleaning up the code would be nice.
ELO.py
- Line 41: The rating inputs should be an array for each team, not inputted individually as separate variables, as it would make scaling for larger games a mess. This would change lines 58 & 59 as well.
XpartaMuPP.py:
- You are missing colons after some of your for/if statements.
- Don't reuse variables and move them to a higher scope if it is less confusing to just make them scoped to the loop itself. (Using i in two loops that aren't nested is fine, but moving i to the scope that encompasses both is not preferable).
- Line 141: "i" should have a more descriptive name when you are using it to count players on a team.
- Line 144: Using for in range() already increments, so the j += 1 is not necessary. This check could also be a lot simpler.
- Line 148: Typo in comment.
- Lines 179 onward: I feel that most of the patch around here can be much simpler.
comment:10 by , 10 years ago
extra: the i++ used on lines 233 239 262 and 266 is also not python and unneccessary for the same reason as j += 1. also line 175 is the syntax for a multiline comment but i can't see the other side of the comment. Also the for loops at the bottom? range(0,1) is just 0 in python so it runs once then stops, so is (2,3). what are you even trying to do with those? i cannot see any valid use for a for loop.
by , 10 years ago
Attachment: | gamereport-guide.txt added |
---|
A brief guide on using the gamereport variable.
comment:11 by , 10 years ago
Keywords: | review added |
---|
comment:12 by , 10 years ago
Remove the "TODO: Team Games." on line 56 of ELO.py. Also, your patch of XpartaMuPP.py seems to be corrupted (see the "this hunk was shorter than expected" warning in the trac viewer). Your ELO.py changes look fine, but scythetwirler or alpha123 would be a better judge. Your changes to check that teams are balanced in XpartaMuPP.py seem to be logically convoluted. Try cleaning it up and avoid checking things more then you need. Fewer ifs would be nice. Sorry I can't be more helpful. You could also condense some of the loops you have at the end of rateGame. For example, concat all the winner names and ratings in one loop, all the loser names and ratings in a second loop, and construct 'message' after both loops.
That said, your patch has come a long way from it's first version. Thank you for putting in the effort and dedication.
comment:13 by , 10 years ago
Keywords: | review removed |
---|
comment:14 by , 10 years ago
Thanks Josh, I will edit it today
I'm not a python dev by the way. Just learning stuff as I go along :D
comment:15 by , 10 years ago
Keywords: | review added |
---|
comment:16 by , 10 years ago
Keywords: | review removed |
---|
Since we are almost certainly never going to find a way to rate uneven team games (such as 2v3s), winner and loser loops can be combined like you did in line 252 of XpartaMuPP.py.
There a couple of spacing issues (line 149, 251 of XpartaMuPP.py).
The range(x) function ranges from 0 to x-1 inclusive. Also, "if i < (len(losers) - 1): " should not be checked each time in that loop and the outer set of parenthesis is extraneous.
players_with_player1 is a rather ugly variable name, perhaps we can change it to something like "team_size"? This variable should be initialized before the loop.
comment:17 by , 10 years ago
Can't 2v3 be like 2 points for the team of two, if they win and, 1 point for each of the team of 3 if they win.
Other solution that could be used. Separate rating. A lot of games do that.
1v1 2v2 3v3 4v4 2v3 1v3 etc...
comment:18 by , 10 years ago
Keywords: | review added |
---|
comment:19 by , 10 years ago
Maybe my earlier comment wasn't clear enough, but I was hoping you could condense this:
# Generate the message for the ratings message = "A rated game has ended. " for i in range(len(winners)): message = message + winners_names[i] if i < (len(winners) - 2): message = message + ", " elif i == (len(winners) - 2): message = message + " and " message = message + "won against " for i in range(len(losers)): message = message + losers_names[i] if i < (len(losers) - 2): message = message + ", " elif i == (len(losers) - 2): message = message + " and " message = message + ". Rating Adjustment: " for i in range(len(winners)): message = message + "%s (%s -> %s)" %(winners_names[i], winners_ratings[i], winners_ratings[i] + winners_ratings_adjustments[i]) if i < (len(winners) - 2): message = message + ", " elif i == (len(winners) - 2): message = message + " and " message = message + "won against " for i in range(len(losers)): message = message + "%s (%s -> %s)" %(losers_names[i], losers_ratings[i], losers_ratings[i] + losers_ratings_adjustments[i]) if i < (len(losers) - 2): message = message + ", " elif i == (len(losers) - 2): message = message + " and " self.lastRated = message
And make it into something more like this:
winnerNameStr = "" winnerRatingStr = "" loserNameStr = "" loserRatingStr = "" # Concat winner data together for message for i in range(len(winners)): # Put an 'and' before the last winner listed. if i == len(winners_names) - 1: # Only put a comma before the 'and' if more than two winners are listed. if len(winners) > 2: winnerNameStr += "," winnerRatingStr += "," winnerNameStr += " and " winnerRatingStr += " and " elif i != 0: winnerNameStr += ", " winnerRatingStr += ", " winnerNameStr += winners_names[i] winnerRatingStr += "%s (%s -> %s)" %(winners_names[i], winners_ratings[i], winners_ratings[i] + winners_ratings_adjustments[i]) # Concat loser data together for message for i in range(len(losers)): # Put an 'and' before the last loser listed. if i == len(losers_names) - 1: # Only put a comma before the 'and' if more than two losers are listed. if len(losers) > 2: loserNameStr += "," loserRatingStr += "," loserNameStr += " and " loserRatingStr += " and " elif i != 0: loserNameStr += ", " loserRatingStr += ", " loserNameStr += losers_names[i] loserRatingStr += "%s (%s -> %s)" %(losers_names[i], losers_ratings[i], losers_ratings[i] + losers_ratings_adjustments[i]) # Construct message self.lastRated = "A rated game has ended. " + winnerNameStr + "won against" + loserNameStr + ". Rating Adjustments: " + winnerRatingStr + "won aginst " + loserRatingStr + "."
(The above is tested and also adds the standard oxford comma along with simplifying the message. Feel free to copy-paste.)
comment:20 by , 10 years ago
Keywords: | review removed |
---|
follow-up: 22 comment:21 by , 10 years ago
Josh: Or just use join and don't care for the and. (Or just join all but the last one and add it that way)
comment:22 by , 10 years ago
Replying to leper:
Josh: Or just use join and don't care for the and. (Or just join all but the last one and add it that way)
Join wouldn't work for the ratings string and the extra logic to handle the 'and' in the names string would balance out all the improvement of using join.
comment:23 by , 10 years ago
It wouldn't. For the rating strings use map first, then join. Should make one of the loops roughly 3 lines, which is still better than even your improved version.
comment:24 by , 10 years ago
Keywords: | review added |
---|
follow-up: 26 comment:25 by , 10 years ago
Keywords: | review removed |
---|
Lines 221-224 can be deleted. [0:something]
is the same as [:something]
. Check if the code still works with 1vs1s, if it doesn't (which looks like it is the case) use an inline if (roughly a ternary operator) to add the " and "
only if it is needed.
Lines 198-218 could be improved with some map calls too.
Lines 183-191 can be shortened with two calls to filter. (Use a local var to find the team of a winner (maybe using next()
(as in next(game.player_info[i].team for i in game.players if i == game.winner)
))
Lines 151-152: fix the indentation, also make that a real comment, not an explanation of what the code already says; The code above that if can probably be improved (shortened/cleaned up) by removing the special case for 1vs1s.
comment:27 by , 10 years ago
Cc: | added |
---|
comment:29 by , 10 years ago
I've debugged it further and it looks like in non 1v1s, pyrogenesis is telling the bot in the gamereport that playerStates are "active" so the lobby bot thinks the game is still in progress. I can't understand why though.
comment:30 by , 10 years ago
Milestone: | Alpha 17 → Alpha 18 |
---|
Based on an IRC discussion with Henry, the new bot is to be taken care of by someone else very soon. However, the bot will not be ready for A17, so I push this back.
If I'm not mistaken, the bot can be updated even if there is no release, as far as code changes are not necessary.
comment:31 by , 9 years ago
Well, I'm back n school now so I don't have much time to work on it so that's why I said that Itms.
But anyway, I already worked out what needs to be done but I don't have enough python skills or the time to code it.
Here's what needs to be done:
Currently, pyrogenesis only submits a game report if someone's playerState that instance of pyrogenesis is not an observer and the game has not ended has changed and the lobby bot only rates a game if all the players have submitted a game report.
This doesn't work for rated team games. I will illustrate this in the scenario below:
So, let's suppose in a 2v2 where players 1&2 are on the same team and players 3&4 are on the same team:
- Player 1 is defeated. This means that 4 game reports are submitted as none of the players are observers at the time.
- Player 2 is defeated. This means that 3 game reports are submitted as may player 1 is an observer or he may have already left the game.
This results in pyrogenesis not rating the game as the number of gamereports submitted does not equal the player number
This all needs to be replaced with new code so that any new gamereports for a game are appended to the old gamereports of that game.
Good luck to anybody who wishes to work on this patch :)
comment:32 by , 9 years ago
Cc: | removed |
---|---|
Milestone: | Alpha 18 → Backlog |
comment:33 by , 9 years ago
Owner: | removed |
---|---|
Status: | assigned → new |
by , 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)
comment:34 by , 9 years ago
Traceback (most recent call last):
File "XpartaMuPP.py", line 753, in iqhandler
self.reportManager.addReport(iqfrom, iqgamereportgame)
File "XpartaMuPP.py", line 401, in addReport
self.checkFull()
File "XpartaMuPP.py", line 458, in checkFull
self.leaderboard.addAndRateGame(self.expandReport(self.interimReportTracker[i], self.interimJIDTracker[i]))
File "XpartaMuPP.py", line 432, in expandReport
if self.processedGameReportplayerStates[player] == "active" and inProcessGameReportplayerStates[player] != "active":
KeyError: <LobbyRanking.Player object at 0x7f5dc56aa4e0>
comment:35 by , 9 years ago
Keywords: | patch removed |
---|---|
Summary: | [PATCH] Expand Rating System → Expand Rating System |
comment:36 by , 7 years ago
Priority: | Must Have → Nice to Have |
---|
Making this abuse-proof is very difficult.
comment:37 by , 6 years ago
Description: | modified (diff) |
---|
I think there is a really need for multiplayer ratings. The singleplayer ratings doesn't say much about your multiplayer abilitys. So here is my "simple" idea. Rating only for games with two teams (independently if 2vs2 or 1vs3 or other constellations):
- add up all ratings of every team
- so you have two ratings, which are also depending on how much member a team have
- take this two ratings and use the same function as in 1vs1
- add this resulting difference to every member of the teams
So not every game could be fair rated, but in the average it should be balanced.
It'd be nice if you spelled the owner as scythetwirler instead of sycthetwirler. :P