Home > Forums
|
Multiplayer Forums
Unanswered Posts | Active Topics
Board index » Games » Featured Games » Age of Conquest (AoC) » Support » AoC API & Code Samples
| Author |
Message |
|
noblemaster
|
Post subject: Rating Calcuation Posted: 12 Aug 2006, 15:38 |
|
| Game Developer |
 |
 |
Joined: 17 Apr 2005, 02:34 Posts: 5166 Location: Honolulu
|
That's for calculating the ranking  . Code: /** * Ranking class. * * @author king (http://www.aevumobscurum.com) * @since February 22, 2006 */ public class Ranking implements Serializable { /** Minimum number of players for ranking. */ public static final int MINIMUM_PLAYERS_FOR_RANKING = 5; /** The rating. */ private int rating = 900; /** The ranking volatility. */ private int volatility = 400; /** The number of games played. */ private int gamesPlayed = 0; /** The various types rating classifications. */ public static enum RatingClassification { /** Level 0. */ LEVEL0("0", new Color(0x00818181), 0, 799), /** Level 1. */ LEVEL1("*", new Color(0x0001C351), 800, 1099), /** Level 2. */ LEVEL2("**", new Color(0x00029AEF), 1100, 1399), /** Level 3. */ LEVEL3("***", new Color(0x00F5E800), 1400, 1799), /** Level 4. */ LEVEL4("****", new Color(0x00F7941D), 1800, 2199), /** Level 5. */ LEVEL5("*****", new Color(0x00E22A24), 2200, Integer.MAX_VALUE); /** The name for the given rating. */ private final String name; /** The color for the given rating. */ private final Color color; /** The minimum number for the rating. */ private final int minRating; /** The maximum number for the rating. */ private final int maxRating; /** * Constructor for rating enum with value. * * @param name The name for the given rating interval. * @param color The color for the given rating. * @param minRating The minimum rating for the given interval. * @param maxRating The maximum rating for the given interval. */ private RatingClassification(String name, Color color, int minRating, int maxRating) { this.name = name; this.color = color; this.minRating = minRating; this.maxRating = maxRating; } /** * Returns the rating classification for the given rating. * * @param rating The rating to find the classification for. * @return The rating classification. */ public static RatingClassification find(int rating) { if ((rating >= LEVEL0.minRating) && (rating <= LEVEL0.maxRating)) { return LEVEL0; } else if ((rating >= LEVEL1.minRating) && (rating <= LEVEL1.maxRating)) { return LEVEL1; } else if ((rating >= LEVEL2.minRating) && (rating <= LEVEL2.maxRating)) { return LEVEL2; } else if ((rating >= LEVEL3.minRating) && (rating <= LEVEL3.maxRating)) { return LEVEL3; } else if ((rating >= LEVEL4.minRating) && (rating <= LEVEL4.maxRating)) { return LEVEL4; } else if ((rating >= LEVEL5.minRating) && (rating <= LEVEL5.maxRating)) { return LEVEL5; } else { // not found, just return null return null; } } /** * To query the name. * * @return The name for the given classification. */ public String getName() { return this.name; }
/** * Ths color for the given classification. * * @return The color for the given classification. */ public Color getColor() { return this.color; } /** * Returns the minimum rating for this rating. * * @return The minimum rating value. */ public int getMinRating() { return this.minRating; } /** * Returns the maximum rating value. * * @return The maximum rating value. */ public int getMaxRating() { return this.maxRating; } };
/** * Returns the number of games played. * * @return The number of games played. */ public int getGamesPlayed() { return gamesPlayed; } /** * Sets the number of games played. * * @param gamesPlayed The number of games played. */ public void setGamesPlayed(int gamesPlayed) { this.gamesPlayed = gamesPlayed; } /** * Returns the rating. * * @return The rating. */ public int getRating() { return rating; } /** * Sets a new rating. * * @param rating The new rating. */ public void setRating(int rating) { this.rating = rating; } /** * Returns the rating volatility. * * @return The rating volatility. */ public int getVolatility() { return volatility; } /** * Sets the rating volatility. * * @param volatility The volatility. */ public void setVolatility(int volatility) { this.volatility = volatility; } /** * Returns the average rating for all the given rankings. * * @param rankings The rankings to calculate the average rating for. * @return The average rating. */ public static double getAverageRating(List<Ranking> rankings) { double averageRating = 0; for (Ranking ranking: rankings) { averageRating += ranking.getRating(); } averageRating /= rankings.size(); return averageRating; } /** * Returns the competition factor for the given rankings. * * @param rankings The rankings to calculate the competition factor for. * @return The competition factor. */ public static double getCompetitionFactor(List<Ranking> rankings) { double volatilitySum2 = 0; for (Ranking ranking: rankings) { volatilitySum2 += ranking.getVolatility() * ranking.getVolatility(); } double averageRating = getAverageRating(rankings); double ratingSum2 = 0; for (Ranking ranking: rankings) { ratingSum2 += (ranking.getRating() - averageRating) * (ranking.getRating() - averageRating); } int size = rankings.size(); return Math.sqrt((volatilitySum2 / size) + (ratingSum2 / (size - 1))); } /** * Returns the win probability of this ranking compared to the inputted ranking. * * @param ranking The other ranking to calculate the win probability for. * @return The win probability for this ranking. */ public double getWinProbability(Ranking ranking) { double a = ranking.getRating() - rating; double b = ranking.getVolatility() * ranking.getVolatility() + volatility * volatility; double erfValue = erf(a / Math.sqrt(2 * b)); return 0.5 * (erfValue + 1.0); } /** * Returns the win probability compared to everybody. * * @param rankings The others to compare this ranking to. * @return The win probability. */ public double getWinProbability(List<Ranking> rankings) { if (rankings.size() > 1) { double probability = 0; for (Ranking ranking: rankings) { if (this != ranking) { probability += ranking.getWinProbability(this); } } return probability / (rankings.size() * (rankings.size() - 1) / ((double)2)); } else { return 1.0; } } /** * Returns this ranking's expected rank compared to other rankings. * * @param rankings The other ranking to compare this ranking to. * @return The expected rank compared to other rankings. */ public double getExpectedRank(List<Ranking> rankings) { double expectedRankSum = 0; for (Ranking ranking: rankings) { expectedRankSum += getWinProbability(ranking); } return expectedRankSum + 0.5; } /** * Returns the expected performance compared to other rankings. * * @param rankings The other rankings to compare this ranking to. * @return The expected performance of this ranking. */ public double getExpectedPerformance(List<Ranking> rankings) { return -gaussianPercentage((getExpectedRank(rankings) - 0.5) / rankings.size()); } /** * Returns the actual performance of this ranking. * * @param actualRank The actual rank. Rank is the actual rank of the ranking in the * competition based on score (1 for first place, NumPlayers forlast). If the * player tied with another player, the rank is the average of the positions * covered by the tied players. * @param numPlayers The number of players. * @return The actual performance of this ranking. */ public double getActualPerformance(double actualRank, int numPlayers) { return -gaussianPercentage((actualRank - 0.5) / numPlayers); } /** * Returns the performed as rating. * * @param actualRank The actual rank. Rank is the actual rank of the ranking in the * competition based on score (1 for first place, NumPlayers forlast). If the * player tied with another player, the rank is the average of the positions * covered by the tied players. * @param rankings The other player's rankings. * @return The performed as rating. */ public double getPerformedAsRating(double actualRank, List<Ranking> rankings) { return rating + getCompetitionFactor(rankings) * (getActualPerformance(actualRank, rankings.size()) - getExpectedPerformance(rankings)); } /** * Returns the weight of a competition for the player. * * @return The weight of the competition for the player. */ public double getWeight() { return (1d / (1d - (0.58 / (gamesPlayed + 1d) + 0.18))) - 1d; } /** * Returns the cap for this player. * * @return The cap for this player. */ public double getCap() { return 180d + (1500d / (1d + gamesPlayed)); } /** * Returns the new ranking for this ranking. * * @param actualRank The actual rank. Rank is the actual rank of the player in the * competition based on score (1 for first place, NumPlayers forlast). If the * player tied with another player, the rank is the average of the positions * covered by the tied players. * @param rankings The other player's rankings. * @return The new ranking */ public Ranking getNewRanking(double actualRank, List<Ranking> rankings) { Ranking newRanking = new Ranking(); // increase games played newRanking.setGamesPlayed(gamesPlayed + 1); // calculate ranking and volatility double weight = getWeight(); double cap = getCap(); double perfAs = getPerformedAsRating(actualRank, rankings); double newRating = (rating + weight * perfAs) / (1 + weight); if ((newRating - rating) > cap) { newRating = rating + cap; } else if ((newRating - rating) < -cap) { newRating = rating - cap; } newRanking.setRating((int)Math.round(newRating)); double a = ((newRating - rating) * (newRating - rating)) / weight; double b = volatility * volatility / (weight + 1); double newVolatility = Math.sqrt(a + b); newRanking.setVolatility((int)Math.round(newVolatility)); return newRanking; } /** * Returns the new rankings for the inputted data. * * @param actualRanks The actual ranks. Rank is the actual rank of the player in the * competition based on score (1 for first place, NumPlayers forlast). If the * player tied with another player, the rank is the average of the positions * covered by the tied players. * @param rankings The actual rankings. * @return The new rankings in the same order as the inputted rankings. */ public static List<Ranking> getNewRankings(List<Double> actualRanks, List<Ranking> rankings) { List<Ranking> newRankings = new ArrayList<Ranking>(); for (int i = 0; i < actualRanks.size(); i++) { double actualRank = actualRanks.get(i); Ranking ranking = rankings.get(i); Ranking newRanking = ranking.getNewRanking(actualRank, rankings); newRankings.add(newRanking); } return newRankings; } /** * Error function. * * @param x Input value. * @return Error funtion output */ private double erf(double x) { return 2.0 * pn(x * Math.sqrt(2)) - 1; } /** * Percentage point of the standard normal distribution. Inverse of the distribution * function. * * @param p The input value. * @return Inverse of the normal distribution. */ private double gaussianPercentage(double p) { return pninv(p); }
/** * Inverse Standard normal distribution. * Approximate using secant method. * * @param x The input value. * @return The output value. */ private double pninv(double x) { if (x==0.5) { return 0; } if (x<=0) { return Double.NEGATIVE_INFINITY; } if (x>=1) { return Double.POSITIVE_INFINITY; } if (x<0.5) { return -pninv(1 - x); } return secant(x, 1, 1.1); }
/** * Secant method. * * @param a Parameter a. * @param x0 Parameter x0. * @param x1 Parameter x1. * @return The result. */ private double secant(double a, double x0, double x1) { double xi = x0, xii = x1, x; double yi = pn(x0)-a, yii = pn(x1)-a, y;
do { x = xii - yii * (xii - xi) / (yii - yi); y = pn(x)-a;
xi = xii; xii = x; yi = yii; yii = y; } while (Math.abs(y) > 1e-14);
return x; } /** * Compute Standard Normal Distribution. * Source: Abramovitz & Stegun, 26.2.11, pg. 932 * * @param x The value to calculate normal distribution for. * @return The normal distribution. */ private double pn(double x) { final double epsilon = 1e-30; if (x == 0) { return 0.5; } if (x < 0) { return 1 - pn(-x); } if (x > 12) { return 1; }
double fac = x; double tot = fac; int n = 1;
while (Math.abs(fac) > epsilon) { fac = fac * x * x / (2.0 * n + 1); tot += fac; n = n+1; } return 0.5 + zn(x) * tot; }
/** * Compute density of standard normal distribution. * * @param x The value to calculate the density for. * @return The density. */ private double zn(double x) { final double sqrt2pi = Math.sqrt(2*Math.PI); return 1.0 / (sqrt2pi * Math.exp(x * x / 2)); } }
_________________
|
|
| Top |
|
 |
|
Stig
|
Post subject: Posted: 13 Aug 2006, 00:14 |
|
| Knight |
 |
 |
Joined: 14 Jun 2006, 23:37 Posts: 2315 Location: Mostlikely at the bar
|
Yeah I get it not 
|
|
| Top |
|
 |
|
noblemaster
|
Post subject: Posted: 13 Aug 2006, 00:16 |
|
| Game Developer |
 |
 |
Joined: 17 Apr 2005, 02:34 Posts: 5166 Location: Honolulu
|
yeah!!! first post in the geek section *stig gets "geek" award 2006 - thanks for posting*
_________________
|
|
| Top |
|
 |
|
Stig
|
Post subject: Posted: 13 Aug 2006, 00:18 |
|
| Knight |
 |
 |
Joined: 14 Jun 2006, 23:37 Posts: 2315 Location: Mostlikely at the bar
|
Aschi wrote: *stig gets "geek" award 2006 - thanks for posting* first time a geek award goes to someone who doesn't even know how to put his computer back together after cleaning, HURRAY
|
|
| Top |
|
 |
|
Biohazard
|
Post subject: Posted: 14 Aug 2006, 03:45 |
|
| Moderator |
 |
 |
Joined: 28 May 2006, 02:55 Posts: 3068 Location: Wigan, UK
|
|
| Top |
|
 |
|
Stig
|
Post subject: Posted: 14 Aug 2006, 05:19 |
|
| Knight |
 |
 |
Joined: 14 Jun 2006, 23:37 Posts: 2315 Location: Mostlikely at the bar
|
|
dusty m8, so I took the panels of and the dust out, but when I rebuild it again I put on the panels the wrong way
|
|
| Top |
|
 |
|
Biohazard
|
Post subject: Posted: 14 Aug 2006, 12:27 |
|
| Moderator |
 |
 |
Joined: 28 May 2006, 02:55 Posts: 3068 Location: Wigan, UK
|
|
| Top |
|
 |
|
Biohazard
|
Post subject: Posted: 18 Aug 2006, 00:35 |
|
| Moderator |
 |
 |
Joined: 28 May 2006, 02:55 Posts: 3068 Location: Wigan, UK
|
|
| Top |
|
 |
|
noblemaster
|
Post subject: Posted: 18 Aug 2006, 01:04 |
|
| Game Developer |
 |
 |
Joined: 17 Apr 2005, 02:34 Posts: 5166 Location: Honolulu
|
|
2200+
The ratings will go OVER 2200 ...
All the ratings together will form a sort of bell curve with some players over 2200. 2300, 2400 is definitly in the reach!
_________________
|
|
| Top |
|
 |
|
Stig
|
Post subject: Posted: 18 Aug 2006, 01:53 |
|
| Knight |
 |
 |
Joined: 14 Jun 2006, 23:37 Posts: 2315 Location: Mostlikely at the bar
|
|
I think there will be some limit, you simply can't go over 2200 I think. UNLESS, you get back up by loads of players. Say Bio and I help Mab to win every game, but no-one will do that
|
|
| Top |
|
 |
|
Biohazard
|
Post subject: Posted: 18 Aug 2006, 02:18 |
|
| Moderator |
 |
 |
Joined: 28 May 2006, 02:55 Posts: 3068 Location: Wigan, UK
|
|
| Top |
|
 |
|
alopezme
|
Post subject: Posted: 18 Aug 2006, 07:53 |
|
| Merchant |
 |
 |
Joined: 15 Aug 2006, 10:17 Posts: 421 Location: Spain
|
|
Yeah, you seems to be very skilled at Java! I like Java. Now I am learning JSP.
|
|
| Top |
|
 |
|
noblemaster
|
Post subject: Posted: 18 Aug 2006, 10:02 |
|
| Game Developer |
 |
 |
Joined: 17 Apr 2005, 02:34 Posts: 5166 Location: Honolulu
|
|
It definitly will go over 2200. In maybe couple of years, some players might even reach 2800 ...
However, the higher your score, the more time it takes to get it!
_________________
|
|
| Top |
|
 |
|
henriqb
|
Post subject: Posted: 18 Aug 2006, 10:17 |
|
| Mercenary |
 |
 |
Joined: 02 Jul 2006, 11:45 Posts: 565 Location: Brasil
|
|
you can just create new colors and rew ranks
|
|
| Top |
|
 |
|
noblemaster
|
Post subject: Posted: 19 Oct 2006, 12:59 |
|
| Game Developer |
 |
 |
Joined: 17 Apr 2005, 02:34 Posts: 5166 Location: Honolulu
|
|
Wow, this thread has been read about 500 times!
_________________
|
|
| Top |
|
 |
Who is online |
Users browsing this forum: No registered users and 1 guest |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum
|

 |