Add user rating using Glicko rating system (#1498)

This commit is contained in:
Quercitron 2016-05-17 17:22:14 +03:00
parent 11158d5fa4
commit 972d59aa37
10 changed files with 701 additions and 9 deletions

View file

@ -497,7 +497,9 @@ public abstract class MatchImpl implements Match {
.setGameType(this.getOptions().getGameType())
.setDeckType(this.getOptions().getDeckType())
.setGames(this.getNumGames())
.setDraws(this.getDraws());
.setDraws(this.getDraws())
.setMatchOptions(this.getOptions().toProto())
.setEndTimeMs((this.getEndTime() != null ? this.getEndTime() : new Date()).getTime());
for (MatchPlayer matchPlayer : this.getPlayers()) {
MatchQuitStatus status = !matchPlayer.hasQuit() ? MatchQuitStatus.NO_MATCH_QUIT :
matchPlayer.getPlayer().hasTimerTimeout() ? MatchQuitStatus.TIMER_TIMEOUT :
@ -505,6 +507,7 @@ public abstract class MatchImpl implements Match {
MatchQuitStatus.QUIT;
builder.addPlayersBuilder()
.setName(matchPlayer.getName())
.setHuman(matchPlayer.getPlayer().isHuman())
.setQuit(status)
.setWins(matchPlayer.getWins());
}

View file

@ -35,6 +35,7 @@ import mage.constants.MatchTimeLimit;
import mage.constants.MultiplayerAttackOption;
import mage.constants.RangeOfInfluence;
import mage.constants.SkillLevel;
import mage.game.result.ResultProtos;
/**
*
@ -55,6 +56,7 @@ public class MatchOptions implements Serializable {
protected SkillLevel skillLevel;
protected boolean rollbackTurnsAllowed;
protected int quitRatio;
protected boolean rated;
/**
* Time each player has during the game to play using his\her priority.
@ -177,4 +179,36 @@ public class MatchOptions implements Serializable {
public void setQuitRatio(int quitRatio) {
this.quitRatio = quitRatio;
}
public boolean isRated() {
return rated;
}
public void setRated(boolean rated) {
this.rated = rated;
}
public ResultProtos.MatchOptionsProto toProto() {
ResultProtos.MatchOptionsProto.Builder builder = ResultProtos.MatchOptionsProto.newBuilder()
.setName(this.getName())
.setLimited(this.isLimited())
.setRated(this.isRated())
.setWinsNeeded(this.getWinsNeeded());
ResultProtos.SkillLevel skillLevel = ResultProtos.SkillLevel.BEGINNER;
switch (this.getSkillLevel()) {
case BEGINNER:
skillLevel = ResultProtos.SkillLevel.BEGINNER;
break;
case CASUAL:
skillLevel = ResultProtos.SkillLevel.CASUAL;
break;
case SERIOUS:
skillLevel = ResultProtos.SkillLevel.SERIOUS;
break;
}
builder.setSkillLevel(skillLevel);
return builder.build();
}
}

View file

@ -584,7 +584,9 @@ public abstract class TournamentImpl implements Tournament {
.setGames(match.getNumGames())
.setDraws(match.getDraws())
.addPlayers(matchToProto(match, pair.getPlayer1()))
.addPlayers(matchToProto(match, pair.getPlayer2()));
.addPlayers(matchToProto(match, pair.getPlayer2()))
.setMatchOptions(match.getOptions().toProto())
.setEndTimeMs((match.getEndTime() != null ? match.getEndTime() : new Date()).getTime());
}
}
for (TournamentPlayer tp : round.getPlayerByes()) {
@ -602,6 +604,7 @@ public abstract class TournamentImpl implements Tournament {
MatchQuitStatus.QUIT;
return MatchPlayerProto.newBuilder()
.setName(player.getPlayer().getName())
.setHuman(player.getPlayer().isHuman())
.setWins(matchPlayer.getWins())
.setQuit(quit)
.build();

View file

@ -29,6 +29,10 @@ public class UserData implements Serializable {
protected String tourneyHistory;
protected int tourneyQuitRatio;
private int generalRating;
private int constructedRating;
private int limitedRating;
public UserData(UserGroup userGroup, int avatarId, boolean showAbilityPickerForced,
boolean allowRequestShowHandCards, boolean confirmEmptyManaPool, UserSkipPrioritySteps userSkipPrioritySteps,
String flagName, boolean askMoveToGraveOrder, boolean manaPoolAutomatic, boolean manaPoolAutomaticRestricted,
@ -68,6 +72,7 @@ public class UserData implements Serializable {
this.passPriorityActivation = userData.passPriorityActivation;
this.autoOrderTrigger = userData.autoOrderTrigger;
this.useFirstManaAbility = userData.useFirstManaAbility;
// todo: why we don't copy user stats here?
}
public static UserData getDefaultUserDataView() {
@ -225,8 +230,31 @@ public class UserData implements Serializable {
return tourneyQuitRatio;
}
public int getGeneralRating() {
return generalRating;
}
public void setGeneralRating(int generalRating) {
this.generalRating = generalRating;
}
public int getConstructedRating() {
return constructedRating;
}
public void setConstructedRating(int constructedRating) {
this.constructedRating = constructedRating;
}
public int getLimitedRating() {
return limitedRating;
}
public void setLimitedRating(int limitedRating) {
this.limitedRating = limitedRating;
}
public static String getDefaultFlagName() {
return "world.png";
}
}

View file

@ -20,6 +20,22 @@ message MatchProto {
optional int32 games = 4;
optional int32 draws = 5;
repeated MatchPlayerProto players = 6;
optional MatchOptionsProto match_options = 7;
optional int64 end_time_ms = 8;
}
message MatchOptionsProto {
optional string name = 1;
optional bool limited = 2;
optional bool rated = 3;
optional SkillLevel skill_level = 4;
optional int32 wins_needed = 5;
}
enum SkillLevel {
BEGINNER = 0;
CASUAL = 1;
SERIOUS = 2;
}
message MatchPlayerProto {
@ -27,6 +43,7 @@ message MatchPlayerProto {
optional int32 wins = 2;
optional MatchQuitStatus quit = 3;
optional bool bye = 4;
optional bool human = 5;
}
enum MatchQuitStatus {
@ -74,4 +91,14 @@ message UserStatsProto {
optional int32 matches_idle_timeout = 7;
optional int32 matches_timer_timeout = 8;
optional int32 matches_quit = 9;
optional GlickoRatingProto general_glicko_rating = 10;
optional GlickoRatingProto constructed_glicko_rating = 11;
optional GlickoRatingProto limited_glicko_rating = 12;
}
message GlickoRatingProto {
required double rating = 1;
required double rating_deviation = 2;
optional int64 last_game_time_ms = 3;
}